0%

祥云杯

祥云杯

这次比赛我觉得打的很有意义,有很多值得学习的地方,虽然在最后一分钟被py嘛了,但是还是可以的。

image-20221101103957337

RE

本次re题前两题都是第十个做出来的,但遇到后面的ollvm这种题就寄了,所以跟着其他大佬来复现。

rocket

是⼀个⽤racket写的程序,通过动调发现,应该是程序内部有东⻄可以运⾏某些指令,但运⾏时后⾯参数要填对。⽽且动调发现,输⼊之后会产⽣输出⽂件,通过输出⽂件进⾏对⽐。可以说是当成了黑盒来做

1
2
3
4
5
6
7
8
9
10
11
12
1
117649
2
125000
111
33506364520275803793
121
33514347173167210897
123456
158267354350243993992524262083318636839704
1234567
2655285589682614779062545959380794422209298811879

发现规律,猜测整个加密是将字符串ascii连接起来转成⼤数,然后进⾏⽴⽅,所以解密也就很简单了

1
2
3
4
5
6
from Crypto.Util.number import long_to_bytes
import gmpy2
print(gmpy2.iroot(72122728040135433910084218324574182235447654897640421711359825692113776202902748285267445589769500040520888384194950935232
m = 193207530030250486323082807418528242300453594901698934812368796575822264198418283118461
print(long_to_bytes(m).decode())
#得到flag:ctf{th1s_is_re4lly_beaut1fly_r1ght?}

engtom

通过strings查询字符串可以看出是JS相关的程序,搜索Js引擎和⽂件头可以认出是JerryScript引擎的快照。

启⽤—show-opcodes和—snapshot-exec编译后,执⾏jerry

1
./jerry --show-opcodes --exec-snapshot /mnt/d/ctf/祥云杯/engtom/engtom/chall.snapshot

得到以下结果

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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
0 : CBC_CHECK_VAR ident:5->string(SboxTable)
2 : CBC_CHECK_VAR ident:6->string(CK)
4 : CBC_CHECK_VAR ident:7->string(FK)
6 : CBC_CHECK_VAR ident:8->string(bigxor)
8 : CBC_CHECK_VAR ident:9->string(leftshift)
10 : CBC_CHECK_VAR ident:10->string(prefixInteger)
12 : CBC_CHECK_VAR ident:11->string(sm4Sbox)
14 : CBC_CHECK_VAR ident:12->string(GET_ULONG_BE)
16 : CBC_CHECK_VAR ident:13->string(PUT_ULONG_BE)
18 : CBC_CHECK_VAR ident:14->string(sm4_getkey)
20 : CBC_CHECK_VAR ident:15->string(encrypt)
22 : CBC_CHECK_VAR ident:16->string(decrypt_sm4)
24 : CBC_CHECK_VAR ident:17->string(compare_array)
26 : CBC_CHECK_VAR ident:18->string(input)
28 : CBC_CHECK_VAR ident:19->string(num)
30 : CBC_CHECK_VAR ident:20->string(message)
32 : CBC_CHECK_VAR ident:21->string(count)
34 : CBC_CHECK_VAR ident:22->string(pad_len)
36 : CBC_CREATE_VAR_EVAL ident:5->string(SboxTable)
38 : CBC_CREATE_VAR_EVAL ident:6->string(CK)
40 : CBC_CREATE_VAR_EVAL ident:7->string(FK)
42 : CBC_CREATE_VAR_FUNC_EVAL lit:91 ident:8->string(bigxor)
45 : CBC_CREATE_VAR_FUNC_EVAL lit:92 ident:9->string(leftshift)
48 : CBC_CREATE_VAR_FUNC_EVAL lit:93 ident:10->string(prefixInteger)
51 : CBC_CREATE_VAR_FUNC_EVAL lit:94 ident:11->string(sm4Sbox)
54 : CBC_CREATE_VAR_FUNC_EVAL lit:95 ident:12->string(GET_ULONG_BE)
57 : CBC_CREATE_VAR_FUNC_EVAL lit:96 ident:13->string(PUT_ULONG_BE)
60 : CBC_CREATE_VAR_FUNC_EVAL lit:97 ident:14->string(sm4_getkey)
63 : CBC_CREATE_VAR_FUNC_EVAL lit:98 ident:15->string(encrypt)
66 : CBC_CREATE_VAR_FUNC_EVAL lit:99 ident:16->string(decrypt_sm4)
69 : CBC_CREATE_VAR_FUNC_EVAL lit:100 ident:17->string(compare_array)
72 : CBC_CREATE_VAR_EVAL ident:18->string(input)
74 : CBC_CREATE_VAR_EVAL ident:19->string(num)
76 : CBC_CREATE_VAR_EVAL ident:20->string(message)
78 : CBC_CREATE_VAR_EVAL ident:21->string(count)
80 : CBC_CREATE_VAR_EVAL ident:22->string(pad_len)
82 : CBC_PUSH_LITERAL ident:23->string(Array)
84 : CBC_NEW0
85 : CBC_ASSIGN_SET_IDENT ident:5->string(SboxTable)
87 : CBC_PUSH_LITERAL_PUSH_NUMBER_0 ident:5->string(SboxTable)
89 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:214
92 : CBC_PUSH_NUMBER_POS_BYTE number:144
94 : CBC_PUSH_NUMBER_POS_BYTE number:233
96 : CBC_PUSH_NUMBER_POS_BYTE number:254
98 : CBC_PUSH_NUMBER_POS_BYTE number:204
100 : CBC_PUSH_NUMBER_POS_BYTE number:225
102 : CBC_PUSH_NUMBER_POS_BYTE number:61
104 : CBC_PUSH_NUMBER_POS_BYTE number:183
106 : CBC_PUSH_NUMBER_POS_BYTE number:22
108 : CBC_PUSH_NUMBER_POS_BYTE number:182
110 : CBC_PUSH_NUMBER_POS_BYTE number:20
112 : CBC_PUSH_NUMBER_POS_BYTE number:194
114 : CBC_PUSH_NUMBER_POS_BYTE number:40
116 : CBC_PUSH_NUMBER_POS_BYTE number:251
118 : CBC_PUSH_NUMBER_POS_BYTE number:44
120 : CBC_PUSH_NUMBER_POS_BYTE number:5
122 : CBC_NEW byte_arg:16
124 : CBC_ASSIGN_BLOCK
125 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:1
128 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:43
131 : CBC_PUSH_NUMBER_POS_BYTE number:103
133 : CBC_PUSH_NUMBER_POS_BYTE number:154
135 : CBC_PUSH_NUMBER_POS_BYTE number:118
137 : CBC_PUSH_NUMBER_POS_BYTE number:42
139 : CBC_PUSH_NUMBER_POS_BYTE number:190
141 : CBC_PUSH_NUMBER_POS_BYTE number:4
143 : CBC_PUSH_NUMBER_POS_BYTE number:195
145 : CBC_PUSH_NUMBER_POS_BYTE number:170
147 : CBC_PUSH_NUMBER_POS_BYTE number:68
149 : CBC_PUSH_NUMBER_POS_BYTE number:19
151 : CBC_PUSH_NUMBER_POS_BYTE number:38
153 : CBC_PUSH_NUMBER_POS_BYTE number:73
155 : CBC_PUSH_NUMBER_POS_BYTE number:134
157 : CBC_PUSH_NUMBER_POS_BYTE number:6
159 : CBC_PUSH_NUMBER_POS_BYTE number:153
161 : CBC_NEW byte_arg:16
163 : CBC_ASSIGN_BLOCK
164 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:2
167 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:156
170 : CBC_PUSH_NUMBER_POS_BYTE number:66
172 : CBC_PUSH_NUMBER_POS_BYTE number:80
174 : CBC_PUSH_NUMBER_POS_BYTE number:244
176 : CBC_PUSH_NUMBER_POS_BYTE number:145
178 : CBC_PUSH_NUMBER_POS_BYTE number:239
180 : CBC_PUSH_NUMBER_POS_BYTE number:152
182 : CBC_PUSH_NUMBER_POS_BYTE number:122
184 : CBC_PUSH_NUMBER_POS_BYTE number:51
186 : CBC_PUSH_NUMBER_POS_BYTE number:84
188 : CBC_PUSH_NUMBER_POS_BYTE number:11
190 : CBC_PUSH_NUMBER_POS_BYTE number:67
192 : CBC_PUSH_NUMBER_POS_BYTE number:237
194 : CBC_PUSH_NUMBER_POS_BYTE number:207
196 : CBC_PUSH_NUMBER_POS_BYTE number:172
198 : CBC_PUSH_NUMBER_POS_BYTE number:98
200 : CBC_NEW byte_arg:16
202 : CBC_ASSIGN_BLOCK
203 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:3
206 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:228
209 : CBC_PUSH_NUMBER_POS_BYTE number:179
211 : CBC_PUSH_NUMBER_POS_BYTE number:28
213 : CBC_PUSH_NUMBER_POS_BYTE number:169
215 : CBC_PUSH_NUMBER_POS_BYTE number:201
217 : CBC_PUSH_NUMBER_POS_BYTE number:8
219 : CBC_PUSH_NUMBER_POS_BYTE number:232
221 : CBC_PUSH_NUMBER_POS_BYTE number:149
223 : CBC_PUSH_NUMBER_POS_BYTE number:128
225 : CBC_PUSH_NUMBER_POS_BYTE number:223
227 : CBC_PUSH_NUMBER_POS_BYTE number:148
229 : CBC_PUSH_NUMBER_POS_BYTE number:250
231 : CBC_PUSH_NUMBER_POS_BYTE number:117
233 : CBC_PUSH_NUMBER_POS_BYTE number:143
235 : CBC_PUSH_NUMBER_POS_BYTE number:63
237 : CBC_PUSH_NUMBER_POS_BYTE number:166
239 : CBC_NEW byte_arg:16
241 : CBC_ASSIGN_BLOCK
242 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:4
245 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:71
248 : CBC_PUSH_NUMBER_POS_BYTE number:7
250 : CBC_PUSH_NUMBER_POS_BYTE number:167
252 : CBC_PUSH_NUMBER_POS_BYTE number:252
254 : CBC_PUSH_NUMBER_POS_BYTE number:243
256 : CBC_PUSH_NUMBER_POS_BYTE number:115
258 : CBC_PUSH_NUMBER_POS_BYTE number:23
260 : CBC_PUSH_NUMBER_POS_BYTE number:186
262 : CBC_PUSH_NUMBER_POS_BYTE number:131
264 : CBC_PUSH_NUMBER_POS_BYTE number:89
266 : CBC_PUSH_NUMBER_POS_BYTE number:60
268 : CBC_PUSH_NUMBER_POS_BYTE number:25
270 : CBC_PUSH_NUMBER_POS_BYTE number:230
272 : CBC_PUSH_NUMBER_POS_BYTE number:133
274 : CBC_PUSH_NUMBER_POS_BYTE number:79
276 : CBC_PUSH_NUMBER_POS_BYTE number:168
278 : CBC_NEW byte_arg:16
280 : CBC_ASSIGN_BLOCK
281 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:5
284 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:104
287 : CBC_PUSH_NUMBER_POS_BYTE number:107
289 : CBC_PUSH_NUMBER_POS_BYTE number:129
291 : CBC_PUSH_NUMBER_POS_BYTE number:178
293 : CBC_PUSH_NUMBER_POS_BYTE number:113
295 : CBC_PUSH_NUMBER_POS_BYTE number:100
297 : CBC_PUSH_NUMBER_POS_BYTE number:218
299 : CBC_PUSH_NUMBER_POS_BYTE number:139
301 : CBC_PUSH_NUMBER_POS_BYTE number:248
303 : CBC_PUSH_NUMBER_POS_BYTE number:235
305 : CBC_PUSH_NUMBER_POS_BYTE number:15
307 : CBC_PUSH_NUMBER_POS_BYTE number:75
309 : CBC_PUSH_NUMBER_POS_BYTE number:112
311 : CBC_PUSH_NUMBER_POS_BYTE number:86
313 : CBC_PUSH_NUMBER_POS_BYTE number:157
315 : CBC_PUSH_NUMBER_POS_BYTE number:53
317 : CBC_NEW byte_arg:16
319 : CBC_ASSIGN_BLOCK
320 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:6
323 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:30
326 : CBC_PUSH_NUMBER_POS_BYTE number:36
328 : CBC_PUSH_NUMBER_POS_BYTE number:14
330 : CBC_PUSH_NUMBER_POS_BYTE number:94
332 : CBC_PUSH_NUMBER_POS_BYTE number:99
334 : CBC_PUSH_NUMBER_POS_BYTE number:88
336 : CBC_PUSH_NUMBER_POS_BYTE number:209
338 : CBC_PUSH_NUMBER_POS_BYTE number:162
340 : CBC_PUSH_NUMBER_POS_BYTE number:37
342 : CBC_PUSH_NUMBER_POS_BYTE number:34
344 : CBC_PUSH_NUMBER_POS_BYTE number:124
346 : CBC_PUSH_NUMBER_POS_BYTE number:59
348 : CBC_PUSH_NUMBER_POS_BYTE number:1
350 : CBC_PUSH_NUMBER_POS_BYTE number:33
352 : CBC_PUSH_NUMBER_POS_BYTE number:120
354 : CBC_PUSH_NUMBER_POS_BYTE number:135
356 : CBC_NEW byte_arg:16
358 : CBC_ASSIGN_BLOCK
359 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:7
362 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:212
365 : CBC_PUSH_NUMBER_0
366 : CBC_PUSH_NUMBER_POS_BYTE number:70
368 : CBC_PUSH_NUMBER_POS_BYTE number:87
370 : CBC_PUSH_NUMBER_POS_BYTE number:159
372 : CBC_PUSH_NUMBER_POS_BYTE number:211
374 : CBC_PUSH_NUMBER_POS_BYTE number:39
376 : CBC_PUSH_NUMBER_POS_BYTE number:82
378 : CBC_PUSH_NUMBER_POS_BYTE number:76
380 : CBC_PUSH_NUMBER_POS_BYTE number:54
382 : CBC_PUSH_NUMBER_POS_BYTE number:2
384 : CBC_PUSH_NUMBER_POS_BYTE number:231
386 : CBC_PUSH_NUMBER_POS_BYTE number:160
388 : CBC_PUSH_NUMBER_POS_BYTE number:196
390 : CBC_PUSH_NUMBER_POS_BYTE number:200
392 : CBC_PUSH_NUMBER_POS_BYTE number:158
394 : CBC_NEW byte_arg:16
396 : CBC_ASSIGN_BLOCK
397 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:8
400 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:234
403 : CBC_PUSH_NUMBER_POS_BYTE number:191
405 : CBC_PUSH_NUMBER_POS_BYTE number:138
407 : CBC_PUSH_NUMBER_POS_BYTE number:210
409 : CBC_PUSH_NUMBER_POS_BYTE number:64
411 : CBC_PUSH_NUMBER_POS_BYTE number:199
413 : CBC_PUSH_NUMBER_POS_BYTE number:56
415 : CBC_PUSH_NUMBER_POS_BYTE number:181
417 : CBC_PUSH_NUMBER_POS_BYTE number:163
419 : CBC_PUSH_NUMBER_POS_BYTE number:247
421 : CBC_PUSH_NUMBER_POS_BYTE number:242
423 : CBC_PUSH_NUMBER_POS_BYTE number:206
425 : CBC_PUSH_NUMBER_POS_BYTE number:249
427 : CBC_PUSH_NUMBER_POS_BYTE number:97
429 : CBC_PUSH_NUMBER_POS_BYTE number:21
431 : CBC_PUSH_NUMBER_POS_BYTE number:161
433 : CBC_NEW byte_arg:16
435 : CBC_ASSIGN_BLOCK
436 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:9
439 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:224
442 : CBC_PUSH_NUMBER_POS_BYTE number:174
444 : CBC_PUSH_NUMBER_POS_BYTE number:93
446 : CBC_PUSH_NUMBER_POS_BYTE number:164
448 : CBC_PUSH_NUMBER_POS_BYTE number:155
450 : CBC_PUSH_NUMBER_POS_BYTE number:52
452 : CBC_PUSH_NUMBER_POS_BYTE number:26
454 : CBC_PUSH_NUMBER_POS_BYTE number:85
456 : CBC_PUSH_NUMBER_POS_BYTE number:173
458 : CBC_PUSH_NUMBER_POS_BYTE number:147
460 : CBC_PUSH_NUMBER_POS_BYTE number:50
462 : CBC_PUSH_NUMBER_POS_BYTE number:48
464 : CBC_PUSH_NUMBER_POS_BYTE number:245
466 : CBC_PUSH_NUMBER_POS_BYTE number:140
468 : CBC_PUSH_NUMBER_POS_BYTE number:177
470 : CBC_PUSH_NUMBER_POS_BYTE number:227
472 : CBC_NEW byte_arg:16
474 : CBC_ASSIGN_BLOCK
475 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:10
478 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:29
481 : CBC_PUSH_NUMBER_POS_BYTE number:246
483 : CBC_PUSH_NUMBER_POS_BYTE number:226
485 : CBC_PUSH_NUMBER_POS_BYTE number:46
487 : CBC_PUSH_NUMBER_POS_BYTE number:130
489 : CBC_PUSH_NUMBER_POS_BYTE number:102
491 : CBC_PUSH_NUMBER_POS_BYTE number:202
493 : CBC_PUSH_NUMBER_POS_BYTE number:96
495 : CBC_PUSH_NUMBER_POS_BYTE number:192
497 : CBC_PUSH_NUMBER_POS_BYTE number:41
499 : CBC_PUSH_NUMBER_POS_BYTE number:35
501 : CBC_PUSH_NUMBER_POS_BYTE number:171
503 : CBC_PUSH_NUMBER_POS_BYTE number:13
505 : CBC_PUSH_NUMBER_POS_BYTE number:83
507 : CBC_PUSH_NUMBER_POS_BYTE number:78
509 : CBC_PUSH_NUMBER_POS_BYTE number:111
511 : CBC_NEW byte_arg:16
513 : CBC_ASSIGN_BLOCK
514 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:11
517 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:213
520 : CBC_PUSH_NUMBER_POS_BYTE number:219
522 : CBC_PUSH_NUMBER_POS_BYTE number:55
524 : CBC_PUSH_NUMBER_POS_BYTE number:69
526 : CBC_PUSH_NUMBER_POS_BYTE number:222
528 : CBC_PUSH_NUMBER_POS_BYTE number:253
530 : CBC_PUSH_NUMBER_POS_BYTE number:142
532 : CBC_PUSH_NUMBER_POS_BYTE number:47
534 : CBC_PUSH_NUMBER_POS_BYTE number:3
536 : CBC_PUSH_NUMBER_POS_BYTE number:255
538 : CBC_PUSH_NUMBER_POS_BYTE number:106
540 : CBC_PUSH_NUMBER_POS_BYTE number:114
542 : CBC_PUSH_NUMBER_POS_BYTE number:109
544 : CBC_PUSH_NUMBER_POS_BYTE number:108
546 : CBC_PUSH_NUMBER_POS_BYTE number:91
548 : CBC_PUSH_NUMBER_POS_BYTE number:81
550 : CBC_NEW byte_arg:16
552 : CBC_ASSIGN_BLOCK
553 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:12
556 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:141
559 : CBC_PUSH_NUMBER_POS_BYTE number:27
561 : CBC_PUSH_NUMBER_POS_BYTE number:175
563 : CBC_PUSH_NUMBER_POS_BYTE number:146
565 : CBC_PUSH_NUMBER_POS_BYTE number:187
567 : CBC_PUSH_NUMBER_POS_BYTE number:221
569 : CBC_PUSH_NUMBER_POS_BYTE number:188
571 : CBC_PUSH_NUMBER_POS_BYTE number:127
573 : CBC_PUSH_NUMBER_POS_BYTE number:17
575 : CBC_PUSH_NUMBER_POS_BYTE number:217
577 : CBC_PUSH_NUMBER_POS_BYTE number:92
579 : CBC_PUSH_NUMBER_POS_BYTE number:65
581 : CBC_PUSH_NUMBER_POS_BYTE number:31
583 : CBC_PUSH_NUMBER_POS_BYTE number:16
585 : CBC_PUSH_NUMBER_POS_BYTE number:90
587 : CBC_PUSH_NUMBER_POS_BYTE number:216
589 : CBC_NEW byte_arg:16
591 : CBC_ASSIGN_BLOCK
592 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:13
595 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:10
598 : CBC_PUSH_NUMBER_POS_BYTE number:193
600 : CBC_PUSH_NUMBER_POS_BYTE number:49
602 : CBC_PUSH_NUMBER_POS_BYTE number:136
604 : CBC_PUSH_NUMBER_POS_BYTE number:165
606 : CBC_PUSH_NUMBER_POS_BYTE number:205
608 : CBC_PUSH_NUMBER_POS_BYTE number:123
610 : CBC_PUSH_NUMBER_POS_BYTE number:189
612 : CBC_PUSH_NUMBER_POS_BYTE number:45
614 : CBC_PUSH_NUMBER_POS_BYTE number:116
616 : CBC_PUSH_NUMBER_POS_BYTE number:208
618 : CBC_PUSH_NUMBER_POS_BYTE number:18
620 : CBC_PUSH_NUMBER_POS_BYTE number:184
622 : CBC_PUSH_NUMBER_POS_BYTE number:229
624 : CBC_PUSH_NUMBER_POS_BYTE number:180
626 : CBC_PUSH_NUMBER_POS_BYTE number:176
628 : CBC_NEW byte_arg:16
630 : CBC_ASSIGN_BLOCK
631 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:14
634 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:137
637 : CBC_PUSH_NUMBER_POS_BYTE number:105
639 : CBC_PUSH_NUMBER_POS_BYTE number:151
641 : CBC_PUSH_NUMBER_POS_BYTE number:74
643 : CBC_PUSH_NUMBER_POS_BYTE number:12
645 : CBC_PUSH_NUMBER_POS_BYTE number:150
647 : CBC_PUSH_NUMBER_POS_BYTE number:119
649 : CBC_PUSH_NUMBER_POS_BYTE number:126
651 : CBC_PUSH_NUMBER_POS_BYTE number:101
653 : CBC_PUSH_NUMBER_POS_BYTE number:185
655 : CBC_PUSH_NUMBER_POS_BYTE number:241
657 : CBC_PUSH_NUMBER_POS_BYTE number:9
659 : CBC_PUSH_NUMBER_POS_BYTE number:197
661 : CBC_PUSH_NUMBER_POS_BYTE number:110
663 : CBC_PUSH_NUMBER_POS_BYTE number:198
665 : CBC_PUSH_NUMBER_POS_BYTE number:132
667 : CBC_NEW byte_arg:16
669 : CBC_ASSIGN_BLOCK
670 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:5->string(SboxTable) number:15
673 : CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE ident:23->string(Array) number:24
676 : CBC_PUSH_NUMBER_POS_BYTE number:240
678 : CBC_PUSH_NUMBER_POS_BYTE number:125
680 : CBC_PUSH_NUMBER_POS_BYTE number:236
682 : CBC_PUSH_NUMBER_POS_BYTE number:58
684 : CBC_PUSH_NUMBER_POS_BYTE number:220
686 : CBC_PUSH_NUMBER_POS_BYTE number:77
688 : CBC_PUSH_NUMBER_POS_BYTE number:32
690 : CBC_PUSH_NUMBER_POS_BYTE number:121
692 : CBC_PUSH_NUMBER_POS_BYTE number:238
694 : CBC_PUSH_NUMBER_POS_BYTE number:95
696 : CBC_PUSH_NUMBER_POS_BYTE number:62
698 : CBC_PUSH_NUMBER_POS_BYTE number:215
700 : CBC_PUSH_NUMBER_POS_BYTE number:203
702 : CBC_PUSH_NUMBER_POS_BYTE number:57
704 : CBC_PUSH_NUMBER_POS_BYTE number:72
706 : CBC_NEW byte_arg:16
708 : CBC_ASSIGN_BLOCK
709 : CBC_PUSH_THREE_LITERALS ident:23->string(Array) const:30->number(462357) const:31->number(472066609)
713 : CBC_PUSH_THREE_LITERALS const:32->number(943670861) const:33->number(1415275113) const:34->number(1886879365)
717 : CBC_PUSH_THREE_LITERALS const:35->number(2358483617) const:36->number(2830087869) const:37->number(3301692121)
721 : CBC_PUSH_THREE_LITERALS const:38->number(3773296373) const:39->number(4228057617) const:40->number(404694573)
725 : CBC_PUSH_THREE_LITERALS const:41->number(876298825) const:42->number(1347903077) const:43->number(1819507329)
729 : CBC_PUSH_THREE_LITERALS const:44->number(2291111581) const:45->number(2762715833) const:46->number(3234320085)
733 : CBC_PUSH_THREE_LITERALS const:47->number(3705924337) const:48->number(4177462797) const:49->number(337322537)
737 : CBC_PUSH_THREE_LITERALS const:50->number(808926789) const:51->number(1280531041) const:52->number(1752135293)
741 : CBC_PUSH_THREE_LITERALS const:53->number(2223739545) const:54->number(2695343797) const:55->number(3166948049)
745 : CBC_PUSH_THREE_LITERALS const:56->number(3638552301) const:57->number(4110090761) const:58->number(269950501)
749 : CBC_PUSH_THREE_LITERALS const:59->number(741554753) const:60->number(1213159005) const:61->number(1684763257)
753 : CBC_NEW byte_arg:32
755 : CBC_ASSIGN_SET_IDENT ident:6->string(CK)
757 : CBC_PUSH_THREE_LITERALS ident:23->string(Array) const:62->number(2746333894) const:63->number(1453994832)
761 : CBC_PUSH_TWO_LITERALS const:64->number(1736282519) const:65->number(2993693404)
764 : CBC_NEW byte_arg:4
766 : CBC_ASSIGN_SET_IDENT ident:7->string(FK)
768 : CBC_PUSH_LITERAL const:66->string(ctf{this_is_an_example})
770 : CBC_ASSIGN_SET_IDENT ident:18->string(input)
772 : CBC_PUSH_NUMBER_0
773 : CBC_ASSIGN_SET_IDENT ident:19->string(num)
775 : CBC_PUSH_LITERAL ident:23->string(Array)
777 : CBC_NEW0
778 : CBC_ASSIGN_SET_IDENT ident:20->string(message)
780 : CBC_PUSH_NUMBER_0
781 : CBC_MOV_IDENT reg:1
783 : CBC_JUMP_FORWARD offset:32(->815)
785 : CBC_MULTIPLY_TWO_LITERALS ident:19->string(num) const:67->number(256)
788 : CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE ident:18->string(input) const:68->string(charCodeAt)
791 : CBC_PUSH_LITERAL reg:1
793 : CBC_CALL1_PROP_PUSH_RESULT
794 : CBC_ADD
795 : CBC_ASSIGN_SET_IDENT_BLOCK ident:19->string(num)
797 : CBC_MODULO_TWO_LITERALS reg:1 const:69->number(4)
800 : CBC_EQUAL_RIGHT_LITERAL const:70->number(3)
802 : CBC_BRANCH_IF_FALSE_FORWARD offset:11(->813)
804 : CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE ident:20->string(message) const:71->string(push)
807 : CBC_PUSH_LITERAL ident:19->string(num)
809 : CBC_CALL1_PROP_BLOCK
810 : CBC_PUSH_NUMBER_0
811 : CBC_ASSIGN_SET_IDENT_BLOCK ident:19->string(num)
813 : CBC_PRE_INCR_IDENT reg:1
815 : CBC_PUSH_TWO_LITERALS reg:1 ident:18->string(input)
818 : CBC_PUSH_PROP_LITERAL const:72->string(length)
820 : CBC_LESS
821 : CBC_BRANCH_IF_TRUE_BACKWARD offset:36(->785)
823 : CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE ident:24->string(Math) const:73->string(ceil)
826 : CBC_PUSH_PROP_LITERAL_LITERAL ident:20->string(message) const:72->string(length)
829 : CBC_DIVIDE_RIGHT_LITERAL const:69->number(4)
831 : CBC_CALL1_PROP_PUSH_RESULT
832 : CBC_ASSIGN_SET_IDENT ident:21->string(count)
834 : CBC_MULTIPLY_TWO_LITERALS ident:21->string(count) const:69->number(4)
837 : CBC_ASSIGN_SET_IDENT ident:22->string(pad_len)
839 : CBC_JUMP_FORWARD offset:7(->846)
841 : CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE ident:20->string(message) const:71->string(push)
844 : CBC_PUSH_NUMBER_0
845 : CBC_CALL1_PROP_BLOCK
846 : CBC_PUSH_PROP_LITERAL_LITERAL ident:20->string(message) const:72->string(length)
849 : CBC_LESS_RIGHT_LITERAL ident:22->string(pad_len)
851 : CBC_BRANCH_IF_TRUE_BACKWARD offset:10(->841)
853 : CBC_PUSH_THREE_LITERALS ident:23->string(Array) const:74->number(19088743) const:75->number(2309737967)
857 : CBC_PUSH_TWO_LITERALS const:76->number(4275878552) const:77->number(1985229328)
860 : CBC_NEW byte_arg:4
862 : CBC_ASSIGN_SET_IDENT_BLOCK ident:25->string(key)
864 : CBC_PUSH_THREE_LITERALS ident:23->string(Array) const:78->number(1605062385) const:79->number(-642825121)
868 : CBC_PUSH_THREE_LITERALS const:80->number(2061445208) const:81->number(1405610911) const:82->number(1713399267)
872 : CBC_PUSH_THREE_LITERALS const:83->number(1396669315) const:84->number(1081797168) const:85->number(605181189)
876 : CBC_PUSH_THREE_LITERALS const:86->number(1824766525) const:87->number(1196148725) const:88->number(763423307)
880 : CBC_PUSH_LITERAL const:89->number(1125925868)
882 : CBC_NEW byte_arg:12
884 : CBC_ASSIGN_SET_IDENT_BLOCK ident:26->string(ans)
886 : CBC_PUSH_LITERAL ident:23->string(Array)
888 : CBC_NEW0
889 : CBC_ASSIGN_SET_IDENT_BLOCK ident:27->string(message_c)
891 : CBC_PUSH_NUMBER_0
892 : CBC_MOV_IDENT reg:1
894 : CBC_JUMP_FORWARD offset:47(->941)
896 : CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE ident:20->string(message) const:90->str 900 : CBC_PUSH_NUMBER_POS_BYTE number:4
902 : CBC_CALL2_PROP_PUSH_RESULT
903 : CBC_MOV_IDENT reg:2
905 : CBC_PUSH_THREE_LITERALS ident:15->string(encrypt) reg:2 ident:25->string(key)
909 : CBC_CALL2_PUSH_RESULT
910 : CBC_MOV_IDENT reg:3
912 : CBC_PUSH_NUMBER_0
913 : CBC_MOV_IDENT reg:4
915 : CBC_JUMP_FORWARD offset:16(->931)
917 : CBC_PUSH_PROP_LITERAL_LITERAL_REFERENCE ident:27->string(message_c) const:71->string(push)
920 : CBC_PUSH_THREE_LITERALS ident:28->string(parseInt) reg:3 reg:4
924 : CBC_PUSH_PROP
925 : CBC_PUSH_NUMBER_POS_BYTE number:16
927 : CBC_CALL2_PUSH_RESULT
928 : CBC_CALL1_PROP_BLOCK
929 : CBC_PRE_INCR_IDENT reg:4
931 : CBC_PUSH_TWO_LITERALS reg:4 reg:3
934 : CBC_PUSH_PROP_LITERAL const:72->string(length)
936 : CBC_LESS
937 : CBC_BRANCH_IF_TRUE_BACKWARD offset:20(->917)
939 : CBC_PRE_INCR_IDENT reg:1
941 : CBC_LESS_TWO_LITERALS reg:1 ident:21->string(count)
944 : CBC_BRANCH_IF_TRUE_BACKWARD offset:48(->896)
946 : CBC_PUSH_LITERAL ident:27->string(message_c)
948 : CBC_BRANCH_IF_FALSE_FORWARD offset:10(->958)
950 : CBC_PUSH_THREE_LITERALS ident:29->string(print) ident:17->string(compare_array) ident:27->string(message_c)
954 : CBC_PUSH_LITERAL ident:26->string(ans)
956 : CBC_CALL2_PUSH_RESULT
957 : CBC_CALL1_BLOCK
958 : CBC_RETURN_FUNCTION_END

找在线解密⽹址可以直接求解

image-20221101104654095

后⾯不可⻅字符换成 }, 即为flag: ctf{w3_f0und_1t_112ug31vjhe121f21fas}

machine

​ 隔了两周终于将这道题整明白了,完完整整的将这个题做了一遍,还是很折磨。首先,拉到ida里看是一个golang逆向,这个go逆向,在出题人编译的时候加上了-s -w,使得这个题去了符号,甚至还需要进行一定的操作才能看到正常的模样。

​ 首先要知道去过符号的go是怎么逆向的,建议编写一个go不去符号的hello world,从start开始一直找到main_main函数,下面简单介绍一下这种go是如何找到main_main的。

第一步找到start函数

1
2
3
4
5
// attributes: thunk
void __golang __noreturn start(char a1)
{
start_0(a1);
}

进入start_0

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
void __golang __noreturn start_0(char a1)
{
__int64 v11; // rax
char v12[65432]; // [rsp+0h] [rbp-FFC0h] BYREF
int v13; // [rsp+FF98h] [rbp-28h] BYREF
__int64 v14; // [rsp+FFB0h] [rbp-10h]
char *v15; // [rsp+FFB8h] [rbp-8h]
__int64 retaddr; // [rsp+FFC0h] [rbp+0h]

v14 = retaddr;
v15 = &a1;
qword_5A5860[2] = v12;
qword_5A5860[3] = v12;
qword_5A5860[0] = v12;
qword_5A5860[1] = &v13;
_RAX = 0LL;
__asm { cpuid }
if ( (_DWORD)_RAX )
{
if ( (_DWORD)_RBX == 1970169159 && (_DWORD)_RDX == 1231384169 && (_DWORD)_RCX == 1818588270 )
byte_5F9C6B = 1;
_RAX = 1LL;
__asm { cpuid }
dword_5F9CCC = _RAX;
}
if ( qword_5A47C0 )
{
qword_5A47C0();
v11 = qword_5A5860[0] + 5024LL;
qword_5A5860[2] = qword_5A5860[0] + 5024LL;
qword_5A5860[3] = v11;
}
sub_45E9A0();
*(_QWORD *)NtCurrentTeb()->NtTib.ArbitraryUserPointer = 291LL;
if ( qword_5A5C18 != 291 )
sub_45CB60();
*(_QWORD *)NtCurrentTeb()->NtTib.ArbitraryUserPointer = qword_5A5860;
qword_5A5BC0[0] = qword_5A5860;
qword_5A5860[6] = qword_5A5BC0;
sub_45F0A0();
STACK[0x1FF40] = runtime_newproc_abi0(v14, (__int64)v15);
sub_45EDC0();
sub_45EFA0();
STACK[0x1FF28] = runtime_badmcall_abi0_0((__int64)&off_510798);//该处off_510798
sub_45A900();
sub_45CB60();
}

找到倒数第三行处的off_510798,双击进入

image-20221116210254376

进入qword_435BA0

image-20221116210321534

发现一大堆没有反编译的数据,我们选中先按c,再按p,创建函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
LABEL_13:
sub_442520(v4);
byte_5F9F60 = 0;
v10 = sub_404F60(v6);
v11 = 0;
runtime_unlockOSThread();
if ( !byte_5F9C6C && !byte_5F9C6E )
{
((void (*)(void))&qword_4C5508[267])();
if ( !dword_5F9CD0 || !dword_5F9CD0 )
{
if ( dword_5F9CC8 )
runtime_gopark(v7, v10);
runtime_exit(v7);
while ( 1 )
MEMORY[0] = 0;
}
v13 = 0LL;
runtime_mcall(v7);
}
v12 = 0;
(*v16)();
}

