[祥云杯 2022] Reverse部分赛题复现
女娲补天:指星期天打了一天的V3,再不学re👶要被开了(确信
rocket
官方给了个Hint: rocket题目环境建议使用Ubuntu22.04,racket版本8.2
先配环境,直接按照hint去github上找.sh脚本安装的话运行程序会一直报permission denied的错而且解决不了(如果有大爹解决了请务必告诉我)。
只能就着一部分动调+静态嗯逆了。main函数里可以看见许多判断路径的操作,在最开始疯狂报错的动调中也可以发现他应该是在找文件路径,并且尝试附加参数什么的。并且就报错信息而言可以怀疑是racket语言编写的程序自带的一个函数。报错差不多就下面这样
并且,main函数里的动调可以发现变量file来自调用函数sub_5592080D70F0(),里面是/proc/self/exe,这是readlink()操作,代表从当前的程序读取。
随后用v17打开file,并不断通过ptrace操作进行跟踪。
通过代码分析可以发现其目的是执行255行的if ( !strcmp((const char *)ptrc + (unsigned int)v103[0], ".rackprog") )
,
ptrc是一个指针,v103是通过sys_read读的东西,根据前面file来自我们自己的程序,那么.rackprog也在我们程序里面吧大概。
尝试010 Editor搜一下,发现有两处
第一处感觉是报错信息啥的,但第二处很显然是个代码段的名字。找一下.rackprog代码段,会发现里面有一个巨大的data数组
把data给dump下来,尝试搜了下关键字rocket,然后会发现一堆诸如hex->string的明文操作,然后还有一步特别像运算的^([[:xdigit:]]{2})*$
然后大眼瞪了一万年只发现了把字符串转换成整型,以及把数据转换成hex数据再转换成字符串的操作,十分自闭。
随后直接去GitHub配了最新版的racket重新动调,然后execv()里有一步syscall,附加调试报错
然后生无可恋,自暴自弃想了下会不会就只有^([[:xdigit:]]{2})*$
一步操作,猜测这玩意是做了一次乘2或者平方或者立方,用output的数据一个一个试了一下,然后发现
import gmpy2
import binascii
enc = 7212272804013543391008421832457418223544765489764042171135982569211377620290274828526744558976950004052088838419495093523281490171119109149692343753662521483209758621522737222024221994157092624427343057143179489608942837157528031299236230089474932932551406181
# enf = gmpy2.iroot(enc, 2)[0].digits()
enf = gmpy2.iroot(enc, 3)[0].digits()
print(enf)
# flag = 193207530030250486323082807418528242300453594901698934812368796575822264198418283118461
# print(hex(flag))
enf = "6374667b746831735f69735f7265346c6c795f626561757431666c795f72316768743f7d"
hex = enf.encode('utf-8')
str = binascii.unhexlify(hex)
flag = str.decode('utf-8')
print(flag)
十分懵逼地得到flag:ctf{th1s_is_re4lly_beaut1fly_r1ght?}
(真的是太美丽了
engtom
评价是纯纯的misc题
.snapshot文件,文件头是JRRYF,但是搜不出什么东西。
尝试010看一下,发现了一些奇怪的方法
看起来就是做了个cbc模式的sm4加密,但是找不到任何数据。
尝试用了下ELF.bat,然后发现文件头其实是JRRY
然后在github上就搜出来一个issue
也是.snapshot,看来应该就是这个jerryscript了吧
Readme里面有这句话
Snapshot support for precompiling JavaScript source code to byte code
然后就对着去查git上的各种文档搜关键字snapshot和bytecode,看到了这两句:--snapshot-exec=ON/OFF
,--show-opcodes=ON/OFF
,编译的时候附带一下,然后运行jerry的时候也附带一下这俩指令
注意一下,这语言很傻逼的一点是运行的时候附带参数是--exec-snapshot
不是他官方文档里面写的--snapshot-exec
😅
然后就能dump出byte code
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->string(splice)
899 : CBC_PUSH_NUMBER_0
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
然后就是找关键字环节
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)
key和ans都找到了,然后确实只有sm4加密,直接试一下吧
有负数就给他转成unsigned数据再试试
key = [19088743, 2309737967, 4275878552, 1985229328]
for i in key:
print(hex(i)[2:], end="")
print()
data = [1605062385, -642825121, 2061445208, 1405610911, 1713399267, 1396669315, 1081797168, 605181189, 1824766525, 1196148725, 763423307, 1125925868]
for i in data:
i = (i & 0xFFFFFFFF)
print(hex(i)[2:], end="")
然后拿到flag:ctf{w3_f0und_1t_112ug31vjhe121f21fas}
前面还以为后半段搞成乱码了,什么杀软flag。
machine
golang虚拟机,先导入修一下符号表,然后来到主函数。
result是对code.bin的解压,可以发现后续会从result中提取opcode进行虚拟机操作。动调,进result按d,array导出就行。
对后面虚拟机的操作分析一下,可以发现是个栈机,并且opcode为204的时候根本没有执行,所以op = 204下面那一大坨都不用分析。
简单翻译一下,注意数据类型是uLL,所以要&0xFFFFFFFFFFFFFFFF
#include <stdio.h>
#define maxn 233333
long long c;
//long long opcodes[maxn], stack[maxn], tempdir[9];
long long stack[maxn], tempdir[9];
unsigned long long opcodes[maxn] = {太长了自己dump吧}
int cnt, cnt_opcodes = 28894, top;
long long op, op1, op2;
int main()
{
while (cnt_opcodes >= -1)
{
--cnt_opcodes;
op = opcodes[cnt];
// printf("DEBUG1: %lld\n", op);
switch (op)
{
case 0:
stack[top++] = opcodes[cnt + 1];
cnt += 2;
break;
case 1:
stack[top++] = tempdir[opcodes[cnt + 1]];
cnt += 2;
break;
case 2:
tempdir[opcodes[cnt + 1]] = stack[top - 1];
--top;
cnt += 2;
break;
case 3:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 + op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 4:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 - op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 5:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 * op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 6:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 / op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 7:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 ^ op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 8:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
if (op1 >= 64) stack[top++] = 0;
else stack[top++] = (op1 << op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 9:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
if (op1 >= 64) stack[top++] = 0;
else stack[top++] = (op1 >> op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 10:
op = stack[top - 1];
--top;
stack[top++] = (~op) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 11:
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 & op2);
cnt += 1;
break;
case 12:
scanf("%lld", &c);
// printf("DEBUG2: %c\n", c);
stack[top++] = c;
cnt += 1;
break;
case 13:
printf("%c", (char)opcodes[cnt + 1]);
cnt += 2;
break;
case 14:
op = stack[top - 1];
--top;
if (op)
{
printf("Fail\n");
return 0;
}
cnt += 1;
break;
}
}
return 0;
}
一个很实际的想法是,把这个流程翻译为c的代码,编译后用angr梭了。
#include <stdio.h>
#define maxn 30005
long long c;
//long long opcodes[maxn], stack[maxn], tempdir[9];
unsigned long long stack[maxn], tempdir[9];
unsigned long long opcodes[maxn] = {太长了自己dump吧};
int cnt, cnt_opcodes = 28894, top;
long long op, op1, op2;
int main()
{
freopen("my_vm", "w", stdout);
while (cnt_opcodes >= -1)
{
--cnt_opcodes;
op = opcodes[cnt];
switch (op)
{
case 0:
printf("stack[top++] = %llu;\n", opcodes[cnt + 1]);
stack[top++] = opcodes[cnt + 1];
cnt += 2;
break;
case 1:
printf("stack[top++] = rg[%u];\n", opcodes[cnt + 1]);
stack[top++] = tempdir[opcodes[cnt + 1]];
cnt += 2;
break;
case 2:
printf("rg[%u] = stack[top - 1];\n--top;\n", opcodes[cnt + 1]);
tempdir[opcodes[cnt + 1]] = stack[top - 1];
--top;
cnt += 2;
break;
case 3:
printf("stack[top - 2] = stack[top - 1] + stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 + op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 4:
printf("stack[top - 2] = stack[top - 1] - stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 - op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 5:
printf("stack[top - 2] = stack[top - 1] * stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 * op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 6:
printf("stack[top - 2] = stack[top - 1] / stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 / op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 7:
printf("stack[top - 2] = stack[top - 1] ^ stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 ^ op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 8:
printf("stack[top - 2] = stack[top - 1] << stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
if (op1 >= 64) stack[top++] = 0;
else stack[top++] = (op1 << op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 9:
printf("stack[top - 2] = stack[top - 1] >> stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
if (op1 >= 64) stack[top++] = 0;
else stack[top++] = (op1 >> op2) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 10:
printf("stack[top - 1] = ~ stack[top - 1];\n");
op = stack[top - 1];
--top;
stack[top++] = (~op) & (0xFFFFFFFFFFFFFFFF);
cnt += 1;
break;
case 11:
printf("stack[top - 2] = stack[top - 1] & stack[top - 2];\n--top;\n");
op1 = stack[top - 1];
op2 = stack[top - 2];
top -= 2;
stack[top++] = (op1 & op2);
cnt += 1;
break;
case 12:
printf("stack[top++] = getchar();\n");
// scanf("%lld", &c);
stack[top++] = c;
cnt += 1;
break;
case 13:
printf("putchar(\'%c\');\n", opcodes[cnt + 1]);
// printf("%c", (char)opcodes[cnt + 1]);
cnt += 2;
break;
case 14:
printf("if(stack[--top] != 0) {printf(\"Fail\\n\"); return 0;}\n");
op = stack[top - 1];
--top;
// if (op)
// {
// printf("Fail\n");
// return 0;
// }
cnt += 1;
break;
}
}
return 0;
}
输出的代码编译然后angr直接explore就行
import angr
def aim_out(state):
return b'Right, your flag is flag{input}' in state.posix.dumps(1)
proj = angr.Project('./my_vm')
state = proj.factory.entry_state()
simgr = proj.factory.simgr(state)
simgr.explore(aim = aim_out)
if simgr.found:
sol_state = simgr.found[0]
print(sol_state.posix.dumps(0))
else:
print('Failed.')
最后得到flag是734f1698a5775ec26cd2e11ed4791e77\r\n
,就是前32位