λ¬Έμ : DreamHack β ICM2022 λΆλ₯: Crypto λμ΄λ: π₯ Bronze 2 FLAG:
DH{10112210997116104}
μνΈλ¬Έ λ± νλ(q)μ 곡κ°λ νλΌλ―Έν° μΌλΆλ§ μ£Όκ³ νλ¬Έμ 볡μνλΌλ λ¬Έμ λ€. κ²λ³΄κΈ°μ λ κ°μ ν€κ° μ½ν 볡μ‘ν μμ΄μ§λ§, μ€μ λ‘ λΉλ°μ ν€ νλμ μ’μ λ²μλΏμ΄λ€. μ μλΌλ μ μ½ νλκ° κ·Έ λ²μλ₯Ό μ λ΅ νλλ‘ μ’ν μ€λ€.

λ¬Έμ κ°μ
| νλͺ© | λ΄μ© |
|---|---|
| λ¬Έμ λͺ | ICM2022 |
| λμ΄λ | π₯ Bronze 2 |
| λΆλ₯ | Crypto |
| μ 곡 νμΌ | main.py, readme.txt |
| μ€ν | Python 3 (fractions.Fraction) |
| ν΅μ¬ μ·¨μ½μ | ν€ κ³΅κ°μ΄ μ’κ³ μ μ μ μ½μ΄ κ°ν΄ μ μμ‘°μ¬λ‘ νλ¬Έ 볡μ |
readme.txtκ° μ λ°μ―€ 곡κ°λ νλΌλ―Έν°λ₯Ό μλ € μ£Όκ³ , "볡νΈν pλ₯Ό DH{μ¬κΈ°}μ λ£μΌλΌ"κ³ μλ΄νλ€. μ¦ μ°λ¦¬κ° ꡬν 건 νλ¬Έ μ μ p κ·Έ μ체λ€.
π§© λ°°κ²½ β κ±°λμ κ³±μ μ°¨μ΄μ νλ¬Έμ μ€μλ€
μνΈν ν¨μλ νλ¬Έ pλ₯Ό λ ν€μ κ±°λμ κ³± μ°¨μ΄μ κ³±ν΄ νλμ μ 리μ qλ‘ λ§λ λ€.
def enc(p, n, key1, key2):
q = (Fraction(p, n+1) * key1**(n+1)) - (Fraction(p, n+1) * key2**(n+1))
return qFraction(p, n+1)μ 곡ν΅μΌλ‘ λ¬ΆμΌλ©΄ μμ΄ λ¨μν΄μ§λ€.
q = (p / (n+1)) Β· ( key1^(n+1) β key2^(n+1) )n, key1, key2κ° λͺ¨λ μμλΌλ©΄ qλ pμ μ΄λ€ μ ν΄μ§ μ 리μλ₯Ό κ³±ν κ°μΌ λΏμ΄λ€. κ·Έ κ³±νλ μμλ§ μλ©΄ λλμ
ν λ²μΌλ‘ pκ° λμμ¨λ€. μ΄ λ¬Έμ μ μ λΆλ "κ·Έ μμ, νΉν key1μ μ΄λ»κ² νΉμ νλλ"λ€.
π¬ μ½λ μ μ°° β 무μμ΄ κ³΅κ°λλ
readme.txtκ° μλ € μ£Όλ κ°μ μ΄λ λ€.
n = 3
key1 = #cencored#
key2 = 95
q = -200640142664324295933714
p = #cencored# (p is number)n = 3μ΄λ n+1 = 4λ€. key2 = 95λ 곡κ°, qλ 곡κ°, κ·Έλ°λ° key1κ³Ό pλ κ°λ €μ Έ μλ€. ν€ μμ± μ½λλ₯Ό 보면 key1μ λ²μμ κ²°μ μ ννΈκ° μλ€.
def key_make():
n, key1, key2 = 0, 1, 0
while key2 < key1: # key2 < key1 μΈ λμ κ³μ λ€μ λ½μ
n = random.randrange(1, 10)
key1 = random.randrange(1, 100)
key2 = random.randrange(1, 100)
return n, key1, key2while key2 < key1μ μ‘°κ±΄μ΄ μ°ΈμΈ λμ λ°λ³΅νλ―λ‘, 루νλ₯Ό λΉ μ Έλμ€λ μκ°μ key2 >= key1 μ΄λ€. μ¦ key1 <= key2 = 95. κ²λ€κ° μ£Όμ΄μ§ qκ° μμλΌλ μ¬μ€μ΄ λ²μλ₯Ό λ μ’νλ€. q = (p/4)(key1^4 β 95^4)μμ pλ μμ(λ¬Έμλ€μ ordλ₯Ό μ΄μ΄ λΆμΈ μ)μ΄λ, qκ° μμμ΄λ €λ©΄ key1^4 β 95^4 < 0, κ³§ key1 < 95 μ¬μΌ νλ€. ν보λ κ³ μ 1..94λ€.
π§± λ°°κ²½ β νλ¬Έ pλ ASCII μ½λλ₯Ό μ΄μ΄ λΆμΈ μ
main.pyλ μ
λ ₯ λ¬Έμμ΄μ μ΄λ κ² μ«μλ‘ λ°κΎΌλ€.
p = ""
for character in emp:
p += str(ord(character)) # κ° κΈμμ ord λ₯Ό λ¬Έμμ΄λ‘ μ΄μ΄ λΆμord('e') = 101, ord('z') = 122 β¦ μ΄λ° κ°μ κ·Έλλ‘ λ¬Έμμ΄λ‘ λΆμ¬ νλμ ν° μ μλ‘ λ§λ λ€. κ·Έλμ 볡μν pλ₯Ό λμΈ μλ¦¬μ© λμ΄ chrλ‘ λλ리면 μλ¬Έμ΄ λμ¨λ€. μλλ ASCII μ½λνλ‘, μ°λ¦¬κ° 볡μν μ«μλ€μ΄ μ΄λ€ λ¬Έμμ λμνλμ§ λ³΄μ¬ μ€λ€.

