[CTF write up] Codegate CTF 2022 Junior - Lotto : Basic Window Reversing

2022. 3. 6. 00:41CTF write up

import sympy

a1 = sympy.Symbol('a1')
a2 = sympy.Symbol('a2')
a3 = sympy.Symbol('a3')
a4 = sympy.Symbol('a4')
a5 = sympy.Symbol('a5')
a6 = sympy.Symbol('a6')

eq1 = a2 + 2 * a1 - 20
eq2 = a3 + 7 * a1 - a2 - 35
eq3 = 7 * a2 - 2 * a1 - a3 - 64
eq4 = 5 * a3 + 3 * a1 - a2 - 135
eq5 = 3 * a5 + a4 - 156
eq6 = a6 + 3 * a4 - a6 * a5 + 1530
eq7 = a6 + a5 - a4 - 46

result = sympy.solve((eq1,eq2,eq3,eq4,eq5,eq6,eq7), dict=True)
print(result)

eq1 = a3 + a2 + a1 - 23
eq2 = a3 + 2 * a1 - a2 - 4
eq3 = 3 * a1 + a3 + 2 * a2 - 35
eq4 = 17 * a5 + 7 * a4 - 469
eq5 = 3 * a6 + 2 * a4 - a5 - 143
eq6 = a5 + 3 * a4 - a6 - 25
eq7 = -2 * a4 + a6 + 3 * a5 - 75

result = sympy.solve((eq1,eq2,eq3,eq4,eq5,eq6,eq7), dict=True)
print(result)

eq1 = a2 + 2 * a1 - 36
eq2 = a3 + a1 - a2 - 9
eq3 = a2 + a1 - a3 - 1
eq4 = a4 + 2 * a5 - 100
eq5 = a6 + a5 + a4 - 103
eq6 = 3 * a5 + a4 - 2 * a6 - 60

result = sympy.solve((eq1,eq2,eq3,eq4,eq5,eq6), dict=True)
print(result)

eq1 = a2 + 31 * a1 - a3 - 56
eq2 = 2 * a2 - a1 - a3 - 1
eq3 = 5 * a3 + 3 * a2 + 7 * a1 - 116
eq4 = a6 + a5 - a4 - 54
eq5 = a6 + a4 - a5 - 36
eq6 = a6 + a5 + a4 - 112

result = sympy.solve((eq1,eq2,eq3,eq4,eq5,eq6), dict=True)
print(result)

eq1 = 3 * a3 + 3 * a1 + 2 * a2 - 140
eq2 = a3 + a2 - 2 * a1 - 20
eq3 = a3 + 7 * a1 - 3 * a2 - 43
eq4 = 3 * a6 + a4 + 2 * a5 - 242
eq5 = 7 * a6 + 3 * a5 - 7 * a4 - 207
eq6 = 11 * a5 + 3 * a4 - 11 * a6 - 71

result = sympy.solve((eq1,eq2,eq3,eq4,eq5,eq6), dict=True)
print(result)

 

윈도우 바이너리라 ida로 디컴파일해보면 굉장히 난잡하다. 그냥 데이터 영역에 있는 문자열을 살펴보면 Congratulation이나 Submit 같이 로또 검증 함수에 들어갈법한 문자열을 찾아 TP 해주면 손쉽게 검증 함수로 보이는 것을 찾을 수 있다. 검증은 단순히 6~7개의 방정식으로 이루어지기 때문에 다음과 같은 방정식 풀이 코드를 이용해주면 로또 번호를 크랙할 수 있다.