본문 바로가기
# write-up/- ctf

HUST 2017 - Mystic Crypt

by ddddh 2017. 6. 6.

HUST 2017 리버싱 문제 중 랜섬웨어를 모토로 한 문제가 있었다.


다른 사람들은 AES 알고리즘을 파악하여 풀었는데, 나는 z3로 ....


https://github.com/ddddhkim/CTFs/tree/master/HUST/HUST_2017/Mystic_Crytp





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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from z3 import *
 
 
I_LOVE = [0x490x5F0x4C0x300x560x330x5F0x530x650x430x750x520x310x740x790x5F]
I_LOVE += [0x560x650x520x790x5F0x6D0x750x430x480x5F0x410x6E0x640x590x300x75]
I_LOVE += [0x830x5B0xD10x730xD50x680x8E0x200xB00x2B0xFB0x720x810x5F0x820x2D]
I_LOVE += [0x5A0xAA0x410xA10x050xC70x340xE20x4D0x980x750x8C0x290xC10x450xF9]
I_LOVE += [0xF90x350x480xD60x2C0x5D0xC60xF60x9C0x760x3D0x840x1D0x290xBF0xA9]
I_LOVE += [0xFE0x0F0x490x720xFB0xC80x7D0x900xB60x500x080x1C0x9F0x910x4D0xE5]
I_LOVE += [0x7C0xD60x910x0D0x500x8B0x570xFB0xCC0xFD0x6A0x7F0xD10xD40xD50xD6]
I_LOVE += [0xC00x470x4A0x840x3B0x8F0x370x140x8D0xDF0x3F0x080x120x4E0x720xED]
I_LOVE += [0x5B0x960xC40xC40x0B0x1D0x930x3F0xC70xE00xF90x400x160x340x2C0x96]
I_LOVE += [0x870x5F0x3B0x140xBC0xD00x0C0x000x310x0F0x330x080x230x410x410xE5]
I_LOVE += [0xC80x150x1D0xE20xC30x080x8E0xDD0x040xE80x770x9D0x120xDC0x5B0x0B]
I_LOVE += [0x4E0xD90x020x3F0xF20x090x0E0x3F0xC30x060x3D0x370xE00x470x7C0xD2]
I_LOVE += [0x480x050xA80x030x8B0x0D0x260xDE0x8F0xE50x510x430x9D0x390x0A0x48]
I_LOVE += [0x100xCB0x650x6D0xE20xC20x6B0x520x210xC40x560x650xC10x830x2A0xB7]
I_LOVE += [0xE40xE00x010x7B0x6F0xED0x270xA50xE00x080x760xE60x7D0x310x7C0xAE]
I_LOVE += [0x490x5F0x4C0x300x560x330x5F0x530x650x430x750x520x310x740x790x5F]
I_LOVE += [0x560x650x520x790x5F0x6D0x750x430x480x5F0x410x6E0x640x590x300x75]
I_LOVE += [0x040x000x000x000x000x000x000x000x020x000x000x000x000x000x000x00]
I_LOVE += [0xAE0xD70x7B0xAA0xAE0xD70x7B0xAA0xAE0xD70x7B0xAA0xAE0xD70x7B0xAA]
I_LOVE += [0xAE0xD70x7B0xAA0xAE0xD70x7B0xAA0x010x000x000x000x000x000x000x00]
 
 
INDEX = "\x63\x7C\x77\x7B\xF2\x6B\x6F\xC5\x30\x01\x67\x2B\xFE\xD7\xAB\x76\xCA\x82\xC9\x7D\xFA\x59\x47\xF0"
INDEX += "\xAD\xD4\xA2\xAF\x9C\xA4\x72\xC0\xB7\xFD\x93\x26\x36\x3F\xF7\xCC\x34\xA5\xE5\xF1\x71\xD8\x31\x15"
INDEX += "\x04\xC7\x23\xC3\x18\x96\x05\x9A\x07\x12\x80\xE2\xEB\x27\xB2\x75\x09\x83\x2C\x1A\x1B\x6E\x5A\xA0"
INDEX += "\x52\x3B\xD6\xB3\x29\xE3\x2F\x84\x53\xD1\x00\xED\x20\xFC\xB1\x5B\x6A\xCB\xBE\x39\x4A\x4C\x58\xCF"
INDEX += "\xD0\xEF\xAA\xFB\x43\x4D\x33\x85\x45\xF9\x02\x7F\x50\x3C\x9F\xA8\x51\xA3\x40\x8F\x92\x9D\x38\xF5"
INDEX += "\xBC\xB6\xDA\x21\x10\xFF\xF3\xD2\xCD\x0C\x13\xEC\x5F\x97\x44\x17\xC4\xA7\x7E\x3D\x64\x5D\x19\x73"
INDEX += "\x60\x81\x4F\xDC\x22\x2A\x90\x88\x46\xEE\xB8\x14\xDE\x5E\x0B\xDB\xE0\x32\x3A\x0A\x49\x06\x24\x5C"
INDEX += "\xC2\xD3\xAC\x62\x91\x95\xE4\x79\xE7\xC8\x37\x6D\x8D\xD5\x4E\xA9\x6C\x56\xF4\xEA\x65\x7A\xAE\x08"
INDEX += "\xBA\x78\x25\x2E\x1C\xA6\xB4\xC6\xE8\xDD\x74\x1F\x4B\xBD\x8B\x8A\x70\x3E\xB5\x66\x48\x03\xF6\x0E"
INDEX += "\x61\x35\x57\xB9\x86\xC1\x1D\x9E\xE1\xF8\x98\x11\x69\xD9\x8E\x94\x9B\x1E\x87\xE9\xCE\x55\x28\xDF"
INDEX += "\x8C\xA1\x89\x0D\xBF\xE6\x42\x68\x41\x99\x2D\x0F\xB0\x54\xBB\x16"
 
 
def sub_401040(recovery, num):
    for i in range(4):
        for j in range(4):
            recovery[(4*j)+i] ^= I_LOVE[(16*num) + 4 * i + j]
 
    return recovery
 
 
