Layer7 동아리 과제

리버싱 11차시 과제

msh1307 2022. 8. 30. 22:42

prob-3

v4로 32바이트 받고, init_cpu를 호출한다.

init_cpu는 입력받은걸 v5로 복사해준다.

그다음 run_cpu가 호출된다.

이런식으로 opcode에 따라서 명령을 수행하는게 들어가있다.

여기를 조금 눈여겨봐야한다.

a1[16]과 a1[17]에 cmp 명령처럼 비교된 결과가 들어간다.

그리고 그 a1에 따라서 분기한다.

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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
from z3 import *
 
stub = [0x880x010x070x200x000x000x000x880x010x080x000x000x000x000xDA0x020x0A0x8A0xD60xBA0x0C0xE00xE70x120x4C0x770x020x0A0x070x050x290x3C0x360x570x270x440x040x020x0A0xF20x4D0xE80x6B0x350xA90x510xE60x250x0A0x770x000x000x0A0xDA0x020x0B0x780x8F0x590x480xC30x010xEC0xA00x770x020x0B0x980xEE0xCF0xA80x5B0xCA0x130xC50x040x020x0B0xF90x650xEB0x450x9A0x630xC50xF40x250x0B0x040x000x000x0B0xDA0x020x0C0xEE0x280xC60x2B0xCB0xDB0x800x1E0x770x020x0C0x690x6A0x7F0xBE0x390xA10x960x560x040x020x0C0xC30x880xFB0x350x6B0x7C0x5F0xA10x250x0C0xDA0x000x000x0B0xDA0x020x0A0x9E0x4B0x3C0x300x6A0xBE0xFE0x830x770x020x0A0x630x8A0x7D0x7E0x410xFD0xB40xA90x040x020x0A0xB10x9A0x8A0x580x9D0xBE0xA90x9D0x250x0A0x770x000x010x0A0xDA0x020x0B0x9A0x000xC10x6C0x4B0xA00x160x9E0x770x020x0B0x4E0xAC0x030x7A0xB70x8C0x840x3F0x040x020x0B0xB80x7D0x9D0xE50x980x9B0xD60xEC0x250x0B0x040x000x010x0B0xDA0x020x0C0xF80xD30x700xDB0x320xAB0xD90x1C0x770x020x0C0x6A0xC90x000x920xE00xEF0x110x290x040x020x0C0xF50xF30xA40x670x9D0xE90x8D0x940x250x0C0xDA0x000x010x0B0xDA0x020x0A0x240x540x770xBA0x220xD30x190x140x770x020x0A0xC90xF70xE70x890x6B0x830x210x0F0x040x020x0A0x480xD10x690x610x890x5C0x1D0x3A0x250x0A0x770x000x020x0A0xDA0x020x0B0x760xC40x870x5A0xA90xA50x950xEA0x770x020x0B0x260xCD0x730xCD0xAA0xAD0x5C0xCF0x040x020x0B0xF30x1A0x8D0x490x660x120xE40x7C0x250x0B0x040x000x020x0B0xDA0x020x0C0x900xD30xCE0xA10xBB0x4C0x680x070x770x020x0C0xE20xF80x9D0x0C0xB70xAC0x530xBF0x040x020x0C0xDB0x3E0x890xB60x160xAA0x4E0x9E0x250x0C0xDA0x000x020x0B0xDA0x020x0A0xDF0xB70xED0x2F0xA70xBF0x900x300x770x020x0A0x750x750x810x4D0x2B0x450x7C0x2F0x040x020x0A0x9E0x990x4B0x4B0xA00x710xEB0xEB0x250x0A0x770x000x030x0A0xDA0x020x0B0x570x660xA90x7B0xCC0x0A0x5E0xB50x770x020x0B0x750xE20x8E0x770x490xB70x5E0xE60x040x020x0B0x9F0xF60xB40x710xD20xE50x480xD70x250x0B0x040x000x030x0B0xDA0x020x0C0x9F0x040x590xA30xC80xB80xA30x7F0x770x020x0C0x080xDB0x050x600xEB0x3F0xCF0xEB0x040x020x0C0xE50x2B0xE30xC10x940xAA0x480xB10x250x0C0xDA0x000x030x0B0x040x010x080x010x000x000x000xF40x070x080x400x020x0E0x000x000x000x000x000x000x000xCC]
 
rip = 0
 