从后往前看找到((void (*)(void))&qword_4C5508[267])()地方,进入发现也没有反编译,老样子点c,再点p。得出来的就是我们要找的main_main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
__int64 __usercall sub_4C5D60@<rax>()
{
__int64 v0; // rdi
__int64 v1; // r14
__int64 result; // rax
unsigned __int64 v3; // rcx
char v4; // [rsp+90h] [rbp-1B8h] BYREF

if ( (unsigned __int64)&v4 <= *(_QWORD *)(v1 + 16) )
sub_45AB00();
result = ((__int64 (*)(void))&qword_49AEB8[277])();
if ( !v0 )
{
if ( v3 >= 0x100 )
sub_45D2A0();
sub_45D260();
}
return result;
}

找到main_main后,发现还有没解析出来的函数,然后又看到主函数的逻辑仿佛像是一个ollvm整过的混淆

image-20221116211529328

在我之前的认知中ollvm的题无非是用脚本或者插件去混淆,或者用unicorn找路线,又或者是硬调。这个题在main_main处还不能f5,这个原因是有一条指令干扰了反汇编,经过尝试发现是下面这个汇编指令干扰了反汇编

image-20221117084151775

将其nop掉就可以f5了,直接得到了经典的虚拟机状态

我们直接看函数,先看前271行

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
if ( (unsigned __int64)&v128 <= *(_QWORD *)(v1 + 16) )
sub_5DAB00();
sub_61B760();
if ( !v0 )
{
if ( v4 < 0x100 )
sub_5DD260();
v143 = v4 - 256;
v157 = v3 + (((__int64)(256 - v4) >> 63) & 0x100);
v142 = -248LL;
retaddr = sub_645BC0();
if ( v5 )
{
LABEL_91:
sub_620E40(v131, v132, v133, v134, v135, v136, v137);
}
else
{
v6 = v142;
retaddr = sub_645A40();
if ( v7 )
{
v142 = v6;
v156 = v7;
opcode = v2;
v129 = &v130;
v8 = ((__int64 (*)(void))loc_5DD486)();
*((_QWORD *)&opcode + 1) = &unk_779E78;
arr_v163 = &unk_779E78;
for ( i = 0LL; v6 > i; i += 8LL )
{
v10 = i + 7;
v11 = 0LL;
while ( v10 >= i )
{
if ( v6 <= (unsigned __int64)v10 )
sub_5DD1E0(v131, v132);
v11 = *(unsigned __int8 *)(v8 + v10--) + (v11 << 8);
}
v12 = v175;
v13 = *((_QWORD *)&opcode + 1);
if ( v176 < v175 + 1 )
{
v141 = i;
v144 = v11;
v14 = *((_QWORD *)&opcode + 1);
runtime_growslice(v131);
v176 = v15;
*((_QWORD *)&opcode + 1) = v16;
i = v141;
v11 = v144;
v12 = v14;
v13 = v16;
v8 = v156;
v6 = v142;
}
v175 = v12 + 1;
*(_QWORD *)(v13 + 8 * v12) = v11;
}

函数主要逻辑是先对code.bin的数据进行加载,然后将数据进行hash和rsa的值进行验证,可以不用管,最后将数据进行一个解压生成opcode,我们直接动态调试,在下面的地方下断点,然后跟踪到v18的“生产地”找到opcode,然后提取出来

image-20221117085530441

image-20221117085708154

用下面的脚本提取opcode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import struct 

def read_bin(file_name):
"""
function: read a bin file, return the tuple of the content in file
"""
with open(file_name, "rb") as f:
f_content = f.read()
content = struct.unpack("B" * len(f_content), f_content)
f.close()
return content
data = read_bin('./opcode')
for i in range(0,len(data),8):
print(hex(data[i+7])+hex(data[i+6])[2:]+hex(data[i+5])[2:]+hex(data[i+4])[2:]+hex(data[i+3])[2:]+hex(data[i+2])[2:]+hex(data[i+1])[2:]+hex(data[i])[2:],end=",")

接下来就是进行一个分析,我们就简单的举两个例子来分析。

比如当op == 0x8 时:

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
else if ( v18 == 8 )                // op == 0x8
{
v76 = lenth;
v77 = lenth - 1;
if ( lenth <= lenth - 1 )//不用管if这个判断
sub_5DD1E0(v131, v132);
v78 = arr[--lenth];
v79 = v76 - 2;
if ( v76 - 2 >= v77 )//永远不会成立
sub_5DD1E0(v131, v132);
v80 = arr[v76 - 2];
lenth = v79;
v81 = -(__int64)(v80 < 0x40) & (v78 << v80);
v82 = arr;
if ( nowplace < v77 )//比较毫无意义,就是混淆
{
v147 = v81;
runtime_growslice(v131);
nowplace = v83;
arr = v84;
v81 = v147;
v79 = (unsigned __int64)v82;
v82 = v84;
}
lenth = v79 + 1;
v82[v79] = v81;//v82就是arr,该行就是表示arr[v79] = -(__int64)(v80 < 0x40) & (v78 << v80)
}

lenth是步长,是决定opcode位置的标识,arr和lenth是全局变量,要进行保留,经过调试发现每一个运算都会使用一个opcode,所以在结束的时候要进行op++。

这是opcode == 0x0的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
else                                  // op == 0x0
{
if ( v175 <= v19 )
sub_5DD1E0(v131, v132);
v20 = *(_QWORD *)(*((_QWORD *)&opcode + 1) + 8 * pc + 8);// 取下一个指令
*(_QWORD *)&opcode = pc + 2; // 更新opcode位置
v21 = lenth;
v22 = arr;
if ( nowplace < lenth + 1 )
{
v139 = v20;
runtime_growslice(v131);
nowplace = v23;
arr = v24;
v20 = v139;
v21 = (unsigned __int64)v22;
v22 = v24;
}
lenth = v21 + 1;
v22[v21] = v20;

会使用*(_QWORD *)&opcode = pc + 2; 进行一个op += 2,v20 = *(_QWORD )(((_QWORD *)&opcode + 1) + 8 * pc + 8);是获取opcode值,也就是说这个相当于是一个赋值操作。

我们将opcode编写成c语言,然后通过优化进行一个恢复加密,再通过angr进行解题

给出脚本:

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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#省略opcode
opcode = []

file = open(r".\opcode","w")
def p(pt):
global file
file.write(pt+";"+"\n")


arr = [0] * 10000
lenth = 0
arr_data = [0] * 10000
scan_len = 0
num = 0
p = 0

while p < len(opode):
op = opode[p]
if op == 0x0:
v11 = lenth
lenth = v11 + 1

arr[v11] = opode[p + 1]
p(f"arr[{v11}] = {arr[v11]}")
p += 2

elif op == 0x1:
v17 = lenth
v18 = lenth + 1

v15 = opode[p + 1]
v16 = arr_data[v15]
lenth = v17 + 1
arr[v17] = v16
p(f"arr[{v17}] = arr_data[{v15}]")
p += 2

elif op == 0x2:
v21 = opode[p + 1]
a_len = lenth - 1
v22 = arr[lenth - 1]
lenth -= 1
arr_data[v21] = v22
p(f"arr_data[{v21}] = arr[{a_len}]")
p += 2

elif op == 0x3:
v23 = lenth
v24 = lenth - 1
lenth -= 1
a_len = lenth
v25 = arr[lenth]
v26 = v23 - 2
v27 = arr[v23 - 2] + v25
lenth = v32 - 2
lenth = v26 + 1
arr[v26] = v27
p(f"arr[{v26}] = arr[{v23 - 2}] + arr[{a_len}]")
p += 1

elif op == 0x4:
v31 = lenth
v32 = lenth - 1
a_len = lenth - 1
v33 = arr[lenth - 1]
lenth -= 1
v34 = v31 - 2
v35 = v33 - arr[v31 - 2]
lenth = v31 - 2
lenth = v34 + 1
arr[v34] = v35
p(f"arr[{v34}] = arr[{a_len}] - arr[{v31 - 2}]")
p += 1

elif op == 0x5:
v39 = lenth
v40 = lenth - 1
a_len = lenth - 1
v41 = arr[lenth - 1]
lenth -= 1
v42 = v39 - 2
v43 = arr[v39 - 2]
lenth = v39 - 2
v44 = v43 * v41
lenth = v42 + 1
arr[v42] = v44
p(f"arr[{v42}] = arr[{v39 - 2}] * arr[{a_len}]")
p += 1

elif op == 0x6:
v48 = lenth
v49 = lenth - 1
a_len = lenth - 1
v50 = arr[lenth - 1]
lenth -= 1
v51 = v48 - 2
v52 = arr[v48 - 2]
lenth = v48 - 2
v53 = v49
v54 = v50 // v52
lenth = v51 + 1
arr[v51] = v54
p(f"arr[{v51}] = arr[{a_len}] // arr[{v48 - 2}]")
assert 0
p += 1

elif op == 0x7:
v68 = lenth
v69 = lenth - 1
a_len = lenth - 1
v70 = arr[lenth - 1]
lenth -= 1
v71 = v68 - 2
v72 = arr[v68 - 2] ^ v70
lenth = v68 - 2
lenth = v71 + 1
arr[v71] = v72
p(f"arr[{v71}] = arr[{v68 - 2}] ^ arr[{a_len}]")
p += 1

elif op == 0x8:
v76 = lenth
v77 = lenth - 1
lenth -= 1
a_len = lenth
v78 = arr[lenth]
v79 = v76 - 2
v80 = arr[v76 - 2]
lenth = v79
v81 = -(v80 < 0x40) & (v78 << v80)
lenth = v79 + 1
arr[v79] = v81
p(f"arr[{v79}] = -(arr[{v76 - 2}] < 0x40) & (arr[{a_len}] << arr[{v76 - 2}])")
p += 1

elif op == 0x9:
v85 = lenth
v86 = lenth - 1
a_len = lenth - 1
v87 = arr[lenth - 1]
lenth -= 1
v88 = v85 - 2
v89 = arr[v85 - 2]
lenth = v88
v90 = -(v89 < 0x40) & (v87 >> v89)
lenth = v88 + 1
arr[v88] = v90
p(f"arr[{v88}] = -(arr[{v85 - 2}] < 0x40) & (arr[{a_len}] >> arr[{v85 - 2}])")
p += 1

elif op == 0xa:
v94 = lenth
v95 = lenth - 1
a_len = lenth - 1
v96 = arr[lenth - 1]
lenth -= 1
lenth = v95 + 1
arr[v95] = ~v96
p(f"arr[{v95}] = ~arr[{a_len}]")
p += 1

elif op == 0xb:
v101 = lenth
v102 = lenth - 1
a_len = lenth - 1
v103 = arr[lenth - 1]
lenth -= 1
v104 = v101 - 2
v105 = arr[v101 - 2] & v103
lenth = v101 - 2
lenth = v104 + 1
arr[v104] = v105
p(f"arr[{v104}] = arr[{v101 - 2}] & arr[{a_len}]")

p += 1

elif op == 0xc:
if flag[scan_len] == "\n":
arr[2] = ord(flag[scan_len])
scan_len += 1
p(f"arr[2] = 0")
p(f"scanf(\"%c\",&arr[2])")
else:
arr[0] = ord(flag[scan_len])
scan_len += 1
p(f"arr[0] = 0")
p(f"scanf(\"%c\",&arr[0])")
num += 1
lenth += 1
p += 1

elif op == 0xd:
try:
p(f"// {chr(opode[p+1])}")
except:
print(hex(p))
p += 2

elif op == 0xe:
lenth -= 1
call = f'''if (arr[{lenth}])\n\texit(0)'''
p(call)
p +=1

elif op == 0xcc:
print("here op == 0xcc")
assert 0
else:
assert 0

file.close()

运行后得到了一个将近两万行的代码,稍微修一下然后用gcc生成文件

image-20221117092240038

1
gcc opcode.c -g -O3 -o opcode

得到的文件如下:

image-20221117092604330

只剩不到300行,直接用z3或者angr进行解决即可,在此采用angr解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import angr
import sys

def main(argv):
path_to_binary = './opcode'
project = angr.Project(path_to_binary)

initial_state = project.factory.entry_state()

simulation = project.factory.simgr(initial_state)
print_good_address = 0x01B66
fail_address = 0x015AD
simulation.explore(find=print_good_address,avoid=fail_address)
if simulation.found:
solution_state = simulation.found[0]
print(solution_state.posix.dumps(sys.stdin.fileno()))

else:
raise Exception('Nooooooooooo')

if __name__ == '__main__':
main(sys.argv)

找到路径,得到flag:734f1698a5775ec26cd2e11ed4791e77