def sub_401A50(recovery):
    recovery_tmp = [0000000000000000]
 
    for x in range(16):
        recovery_tmp[x] = recovery[x]
 
    recovery[5= recovery_tmp[4]
    recovery[6= recovery_tmp[5]
    recovery[7= recovery_tmp[6]
    recovery[4= recovery_tmp[7]
 
    recovery[10= recovery_tmp[8]
    recovery[8= recovery_tmp[10]
 
    recovery[11= recovery_tmp[9]
    recovery[9= recovery_tmp[11]
 
    recovery[15= recovery_tmp[12]
    recovery[14= recovery_tmp[15]
    recovery[13= recovery_tmp[14]
    recovery[12= recovery_tmp[13]
 
    return recovery
 
 
def sub_401C90(recovery):
    for i in range(4):
        for j in range(4):
            recovery[(4*i)+j] = INDEX.find(chr(recovery[(4*i)+j])) 
 
    return recovery
 
 
def sub_4017F0(recovery):
    input_ = [BitVec("input_%d" % x, 32for x in range(16)]
 
    s = Solver()
    for x in range(16): s.add(input_[x] <= 0xff)
 
    for i in range(4):
        v1 = input_[i]
        v2 = (input_[i + 12] ^ input_[i + 8] ^ input_[i + 4] ^ input_[i]) & 0xff
        v3 = (input_[i + 4] ^ input_[i]) & 0xff
        input_[i] ^= v2 ^ 27 * ((v3 >> 7& 1) ^ 2 * v3 & 0xff
        v4 = input_[i + 8] ^ input_[i + 4& 0xff
        input_[i + 4] ^= v2 ^ 27 * ((v4 >> 7& 1) ^ 2 * v4 & 0xff
        v5 = input_[i + 12] ^ input_[i + 8& 0xff
        input_[i + 8] ^= v2 ^ 27 * ((v5 >> 7& 1) ^ 2 * v5 & 0xff
        input_[i + 12] ^= v2 ^ 27 * (((v1 ^ input_[i + 12]) >> 7& 1) ^ 2 * (v1 ^ input_[i + 12]) & 0xff
 
    for i in range(16):
        s.add(input_[i] == recovery[i])    
 
    if s.check() == sat:
        model = s.model()
        for x in model:
            index_ = str(x).find("_"+ 1
            rec_idx = int(str(x)[index_:])
            recovery[rec_idx] = int(str(model[x]))
 
    return recovery
 
 
def decrypt(fd, decrypt_):
 
    while True:
        try:
            recovery = [0000000000000000]
 
            stream = fd.read(0x20)[:0x10]
 
            for l in range(4):
                for m in range(4):
                    recovery[(4*m)+l] = ord(stream[(4*l)+m])
 
            recovery = sub_401040(recovery, 0xe)
            recovery = sub_401A50(recovery)
            recovery = sub_401C90(recovery)
 
            for k in range(0x10xe):
                recovery = sub_401040(recovery, 0xe-k)
                recovery = sub_4017F0(recovery)
                rerecoverycovery = sub_401A50(recovery)
                recovery = sub_401C90(recovery)
 
            recovery = sub_401040(recovery, 0)
 
            result = [0000000000000000]
            for i in range(4):
                for j in range(4):
                    result[ (4*i) + j] = recovery[(4*j) + i]
 
            png = ""
            for x in range(16):
                png += chr(result[x])
            decrypt_.write(png)
 
        except:
            print "[+] Done."
            break
 
 
if __name__ == "__main__":
    print "[+] Hust 2017 rev 150pt"
    print "[+] making \"recovery.png\""
    
    fd = open("Find Me.hust""rb")
    decrypt_ = open("recovery.png""wb")    
    decrypt(fd, decrypt_)
cs



'# write-up > - ctf' 카테고리의 다른 글

Codegate 2019 - The Matirx  (5) 2019.01.30
GoogleCTF 2017 - food  (1) 2017.06.19
[DEFCON 2017] - pegem  (2) 2017.05.10
[Plaid CTF 2017] zamboni  (0) 2017.05.02
[DEFCON 2017] witchcraft  (0) 2017.05.02