FLAG = [BitVec("FLAG_%d" %i, 64for i in range(4)]
REG = [x for x in FLAG] + [0* (18 - 4)
 
REG_num = 16
REG_bit = 64
 
bytedef = [0xCC0x880x040xDA0x1C0x4A0x250x770xF40x40]
 
while True:
    if stub[rip] == bytedef[0]:            # RET
        break
    elif stub[rip] == bytedef[1]:          # MOV
        id = stub[rip + 1]
        if id == 0:
            src = stub[rip + 2]
            dst = stub[rip + 3]
            REG[src] = REG[dst]
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 4
        elif id == 1:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 4], "little")
            REG[src] = imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 4
        elif id == 2:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 8], "little")
            REG[src] = imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 8
        else:
            raise Exception("EMULATE ERROR")
    elif stub[rip] == bytedef[2]:          # ADD
        id = stub[rip + 1]
        if id == 0:
            src = stub[rip + 2]
            dst = stub[rip + 3]
            REG[src] += REG[dst]
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 4
        elif id == 1:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 4], "little")
            REG[src] += imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 4
        elif id == 2:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 8], "little")
            REG[src] += imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 8
        else:
            raise Exception("EMULATE ERROR")
    elif stub[rip] == bytedef[3]:          # SUB
        id = stub[rip + 1]
        if id == 0:
            src = stub[rip + 2]
            dst = stub[rip + 3]
            REG[src] -= REG[dst]
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 4
        elif id == 1:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 4], "little")
            REG[src] -= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 4
        elif id == 2:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 8], "little")
            REG[src] -= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 8
        else:
            raise Exception("EMULATE ERROR")
    elif stub[rip] == bytedef[4]:          # AND
        id = stub[rip + 1]
        if id == 0:
            src = stub[rip + 2]
            dst = stub[rip + 3]
            REG[src] &= REG[dst]
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 4
        elif id == 1:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 4], "little")
            REG[src] &= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 4
        elif id == 2:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 8], "little")
            REG[src] &= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 8
        else:
            raise Exception("EMULATE ERROR")
    elif stub[rip] == bytedef[5]:          # OR
        id = stub[rip + 1]
        if id == 0:
            src = stub[rip + 2]
            dst = stub[rip + 3]
            REG[src] |= REG[dst]
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 4
        elif id == 1:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 4], "little")
            REG[src] |= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 4
        elif id == 2:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 8], "little")
            REG[src] |= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 8
        else:
            raise Exception("EMULATE ERROR")
    elif stub[rip] == bytedef[6]:          # NOT
        src = stub[rip + 1]
        REG[src] = ~REG[src]
        REG[src] &= ((1 << REG_bit) - 1)
        rip += 2
    elif stub[rip] == bytedef[7]:          # XOR
        id = stub[rip + 1]
        if id == 0:
            src = stub[rip + 2]
            dst = stub[rip + 3]
            REG[src] ^= REG[dst]
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 4
        elif id == 1:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 4], "little")
            REG[src] ^= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 4
        elif id == 2:
            src = stub[rip + 2]
            imm = int.from_bytes(stub[rip + 3:rip + 3 + 8], "little")
            REG[src] ^= imm
            REG[src] &= ((1 << REG_bit) - 1)
            rip += 3 + 8
        else:
            raise Exception("EMULATE ERROR")
    elif stub[rip] == bytedef[8]:          # CMP
        src = stub[rip + 1]
        dst = stub[rip + 2]
        REG[REG_num] = REG[src] == REG[dst]
        REG[REG_num + 1= src > dst
        rip += 3
    elif stub[rip] == bytedef[9]:
        id = stub[rip + 1]
        if id == 0:
            dst = int.from_bytes(stub[rip + 2:rip + 2 + 8], "little")
            rip = dst
        elif id == 1:
            dst = int.from_bytes(stub[rip + 2:rip + 2 + 8], "little")
            if REG[REG_num] == True:
                rip = dst
            else:
                rip += 2 + 8
        elif id == 2:
            dst = int.from_bytes(stub[rip + 2:rip + 2 + 8], "little")
            if REG[REG_num] == False:
                rip = dst
            else:
                rip += 2 + 8
        else:
            raise Exception("EMULATE ERROR")  
    else:
        raise Exception("EMULATE ERROR")
    
= Solver()
s.add(REG[0== 0x4635CE5D1658B74C)
s.add(REG[1== 0xE1EC52A29AF4B45F)
s.add(REG[2== 0xBDF35F48B8974554)
s.add(REG[3== 0xC42B5522A0596E41)    
 
print(s.check())
 
= s.model()
 
for f in FLAG:
    print(m[f].as_long().to_bytes(8"little").decode(), end="")
print()
 
cs

opcode에 따른 처리가 다 구현된 코드이다.

 

prob-4

구조는 prob-4랑 비슷하다.

init_cpu에서 입력을 복사해준다.

run_cpu의 모습이다.

opcode에 따라서 다른 처리를 한다.

여기서 분기에 관한 부분을 처리한다.

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
from z3 import * 
data = [221712800022180000224210124198762098355119146932103972227482212482005900101201059210191152312441401731841572242108625415911425018151199932101392191164242115818159011012010592101831769591207254121042242101732549722426699814393210421882541751981152052015902101201059210174771392032783182168224210315120497228252331419321019925561841571951842285903101201059210105107103192737149859318100017978332140000000204]
cur = 0
FLAG = [BitVec('FLAG_%d'%i ,64for i in range(4)]
REG = [i for i in FLAG] + [0* 14
while True:
    if(data[cur] == 0xcc):
        break
    elif(data[cur] == 0x16):
        if(data[cur+1== 1):
            print('mov 1')
            REG[data[cur+2]] = int.from_bytes(data[cur+3:cur+7],'little')
            REG[data[cur+2]] &= 0xffffffffffffffff
            cur += 7
        # elif(data[cur+1] == 2):
        #     print('mov 2')
        #     cur += 11
        # else:
        #     cur += 4
    elif(data[cur] == 0x5d):
        if(data[cur+1== 1):
            print('add 1')
            REG[data[cur+2]] += int.from_bytes(data[cur+3:cur+7],'little')
            REG[data[cur+2]] &= 0xffffffffffffffff
            cur += 7
        elif(data[cur+1== 2):
            print('add 2')
            REG[data[cur+2]] += int.from_bytes(data[cur+3:cur+11],'little')
            REG[data[cur+2]] &= 0xffffffffffffffff
            cur += 11
        # else:
        #     print('add 3')
        #     cur += 4
    elif(data[cur] == 0xe0):
        if(data[cur+1== 2):
            print('sub 2')
            REG[data[cur+2]] -= int.from_bytes(data[cur+3:cur+11],'little')
            REG[data[cur+2]] &= 0xffffffffffffffff
            cur += 11
        # elif(data[cur+1] == 1):
        #     print('sub 1')
        #     cur += 7
        # else:
        #     print('sub 3')
        #     cur += 4
    # elif(data[cur] == 0xb2):
    #     if(data[cur+1]==1):
    #         print('or 1')
    #         cur += 7
    #     elif(data[cur+1]==2):
    #         print('or 2')
    #         cur += 11
    #     else:
    #         print('or 3')
    #         cur += 4
    elif(data[cur] == 0x78):
        print('not')
        REG[data[cur+1]] = ~REG[data[cur+1]]
        REG[data[cur+1]] &= 0xffffffffffffffff
        cur += 2
    elif(data[cur] == 0x3b):
        if(data[cur+1]==2):
            print('xor 2')
            REG[data[cur+2]] ^= int.from_bytes(data[cur+3:cur+11],'little')
            REG[data[cur+2]] &= 0xffffffffffffffff
            cur += 11
        # elif(data[cur+1]==1):
        #     print('xor 1')
        #     cur += 7
        else:
            print('xor 3')
            REG[data[cur+2]] ^= REG[data[cur+3]]
            cur += 4
    elif(data[cur] == 0xb3):
        print('cmp')
        REG[16= REG[data[cur+1]] == REG[data[cur+2]]
        REG[17= data[cur+1> data[cur+2]
        cur += 3
    elif(data[cur] == 0x21):
        if(data[cur+1]==2):
            print('jne')
            if(REG[16]):
                cur+=10
            else:
                cur = int.from_bytes(data[cur+2:cur+10],'little'& 0xff
        # elif(data[cur+1] ==1):
        #     print('je')
        #     cur+=10
        # else:
        #     print('jmp')
        #     cur += 10
    # else:
    #     if(data[cur+1]== 1):
    #         print('and 1')
    #         cur += 7
    #     elif(data[cur+2] == 2):
    #         print('and 2')
    #         cur += 11
    #     else:
    #         print('and 3')
    #         cur += 4
 
= Solver()
s.add(REG[0== 0x7ECB527EEABB074C)
s.add(REG[1== 0xE635AE1A1123CE4F)
s.add(REG[2== 0x61467F6C95358D52)
s.add(REG[3== 0x1FA186EA0DBF462E)
s.check()
= s.model()
FLAG = FLAG[::-1]
flag = []
for i in FLAG:
    flag.append(m[i].as_long().to_bytes(8,'little').decode())
print(''.join(flag[::-1]))
cs

처음에는 레지스터들에 대해서 처리해주지 않았고, cur만 더해주면서 사용되는 명령어들을 확인했다.

 

사용되지 않는 명령어들을 찾기 위해서, cur을 더하면서 바이트 코드들을 읽었다.

다음 명령어로 계속 넘겨주면, 굳이 처리를 하지 않더라도 어떤 opcode가 쓰이는지 알 수 있다.

그리고 사용되지 않는 명령어들은 주석처리를 해줬다.

 

사용되는 명령들만 보고 구현을 했다.

그다음 방정식 풀고, flag를 출력해주면 된다.

'Layer7 동아리 과제' 카테고리의 다른 글

포너블 1차시 과제  (0) 2022.09.18
포너블 1차시 실습 라업  (0) 2022.09.14
리버싱 10차시 과제  (0) 2022.08.23
리버싱 9차시 과제  (0) 2022.08.16
리버싱 8차시 과제  (0) 2022.08.10