๋ ๋ํ ยท AI ์๋ํ ยท ์์คํ
์์ง๋์ด๋ง
์ง์ ๋ง๋ค๊ณ , ์คํํ๊ณ , ๊ธฐ๋กํ๋ค
ยฉ 2026 ZINO LAB
[๐ฅ ๋ธ๋ก ์ฆ 3] ์ธ ๋๋จธ์ง๋ฅผ ํฉ์ณ flag๋ฅผ ๋์ด๋ฆฌ๋ค โ DreamHack chinese what? ํ์ด โ ZINO
2026-07-13 ยท 1๋ถ ์ฝ๊ธฐ ยท
flag๋ฅผ ์ ์๋ก ๋ณธ ๋ค ์ธ ๊ฐ์ 420๋นํธ ์์๋ก ๋๋ ๋๋จธ์ง๋ง ๊ณต๊ฐ๋ crypto ๋ฌธ์ . ๋๋จธ์ง ํ๋๋ก๋ flag๊ฐ ์์๋ณด๋ค ์ปค์ ๋ณต์๋์ง ์์ง๋ง, ์๋ก์์ธ ์ธ ์์์ ๊ณฑ์ด flag๋ณด๋ค ํฌ๋ฏ๋ก ์ค๊ตญ์ธ์ ๋๋จธ์ง ์ ๋ฆฌ(CRT)๋ก ์ธ ํฉ๋์์ ํฉ์น๋ฉด flag๊ฐ ์ ์ผํ๊ฒ ๊ฒฐ์ ๋๋ค. CRT๋ก ์ ์๋ฅผ ๋ณต์ํด ๋ฐ์ดํธ๋ก ๋๋๋ ธ๋ค.
๋ฌธ์ : DreamHack โ chinese what?
๋ถ๋ฅ : Crypto
๋์ด๋ : ๐ฅ ๋ธ๋ก ์ฆ 3
FLAG : DH{Th3_Ch1n35e_r3m4iNd3r_tHe0r3m_w4s_qu1T3_345y_r1ght??_:)}
๋ฌธ์ ์ค๋ช
์ด ์ ๋ต์ ๋๋๊ณ ์๋ ค์ค๋ค.
CRT๋ rsa์ ๋ง์ด ์์ฉ๋๋ ์ ๋ฆฌ์
๋๋ค. ๊ฐ๋จํ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๋ฉฐ CRT๋ ๋ฌด์์ธ์ง ์์๋ณด์ธ์.
์ด๋ฆ chinese what? , ์ค๋ช
CRT โ ์ค๊ตญ์ธ์ ๋๋จธ์ง ์ ๋ฆฌ(Chinese Remainder Theorem)๋ฅผ ์ฐ๋ ์
๋ฌธ ๋ฌธ์ ๋ค. flag๋ฅผ ์ ์๋ก ๋ฐ๊พผ ๋ค ์ธ ์์๋ก ๋๋ ๋๋จธ์ง๋ง ๊ณต๊ฐ๋๋๋ฐ, ๊ทธ ๋๋จธ์ง๋ค์ CRT๋ก ํฉ์น๋ฉด ์๋ flag๊ฐ ๊ทธ๋๋ก ๋์จ๋ค.
chinese what? โ ์ธ ๋๋จธ์ง๋ฅผ CRT๋ก ํฉ์ณ flag ๋ณต์
๋ฌธ์ ๊ฐ์
ํญ๋ชฉ ๋ด์ฉ ๋ฌธ์ ๋ช
chinese what? ๋์ด๋ ๐ฅ ๋ธ๋ก ์ฆ 3 ๋ถ๋ฅ Crypto (์ ์๋ก ) ์ ๊ณต ํ์ผ prob.py , output.txt ๋ชฉํ ์ธ ๋๋จธ์ง์์ flag ์ ์ ๋ณต์ ํต์ฌ ๊ธฐ๋ฒ ์ค๊ตญ์ธ์ ๋๋จธ์ง ์ ๋ฆฌ(CRT)
์ํธ๋ ๊ฒ๋ ์๋ค. flag๋ฅผ ์ธ ์กฐ๊ฐ์ "๋๋จธ์ง"๋ก๋ง ํ๋ ธ์ ๋ฟ์ด๊ณ , ๊ทธ ์กฐ๊ฐ์ ๋ค์ ๋ง์ถ๋ ์ ๋ฆฌ๋ฅผ ์๋ฉด ๋์ด๋ค.
๋ฐฐ๊ฒฝ โ ์ค๊ตญ์ธ์ ๋๋จธ์ง ์ ๋ฆฌ(CRT)
CRT๋ "์๋ก์์ธ ์ฌ๋ฌ ์๋ก ๋๋ ๋๋จธ์ง๋ฅผ ์๋ฉด, ์๋ ์๋ฅผ ๊ทธ ์๋ค์ ๊ณฑ ๋ฒ์ ์์์ ์ ์ผํ๊ฒ ์์๋ผ ์ ์๋ค"๋ ์ ๋ฆฌ๋ค. ๊ณ ๋ ์ค๊ตญ์ "๋ฌผ๊ฑด์ 3๊ฐ์ฉ ์ธ๋ฉด 2๊ฐ ๋จ๊ณ , 5๊ฐ์ฉ ์ธ๋ฉด 3๊ฐ ๋จ๊ณ , 7๊ฐ์ฉ ์ธ๋ฉด 2๊ฐ ๋จ๋๋ค. ๋ฌผ๊ฑด์ ๋ช ๊ฐ์ธ๊ฐ?"๋ผ๋ ๋ฌธ์ ์์ ์ด๋ฆ์ด ์๋ค.
x โก 2 (mod 3) , , โ (mod 105)
์ด ๊ธ์ด ๋์์ด ๋๋์?
๐ฅ ํต์ฌ ๐ก ์ธ์ฌ์ดํธ ๐ ์ข์์ ๐คฏ ์ถฉ๊ฒฉ โก ๋น ๋ฆ
x โก 3 (mod 5)
x โก 2 (mod 7)
x = 23
3, 5, 7 ์ ์๋ก์์ด๊ณ ๊ทธ ๊ณฑ์ 105 ๋ค. 0 โค x < 105 ๋ฒ์์์ ๋ต์ 23 ํ๋๋ฟ์ด๋ค.์์์ผ๋ก๋, ๋ชจ๋๋ฌ๋ค์ ๊ณฑ์ N = p1ยทp2ยทp3 , ๊ฐ Ni = N / pi ๋ผ ํ ๋
x = ฮฃ ( ci ยท Ni ยท (Niโปยน mod pi) ) (mod N) ๋ก ๊ณ์ฐํ๋ค. Ni ๋ pi ๋ฅผ ์ ์ธํ ๋๋จธ์ง ์์๋ค์ ๊ณฑ์ด๋ผ pj (jโ i)๋ก๋ ๋๋์ด๋จ์ด์ง๊ณ , pi ์ ๋ํด์๋ง ์ญ์์ ๊ณฑํด ๋ฑ ๊ทธ ์๋ฆฌ์์๋ง 1 ์ด ๋๊ฒ ๋ง์ถ๋ค. ๊ทธ๋์ ๊ฐ ํญ์ด ์๋ก ๊ฐ์ญ ์์ด ์๊ธฐ ๋๋จธ์ง ์กฐ๊ฑด๋ง ๋ง์กฑ์ํจ๋ค.
ํต์ฌ ์กฐ๊ฑด์ "์๋ ์๊ฐ N ๋ณด๋ค ์์์ผ ํ๋ค"๋ ๊ฒ ์ด๋ค. CRT๊ฐ ์ฃผ๋ ๋ต์ mod N ๊ฐ์ด๋ผ, ์๋ ์๊ฐ N ์ด์์ด๋ฉด ์๋ ค ๋๊ฐ ์ ๋ณด๋ฅผ ๋์ด๋ฆด ์ ์๋ค. ์ด ๋ฌธ์ ๋ ๊ทธ ์กฐ๊ฑด์ด ์ฑ๋ฆฝํ๋๋ก ์์๋ฅผ ๋๋ํ ์ก์๋ค.
๐ฌ ์ ์ฐฐ โ flag๋ฅผ ๋๋จธ์ง๋ก๋ง ํ๋ ธ๋ค prob.py ๋ฅผ ๋ณด๋ฉด ๊ตฌ์กฐ๊ฐ ํ๋์ ๋ค์ด์จ๋ค.
from Crypto.Util.number import bytes_to_long, getPrime
flag = bytes_to_long ( b 'DH{???...???}' ) # flag ๋ฅผ ํฐ ์ ์๋ก
p1 = getPrime ( 420 ); p2 = getPrime ( 420 ); p3 = getPrime ( 420 )
print ( f 'p1 = { p1 } ' ); print ( f 'p2 = { p2 } ' ); print ( f 'p3 = { p3 } ' )
print ( f 'c1 = { flag % p1 } ' ) # flag ๋ฅผ ๊ฐ ์์๋ก ๋๋ ๋๋จธ์ง๋ง ๊ณต๊ฐ
print ( f 'c2 = { flag % p2 } ' )
print ( f 'c3 = { flag % p3 } ' ) prob.py โ flag๋ฅผ ์ ์๋ก ๋ฐ๊พผ ๋ค 420๋นํธ ์์ 3๊ฐ๋ก ๋๋ ๋๋จธ์ง c1,c2,c3๋ง ์ถ๋ ฅ
flag๋ฅผ ์ ์๋ก ๋ง๋ ๋ค, ์ธ ๊ฐ์ 420๋นํธ ์์๋ก ๋๋ ๋๋จธ์ง c1, c2, c3 ์ ์ถ๋ ฅํ๋ค. output.txt ์๋ ์์ ์ธ ๊ฐ์ ๋๋จธ์ง ์ธ ๊ฐ๊ฐ ๊ทธ๋๋ก ๋ค์ด ์๋ค.
output.txt โ p1,p2,p3 (420๋นํธ ์์)์ c1,c2,c3 (๋๋จธ์ง)์ ํฐ ์ ์ ๊ฐ๋ค
์ฆ ์ฐ๋ฆฌ๊ฐ ์๋ ๊ฒ์ pi ์ flag mod pi ๋ฟ์ด๋ค. ๋ฑ CRT๊ฐ ํ์ด๋ด๋ผ๋ ํํ๋ค.
๐ฃ ํต์ฌ โ ์ ํ๋๋ก๋ ์ ๋๊ณ , ์
์ด๋ฉด ๋๋๊ฐ ๋๋จธ์ง ํ๋(c1 = flag mod p1 )๋ง์ผ๋ก๋ flag๋ฅผ ๋ชป ๋๋๋ฆฐ๋ค. flag๊ฐ p1 ๋ณด๋ค ํฌ๊ธฐ ๋๋ฌธ์ด๋ค. flag๋ ์ฝ 471๋นํธ(์ฝ 59๋ฐ์ดํธ)์ธ๋ฐ p1 ์ 420๋นํธ๋ผ, flag mod p1 ์ ์ด๋ฏธ ํ ๋ฐํด ์ด์ ๋์ ๋์จ ๊ฐ์ด๋ค. c1 ๋ง์ผ๋ก flag๊ฐ c1 ์ธ์ง c1 + p1 ์ธ์ง c1 + 2ยทp1 ์ธ์ง ์ ์ ์๋ค.
๊ทธ๋ฐ๋ฐ ์๋ก ๋ค๋ฅธ ์์ ์ธ ๊ฐ๋ก ๋๋ ๋๋จธ์ง๋ฅผ ๋ชจ๋ ์๋ฉด ์ด์ผ๊ธฐ๊ฐ ๋ฌ๋ผ์ง๋ค. ์ธ ์์์ ๊ณฑ N = p1ยทp2ยทp3 ์ ์ฝ 1259๋นํธ๋ผ flag(471๋นํธ)๋ณด๋ค ํจ์ฌ ํฌ๋ค. CRT๋ 0 โค x < N ๋ฒ์์์ ์ธ ๋๋จธ์ง ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํ๋ x ๋ฅผ ์ ์ผํ๊ฒ ์ค๋ค. flag๊ฐ ์ด ๋ฒ์ ์์ ์์ผ๋, ๊ทธ ์ ์ผํ x ๊ฐ ๋ฐ๋ก flag๋ค. ์์ ์๋ก ์๋ฆฌ๋ฅผ ๋จผ์ ํ์ธํด ๋ดค๋ค.
CRT ์์ ์ ์์ฐ โ xโก2(mod3), xโก3(mod5), xโก2(mod7)์ ์ ์ผํด x=23 mod 105
x โก 2 (mod 3) , x โก 3 (mod 5) , x โก 2 (mod 7) ๋ฅผ CRT๋ก ํฉ์น๋ฉด x = 23 ํ๋๋ก ๋จ์ด์ง๊ณ , ์ค์ ๋ก 23 ์ ๊ฐ ์๋ก ๋๋๋ฉด ์ํ๋ ๋๋จธ์ง๊ฐ ๋์จ๋ค. ์ด ๋ฌธ์ ๋ ๋๊ฐ์ด, ์์๋ง ํจ์ฌ ํด ๋ฟ์ด๋ค.
๐ ์ต์คํ๋ก์ CRT ๊ณต์์ ๊ทธ๋๋ก ๊ตฌํํด ์ธ ํฉ๋์์ ํฉ์น๋ค.
from Crypto.Util.number import long_to_bytes
vals = {}
for line in open ( "output.txt" ):
k, v = line. split ( " = " ); vals[k. strip ()] = int (v)
ps = [vals[ "p1" ], vals[ "p2" ], vals[ "p3" ]]
cs = [vals[ "c1" ], vals[ "c2" ], vals[ "c3" ]]
def crt ( rem , mod ):
from functools import reduce
N = reduce ( lambda a , b : a * b, mod); x = 0
for r, m in zip (rem, mod):
Ni = N // m
x += r * Ni * pow (Ni, - 1 , m) # Niยท(Niโปยน mod m) : m ์์๋ง 1
return x % N
flag = crt (cs, ps)
print ( long_to_bytes (flag). decode ()) solve.py ์คํ โ CRT๋ก flag ์ ์๋ฅผ ๋ณต์ํ๊ณ long_to_bytes๋ก ๋์ฝ๋ํด ํ๋๊ทธ ์ถ๋ ฅ
๋ณต์ํ ์ ์๊ฐ ์ ๋ง flag๊ฐ ๋ง๋์ง, ๋นํธ ์์ ๋๋จธ์ง ์๋ณต์ผ๋ก ํ์ธํ๋ค.
๊ฒ์ฆ โ flag 471๋นํธ < p1p2p3 1259๋นํธ, ๋ณต์๊ฐ์ ๊ฐ ์์๋ก ๋๋๋ฉด ์๋ c1,c2,c3์ ์ผ์น
flag๋ 471๋นํธ๋ก N (1259๋นํธ)๋ณด๋ค ์์ CRT ์กฐ๊ฑด์ ๋ง์กฑํ๊ณ , ๋ณต์ํ ์ ์๋ฅผ ๋ค์ ๊ฐ ์์๋ก ๋๋๋ฉด ์๋ ๋๋จธ์ง c1, c2, c3 ์ ์ ํํ ์ผ์นํ๋ค. ๋ฐ์ดํธ๋ก ๋๋๋ฆฌ๋ฉด ํ๋๊ทธ๋ค.
DH{Th3_Ch1n35e_r3m4iNd3r_tHe0r3m_w4s_qu1T3_345y_r1ght??_:)} "The Chinese remainder theorem was quite easy, right?" โ ์ ๋ง ๊ทธ๋ ๋ค.
๐ ๊ฒฐ๋ก CRT๋ ๋๋จธ์ง ์กฐ๊ฐ๋ค์ ์๋ณธ์ผ๋ก ๋๋๋ฆฌ๋ ์ ๋ฆฌ๋ค.
์ด ๋ฌธ์ ๋ flag๋ฅผ ์ธ ๊ฐ์ ๋๋จธ์ง๋ก ์ชผ๊ฐฐ์ง๋ง, ์๋ก์์ธ ์์๋ค์ ๊ณฑ์ด flag๋ณด๋ค ํฌ๊ธฐ๋ง ํ๋ฉด ๊ทธ ์กฐ๊ฐ๋ค์ ์ธ์ ๋ ํ๋๋ก ํฉ์ณ์ง๋ค. CRT๋ RSA-CRT(๊ฐ์ธํค ์ฐ์ฐ ๊ฐ์), ๋น๋ฐ ๋ถ์ฐ, ๊ฒฉ์ ๊ณต๊ฒฉ ๋ฑ ์ํธํ ๊ณณ๊ณณ์์ ์ฐ์ด๋ ๊ธฐ๋ณธ ๋๊ตฌ๋ค. "๋๋จธ์ง๋ง ๊ณต๊ฐํ๋ฉด ์์ ํ๊ฒ ์ง"๋ผ๋ ์ง๊ด์, ๋ชจ๋๋ฌ๋ค์ ๊ณฑ์ด ์๋ณธ๋ณด๋ค ํฐ ์๊ฐ ๋ฌด๋์ง๋ค.
์ ๋ณด๋ฅผ ์กฐ๊ฐ๋ด ํ๋ ค๋, ์กฐ๊ฐ์ด ์ถฉ๋ถํ๋ฉด ๋ณต์๋๋ค.
๊ฐ๊ฐ์ ci ๋ flag์ ์ผ๋ถ ์ ๋ณด์ ๋ถ๊ณผํด ๋ณด์ธ๋ค. ํ์ง๋ง ์๋ก์์ธ ๋ชจ๋๋ฌ๋ก ์ป์ ๋๋จธ์ง๋ค์ ๊ฒน์น์ง ์๋ ์ ๋ณด๋ผ, ๊ณฑ์ด ์๋ณธ์ ๋ฎ์ ๋งํผ ๋ชจ์ด๋ฉด ์์ ํ ์ฌ๊ตฌ์ฑ๋๋ค. ๊ฐ์ ์ง์ง๋ก ์จ๊ธฐ๋ ค๋ฉด ๋๋จธ์ง ๊ฐ์ยทํฌ๊ธฐ๋ฅผ ์๋ณธ๋ณด๋ค ์๊ฒ ์ ์งํ๊ฑฐ๋(์ ๋ณด๋ฅผ ๋ถ์กฑํ๊ฒ), ์ ์ด์ ๋๋จธ์ง๊ฐ ์๋๋ผ ๋๋๋ฆด ์ ์๋ ํํ๋ก ๊ฐ์ถฐ์ผ ํ๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