1. ๋ฌธ์ ์ค๋ช
rsa ์ํธ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐํ์ผ๋ก ์์ฑ๋ ๊ฐ์ ๋ณตํธํํ๋ฉด ๋๋ ๋ฌธ์ ๊ฐ๋ค.
(RSA ์ ์ ๋ฆฌ๋ ๋ธ๋ก๊ทธ: https://gngsn.tistory.com/96)
2. ๋ฌธ์ ๋ถ์
import os
from Crypto.Util.number import getPrime
from Crypto.Util.number import isPrime
from Crypto.Util.number import bytes_to_long
<์์ ์์ฑ ํจ์: generate_primes()>
def generate_primes():
while True:
#512 bits ์์ p ๊ทธ๋ฆฌ๊ณ p๋ฅผ ๊ธฐ๋ฐ์ผ๋ก q,r,s ์์ฑ
p = getPrime(512),
q = (2*p) + 1
r = (2*q) + 1
s = (2*r) + 1
#q, r, s๊ฐ ๋ชจ๋ ์์์ด๋ฉด while ๋ฌดํ๋ฃจํ ์ข
๋ฃ
if isPrime(q) and isPrime(r) and isPrime(s):
break
#p,q,r,s ๊ฐ ๋ฐํ
return (p, q, r, s)
getPrime() ํจ์๋ ์์๋ฅผ ๊ตฌํ๋ ํจ์์ด๊ณ , isPrime() ํจ์๋ ์์์ธ์ง ํ๋ณํ๋ ํจ์์ด๋ค.
์์ธ์๋ถํด ๋ฌธ์ ๊ฐ ์ด๋ ต๋ค๋ ์ฌ์ค์ ๊ธฐ๋ฐํ RSA ์ํธํ ์๊ณ ๋ฆฌ์ฆ์, ํค๋ฅผ ์์๋ด๊ธฐ ์ด๋ ต๊ฒ ํ๊ธฐ ์ํด ํฐ ์์๊ฐ ํ์ํ๋ค. ์ด ํจ์๋ฅผ ํตํด ํฐ ์์ ์์๋ฅผ ์ป์ ์ ์๋ค.
ํ์ฌ 512 bits์ ์์๋ฅผ ๋ง๋ค๊ณ ์๋๋ฐ, ์ด ๋ถ๋ถ์์ ํด๋น rsa ์ํธํ ์๊ณ ๋ฆฌ์ฆ์ด ๊นจ์ง ์ ์๋ ๊ฒ์ ์ ์ ์๋ค. ํ์ฌ ์ปดํจํ ํ์๋ก 1024 bits ์ดํ์ ์์๋ ์์ธก์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
<๋ฉ์ธ ํจ์>
def main() -> int:
#gernerate_primes() ํจ์๋ฅผ ํธ์ถํด p,q,r,s๋ฅผ ์์ฑ
#p,q,r,s๋ฅผ ์ด์ฉํด ๊ฐ์ธํค์ ์ผ๋ถ์ธ N์ ์์ฑ
(p, q, r, s) = generate_primes()
N = p * q * r * s
e = 0x10001
with open("flag.txt", "r") as flag_file:
#read()๋ฅผ ํตํด ํ์ผ์ ๋ด์ฉ์ ์ฝ์ด์ค๊ณ , strip()์ ์ฌ์ฉํด ์์ชฝ ๋ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ๋ค
flag = flag_file.read().strip()
#pow() ์ ๊ณฑ๊ทผ ํจ์๋ฅผ ์ฌ์ฉํด ์ํธ๋ฌธ CT๋ฅผ ๊ณ์ฐํ๋ค.
CT = pow(bytes_to_long(flag.encode()), e, N)
print(f"{N = }")
print(f"{CT = }")
e-> 16์ง์: 0x10001, 10์ง์: 65537, 8์ง์: 20001, 2์ง์: 10000000000000001
3. ๋ฌธ์ ํ์ด
<์๋ 1>
output.txt ํ์ผ์ N๊ฐ๊ณผ CT(์ํธ๋ฌธ)๊ฐ์ด ์ฃผ์ด์ ธ์๋ค.
N = 489654925303072532553659432557377999607856370197579144782976005904927235244321459117898721690940319487769632950077647476152880207627385231603017537961906244964117707813500615680799967895028255666319186794462243666159201392490299439947399915406223652423977002396844720487588735149486903743362109592536081726574342051928022071576485169655694281378301551060632699138055044915993078059902577590451519251321215765308977494770310317350866241246677761542212605478044672014913289740381478940929584556588858045439572693806615268502627912952686133840081188641597461343817750411035667135310831687533531094008308185320371643348451
CT = 58535947031303233853656030097871859886777764034955095086618901763996192727846608049414977429851683454541344096765319691912454768331685486037922533236779909508856486986528041125267338846421238077083738092020495236946742989769815669001100361743526446503248639704900983287986142636083524250650662602975802778548032518674346903013262799229594298599457623347987250272218522320743415393958131916181915804368140008312975210397791293701839101635851486434802271100141743496402698229558250485987421664294229816166263965806962242894230766553316312608696594536239328785792283453559549564751529321240567418095487324718881437825650
1. ์ถฉ๋ถํ ํฐ ์์ p์ q ์ค์
ํ์ฌ p์ q๋ ์์ง ๋ชปํ๋ค.
2. N ๊ตฌํ๊ธฐ
ํ์ฌ N์ ๊ฐ์ด ์ฃผ์ด์ ธ์๊ณ , p๊ฐ 512bits์ด๊ธฐ ๋๋ฌธ์ p๋ฅผ ๊ตฌํ ์ ์๋ค.
from sympy import isprime
def factorize_n(n):
# 512๋นํธ ์์์ ๋ฒ์ ๊ณ์ฐ
min_p = 2**511
max_p = 2**512 - 1
# 512๋นํธ ๋ฒ์ ๋ด์์ ์์ `p` ์ฐพ๊ธฐ
for p in range(min_p, max_p + 1):
if n % p == 0: # `p`๊ฐ `N`์ ์ธ์๋ผ๋ฉด
q = n // p # `q` ๊ณ์ฐ
if isprime(q): # `q`๊ฐ ์์์ธ์ง ํ์ธ
return p, q
return None, None # ์คํจ ์ ๋ฐํ
# ์ฃผ์ด์ง `N` ๊ฐ
N = 489654925303072532553659432557377999607856370197579144782976005904927235244321459117898721690940319487769632950077647476152880207627385231603017537961906244964117707813500615680799967895028255666319186794462243666159201392490299439947399915406223652423977002396844720487588735149486903743362109592536081726574342051928022071576485169655694281378301551060632699138055044915993078059902577590451519251321215765308977494770310317350866241246677761542212605478044672014913289740381478940929584556588858045439572693806615268502627912952686133840081188641597461343817750411035667135310831687533531094008308185320371643348451
# ์์ธ์๋ถํด ์คํ
p, q = factorize_n(N)
if p and q:
print(f"p = {p}")
print(f"q = {q}")
else:
print("์์ธ์๋ถํด ์คํจ")
-> ํ์ด์ฌ ์ฝ๋๋ฅผ ์์ฑํด p๊ฐ์ ๊ตฌํ๋ ค ํ๋๋ฐ, N๊ฐ์ด ๋๋ฌด ์ปค์ ์๊ฐ ์ด์์ผ๋ก ์๊ฐ์ด ๋๋ฌด ์ค๋๊ฑธ๋ฆฐ๋ค...3์๊ฐ ์ด์ ์ฝ๋๋ฅผ ๋๋ ธ์ง๋ง ๊ฐ์ด ๋์ค์ง ์์ ๋ค๋ฅธ ์ฝ๋๋ฅผ ์ฐพ์๋ณด๊ธฐ๋ก ํ๋ค.
<์๋ 2-write up ์ฐธ๊ณ >
(์ฐธ๊ณ ํ ๋ผ์ดํธ์ : https://johan6337.github.io/posts/write-up-glacierctf-2024/)
N์ ๊ฐ์ด ์ฃผ์ด์ก์ผ๋, p๋ฅผ ์์ ์๋ ์ํฉ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ง ์ํธ๋ฌธ์ ๋ณตํธํํ๋ฉด flag๊ฐ ๋์ฌ๊ฒ์ด๋ค.์ฐธ๊ณ ํ ๋ผ์ดํธ์ ์์๋ sage๋ฅผ ์ฌ์ฉํด ๋ฌธ์ ๋ฅผ ํ์ดํ๋๋ฐ, ๋๋ ๋ค๋ฅธ ํ์ด์ฌ ๋ชจ๋๋ก sage๋ฅผ ๋์ฒดํด์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ค.
SageMath
SageMath ๋๋ Sage๋ ์ปดํจํฐ์ฉ ์ํ ์ํํธ์จ์ด ์ค ํ๋์ด๋ค. ๋ค์ํ ๊ธฐ๋ฅ์ด ๊ตฌํ๋์ด ์๊ณ , Python ์์์ ๋์ํ๋๋ก ๊ตฌํ๋ ์ํํธ์จ์ด์ด๋ฉฐ ์์ฒด์ ์ธ ๋ฌธ๋ฒ์ด Python๊ณผ ์ ์ฌํ์ฌ ์ฝ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
from sympy import symbols, Eq, solve
from Crypto.Util.number import inverse, long_to_bytes
N = 489654925303072532553659432557377999607856370197579144782976005904927235244321459117898721690940319487769632950077647476152880207627385231603017537961906244964117707813500615680799967895028255666319186794462243666159201392490299439947399915406223652423977002396844720487588735149486903743362109592536081726574342051928022071576485169655694281378301551060632699138055044915993078059902577590451519251321215765308977494770310317350866241246677761542212605478044672014913289740381478940929584556588858045439572693806615268502627912952686133840081188641597461343817750411035667135310831687533531094008308185320371643348451
CT = 58535947031303233853656030097871859886777764034955095086618901763996192727846608049414977429851683454541344096765319691912454768331685486037922533236779909508856486986528041125267338846421238077083738092020495236946742989769815669001100361743526446503248639704900983287986142636083524250650662602975802778548032518674346903013262799229594298599457623347987250272218522320743415393958131916181915804368140008312975210397791293701839101635851486434802271100141743496402698229558250485987421664294229816166263965806962242894230766553316312608696594536239328785792283453559549564751529321240567418095487324718881437825650
# ๋ณ์ ์ ์. sympy ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ฌ์ฉ๋๋ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ์ x๋ฅผ ์ ์ํ๋ค.
x = symbols('x')
# ๋คํญ์ ์ ์. f๊ฐ 0์ด ๋๋ ๊ฐ์ ์ฐพ๋๊ฒ์ด ๋ชฉํ์ด๋ค. ์ฆ x(=p)๋ฅผ ์ฐพ๋ ๋ถ๋ถ์ด๋ค.
f = x * (2 * x + 1) * (2 * (2 * x + 1) + 1) * (2 * (2 * (2 * x + 1) + 1) + 1) - N
# ๊ทผ ๊ตฌํ๊ธฐ
roots = solve(Eq(f, 0), x) #Eq(f,0)=f๊ฐ 0์ธ ๊ฒฝ์ฐ. ์ฆ f๊ฐ 0์ด ๋๋ x๋ฅผ ์ฐพ๋๋ค.
p = int(roots[0]) #์ ์๋ก ํ๋ณํ
phi = (p - 1) * 2 * p * 2 * (2 * p + 1) * 2 * (2 * (2 * p + 1) + 1)
# ๊ณต๊ฐํค & ๋น๋ฐํค ๊ณ์ฐ
e = 0x10001 #๋ฌธ์ ์์ ์ฃผ์ด์ง
d = inverse(e, phi) #e์ phi๊ฐ์ ๊ฐ์ง๊ณ ๋น๋ฐํค๋ฅผ ๊ณ์ฐํ๋ค.
# ๋ณตํธํ
PT = pow(CT, d, N)
print(long_to_bytes(int(PT)))
gctf{54dly_50ph13_63rm41n_pr1m35_wh3r3_n07_u53d_53curly}
'๐ฆ Private > CTF Wriet-Up' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Fuzzybytes[Web] (0) | 2024.12.01 |
---|---|
Welcom-Pawn [misc] (1) | 2024.11.29 |