바이너리는 64bit elf 파일이고 메인함수를 보면 입력값을 받아서 아래와 같이 여러함수를 거친 후 플래그를 출력해준다.
먼저 numeric 함수를 보면 입력값에서 48을 뺀 값이 9이하인지 확인을 한다. 이를 통해 입력값이 0~9까지의 숫자여야 한다는걸 알 수 있다.
이후 함수들에 대해 분석해보면 각 함수별로 입력값을 통해 여러가지 연산을 하고 있는데 z3로 각 연산에 만족하는 수를 구해주면 된다.
중간에 결과값이 0인 연산과 같은 경우 a[11]이 0일 것이기 때문에 제외한 후 따로 s.add((a[11] - 48) == 0) 요렇게 a[11]을 0으로 지정해줬다.
from z3 import *
a = []
s = Solver()
for i in range(0,20):
a.append(BitVec('a['+str(i)+']',8))
s.add(a[i]<=57,a[i]>=48)
s.add((a[11] - 48) == 0)
s.add((a[15] - 48 + a[4] - 48) == 10)
s.add((a[1] - 48) * (a[18] - 48) == 2)
s.add((a[15] - 48) / (a[9] - 48) == 1)
s.add(a[5] - a[17] == -1)
s.add(a[15] - a[1] == 5)
s.add((a[1] - 48) * (a[10] - 48) == 18)
s.add(a[8] - 48 + a[13] - 48 == 14)
s.add((a[18] - 48) * (a[8] - 48) == 5)
#s.add((a[4] - 48) * (a[11] - 48) == 0)
s.add(a[8] - 48 + a[9] - 48 == 12)
s.add(a[12] - a[19] == 1)
s.add((a[9] - 48) % (a[17] - 48) == 7)
s.add((a[14] - 48) * (a[16] - 48) == 40)
s.add(a[7] - a[4] == 1)
s.add(a[6] - 48 + a[0] - 48 == 6)
s.add(a[2] == a[16])
s.add(a[4] - a[6] == 1)
s.add((a[0] - 48) % (a[5] - 48) == 4)
#s.add((a[5] - 48) * (a[11] - 48) == 0)
s.add((a[10] - 48) % (a[15] - 48) == 2)
#s.add((a[11] - 48) / (a[3] - 48) == 0)
s.add(a[14] - a[13] == -4)
s.add(a[18] - 48 + a[19] - 48 == 3)
s.add(a[3] - 48 + a[17] - 48 == 9)
flag = ""
if s.check() == z3.sat:
try:
m = s.model()
for i in range(0, 20):
flag += chr(int(str(m[a[i]])))
print "Flag = " + flag
except:
print "Not Found"
Flag = 42813724579039578812
'CTF > Writeup' 카테고리의 다른 글
D-CTF Quals 2018 Get Admin (0) | 2018.09.24 |
---|---|
Codegate 2018 CTF RedVelvet (0) | 2018.09.18 |
LAYER7 CTF 2018 Margaret (0) | 2018.09.17 |
LAYER7 CTF 2018 url routing (0) | 2018.09.17 |
Meepwn CTF Quals 2018 OmegaSector (0) | 2018.07.17 |