본문 바로가기

CTF

TUCTF 2017 write up

[Only Reversing Write up]


Funmail - 25



id = "john galt" , pw = "this-password-is-a-secret-to-everyone!"



Funmail2.0 - 50


해당 문제 메인을 보면 id와 pw가 맞아도 25점 문제처럼 mail 을 실행시키는 함수가 없다.

따로 함수를 찾아보면 printFlag() 라는 함수가 존재한다.



1
2
> str(bytearray([ord(i)^7 for i in "zf760ow4l4X407}4bX;X~3w7~|T@WO@"])).encode('rot13')[::-1]
'TUCTF{l0c4l_<_r3m073_3x3cu710n}'
cs


Unknown - 200


main 함수모습을 보면 인자로 입력한 문자열 길이가 56 이여야 한다.

사실상 밑에 출력부분을 보면 인자가 Flag인걸 알 수 있다.

후에 sub_401E90 함수에서 입력한 문자열을 확인한다.

sub_400A1C 함수는 보기에 어떤 역할을 하는지 잘 몰랐는데

직접 동적디버깅 해보고 값을 보니 md4 암호화 인걸 알 수 있었다.  

입력한 값을 암호화 한 후 &unk_401DAC에 있는 값들과 비교를 한다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import hashlib
 
c = [0xFDFAB57A, 0x032449A7, 0x5F383821, 0xFDFAB57A, 0x25435E02, 0x59E2EB0D, 0x5ED756D7, 0x5CFFF023, 0x9239BDF3,
     0xF62C7F9B, 0x63E13F5F, 0xD6338E84, 0x5CFFF023, 0xFF20BDEF, 0xC51F928E, 0x63E13F5F, 0xFF20BDEF, 0xC51F928E,
     0xB59D1071, 0xF62C7F9B, 0xC51F928E, 0x388D9870, 0xFF20BDEF, 0xCEECC5BA, 0xA952136B, 0x96710841, 0xFF20BDEF,
     0xC51F928E, 0xF536DFFD, 0xCEECC5BA, 0xA952136B, 0xC5D7DAC4, 0xFF20BDEF, 0x12A92A61, 0x63E13F5F, 0xB59D1071,
     0xFF20BDEF, 0x388D9870, 0x63E13F5F, 0xCD78354E, 0xFF20BDEF, 0xF2184419, 0xCEECC5BA, 0xCD78354E, 0xC51F928E,
     0x3CA8BFDC, 0xF62C7F9B, 0x3CA8BFDC, 0xF2184419, 0xCEECC5BA, 0xC51F928E, 0x3CA8BFDC, 0xA952136B, 0x2FF35144,
     0xBA165EA7, 0xEF1B84CD]
 
 
def ROL(data, shift, size=32):
    shift %= size
    remains = data >> (size - shift)
    body = (data << shift) - (remains << size)
    return (body + remains)
 
 
if __name__ == "__main__":
    flag = ""
    for j in c:
        for i in range(0, 127):
            string = chr(i)
            md5 = hashlib.new("md4")
            md5.update(string)
            h = int(md5.hexdigest()[24:], 16) * 31337 & 0xffffffff
            if ROL(h, 0x15) == j:
                flag += string
                break
    print flag
 
# TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}
cs


Future - 250


해당 main 과 핵심 함수들의 모습이다. 

입력한 값들을 두개의 함수로 암호화 시킨 후 값이 v7과 같다면 성공이다.

간단히 역연산을 할 수도 있지만 z3을 이용해 풀이했다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from z3 import *
 
s = Solver()
flag = [BitVec("flag[%d]" % i, 16) for i in range(25)]
s.add(flag[24] == 125)  # '}'
s.add(flag[0] == 84)  # 'T'
s.add(flag[1] == 85)  # 'U'
s.add(flag[2] == 67)  # 'C'
s.add(flag[3] == 84)  # 'T'
s.add(flag[4] == 70)  # 'F'
s.add(flag[5] == 123)  # '{'
 
for i in range(25):
    s.add(flag[i] >= 0)
    s.add(flag[i] <= 127)
 
 
def genMatrix(mat, s):
    for i in range(25):
        m = (i * 2) % 25
        f = (i * 7) % 25
        mat[m / 5][m % 5] = s[f]
 
 
def genAuthString(mat, auth):
    auth[0] = mat[0][0] + mat[4][4]
    auth[1] = mat[2][1] + mat[0][2]
    auth[2] = mat[4][2] + mat[4][1]
    auth[3] = mat[1][3] + mat[3][1]
    auth[4] = mat[3][4] + mat[1][2]
    auth[5] = mat[1][0] + mat[2][3]
    auth[6] = mat[2][4] + mat[2][0]
    auth[7] = mat[3][3] + mat[3][2] + mat[0][3]
    auth[8] = mat[0][4] + mat[4][0] + mat[0][1]
    auth[9] = mat[3][3] + mat[2][0]
    auth[10] = mat[4][0] + mat[1][2]
    auth[11] = mat[0][4] + mat[4][1]
    auth[12] = mat[0][3] + mat[0][2]
    auth[13] = mat[3][0] + mat[2][0]
    auth[14] = mat[1][4] + mat[1][2]
    auth[15] = mat[4][3] + mat[2][3]
    auth[16] = mat[2][2] + mat[0][2]
    auth[17] = mat[1][1] + mat[4][1]
 
 
mat = [[0] * 5 for i in range(5)]
genMatrix(mat, flag)
 
auth = []
for i in range(19): auth.append(0)
genAuthString(mat, auth)
 
passwd = [0x8b, 0xce, 0xb0, 0x89, 0x7b, 0xb0, 0xb0, 0xee, 0xbf, 0x92, 0x65, 0x9d, 0x9a, 0x99, 0x99, 0x94, 0xad, 0xe4, 0x00]
 
for i in range(19):
    s.add(passwd[i] == auth[i])
 
print s.check()
arr = s.model()
 
key = ''.join([chr(int(str(arr[flag[i]]))) for i in range(0, 25)])
print key
 
# TUCTF{5y573m5_0f_4_d0wn!}
cs