μΆμ²: Wikimedia Commons, public domain
μ΄ μ¬μ€μ μ λ΅ κ²μ¦μλ μ°μΈλ€. μ μμ‘°μ¬λ‘ λμ¨ p νλ³΄κ° μ€μ νλ¬Έμ΄λΌλ©΄, κ·Έ μ«μλ λ°λμ μ ν¨ν ASCII μ½λ(λλ΅ 32~126)λ€λ‘ κΉλνκ² μͺΌκ°μ ΈμΌ νλ€. μ무 μ μλ λλ κ² μλλΌ "ASCIIλ‘ μ½νλ μ μ"λΌλ μ‘°κ±΄μ΄ μ λ΅μ ν λ² λ κ±Έλ¬ μ€λ€.
π£ ν΅μ¬ β λΆμ λ°©μ μμ μ μ 쑰건μΌλ‘ λ«λλ€
μμ pμ λν΄ νλ©΄ μ΄λ λ€.
p = 4Β·q / ( key1^4 β 95^4 )key1 νλλ₯Ό λͺ¨λ₯΄λ λ―Έμ§μκ° λ(κ°μ΄ νλλ‘ μ μ ν΄μ§λ λΆμ λ°©μ μ)μ²λΌ 보μ΄μ§λ§, μ¬κΈ°μ κ°ν μ μ½μ΄ λ κ° λΆλλ€.
pλ μμ μ μμ¬μΌ νλ€ (λλμ μ΄ λ± λ¨μ΄μ ΈμΌ νλ€).- κ·Έ μ μλ ASCII μ½λμ λμ΄μ΄μ΄μΌ νλ€.
key1μ 1..94λ‘ νμΌλ©° 4qκ° (key1^4 β 95^4)λ‘ λλμ΄λ¨μ΄μ§λ κ²½μ°λ§ λ¨κΈ°λ©΄ νλ³΄κ° ν μ€λ€. κ±°κΈ°μ "ASCIIλ‘ μ½νλκ°"λ₯Ό λνλ©΄ μ λ΅ key1μ΄ μ μΌνκ² λ¨λλ€. μ’μ ν€ κ³΅κ° + μ μ/ν¬λ§· μ μ½μ μ‘°ν©μ΄ μ΄λ° λΆμ λ°©μ μν λ¬Έμ λ₯Ό νΈλ μ νμ μΈ μ΄μ λ€.
βΆπ μ½μ§ β key1 λ²μλ₯Ό μλͺ» μ½μ΄ ν€λ§΄
μ²μμ while key2 < key1μ "μ’
λ£ μ key2 < key1"λ‘ μ°©κ°ν΄ key1μ 96..99λ‘ μ‘κ³ λλ Έλ€. λΉμ°ν μ μλ‘ λ¨μ΄μ§λ key1μ΄ μμ΄ νλ³΄κ° 0κ°μλ€. 루νμ μ’
λ£ μ‘°κ±΄(μ°ΈμΈ λμ λ°λ³΅ β μ’
λ£ μ 쑰건 κ±°μ§)μ λ€μ μ§κ³ λμμΌ key1 <= 95, q<0κΉμ§ λν΄ 1..94λ‘ μ’νκ³ , κ·Έμ μΌ key1 = 38μμ κΉλν μ μ pκ° λμλ€.
π― νμ΄ β key1 μ μμ‘°μ¬
key1μ 1..94λ‘ λ리며 pκ° μμ μ μμΈμ§, ASCIIλ‘ μͺΌκ°μ§λμ§ νμΈνλ€.
# solve.py
from fractions import Fraction
n, key2 = 3, 95
q = -200640142664324295933714
for key1 in range(1, 95):
denom = key1**(n+1) - key2**(n+1)
p = Fraction(q*(n+1), denom)
if p.denominator == 1 and p.numerator > 0: # μ μ & μμ
s = str(p.numerator)
dec, i, ok = "", 0, True
while i < len(s): # 2~3μ리 ord λ‘ κ·Έλ¦¬λ λμ½λ
for L in (2, 3):
if i+L <= len(s) and 32 <= int(s[i:i+L]) <= 126:
dec += chr(int(s[i:i+L])); i += L; break
else:
ok = False; break
print(f"key1={key1} p={p.numerator}")
if ok: print(f" decodes-> {dec!r}")
key1 = 38μμ p = 10112210997116104κ° λμ€κ³ , μ΄λ₯Ό λμΈ μλ¦¬μ© λμΌλ©΄ 101 122 109 97 116 104 = ord('e','z','m','a','t','h') = "ezmath"λ‘ κΉλνκ² μ½νλ€. readme.txtλ "볡νΈν pλ₯Ό λ£μΌλΌ"κ³ νμΌλ, νλκ·Έλ κ·Έ μ«μ p μ체λ€.
FLAG: DH{10112210997116104}
π κ²°λ‘
ν€κ° λ κ°λΌλ νλκ° κ³΅κ°λκ³ νλκ° μ’μΌλ©΄ λμ΄λ€.
μνΈμμ λ ν€μ κ±°λμ κ³± μ°¨μ΄λΌλ κ·Έλ΄μΈν λͺ¨μμ νκ³ μμ§λ§, ν ν€κ° 곡κ°λκ³ λ€λ₯Έ ν€λ 100 λ―Έλ§μ΄λΌλ μκ° μ€μ λΉλ°μ 100κ°μ§λ μ λλ€. ν€ κ³΅κ°μ΄ μμΌλ©΄ κ΅¬μ‘°κ° λ³΅μ‘ν΄λ μ μμ‘°μ¬κ° λ΅μ΄λ€.
μ μΒ·ν¬λ§· μ μ½μ κ·Έ μμ²΄λ‘ λ°©μ μμ΄λ€.
λ―Έμ§μκ° νλ λ¨μ λΆμ λ°©μ μμ΄λΌλ, "μ μλ‘ λ¨μ΄μ ΈμΌ νλ€", "ASCIIλ‘ μ½νμΌ νλ€" κ°μ μ μ½μ κ±Έλ©΄ ν΄κ° νλλ‘ λ«νλ€. μμ°μ΄ νλ¬Έμ΄λΌλ μ±μ§κ³Ό μ μ λλμ μ΄λΌλ μ±μ§μ νλ³μλ‘ μ°λ κ²μ crypto λ¬Έμ μμ λκ³ λκ³ ν΅νλ μ§λ¦κΈΈμ΄λ€.
Comments
λκΈ
λκΈμ λ¨κΈ°λ €λ©΄ λ‘κ·ΈμΈμ΄ νμν΄μ. (λ€μ΄λ² Β· κ΅¬κΈ κ³μ )
λκΈ λΆλ¬μ€λ μ€β¦