祥云杯 这次比赛我觉得打的很有意义,有很多值得学习的地方,虽然在最后一分钟被py嘛了,但是还是可以的。
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_bytesimport gmpy2print (gmpy2.iroot(72122728040135433910084218324574182235447654897640421711359825692113776202902748285267445589769500040520888384194950935232 m = 193207530030250486323082807418528242300453594901698934812368796575822264198418283118461 print (long_to_bytes(m).decode())
engtom
通过strings查询字符串可以看出是JS相关的程序,搜索Js引擎和⽂件头可以认出是JerryScript引擎的快照。
启⽤—show-opcodes和—snapshot-exec编译后,执⾏jerry
1 ./jerry --show-opcodes --exec-snapshot /m nt/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
找在线解密⽹址可以直接求解
后⾯不可⻅字符换成 }, 即为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 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; char v12[65432 ]; int v13; __int64 v14; char *v15; __int64 retaddr; 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); sub_45A900(); sub_45CB60(); }
找到倒数第三行处的off_510798,双击进入
进入qword_435BA0
发现一大堆没有反编译的数据,我们选中先按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; __int64 v1; __int64 result; unsigned __int64 v3; char v4; 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整过的混淆
在我之前的认知中ollvm的题无非是用脚本或者插件去混淆,或者用unicorn找路线,又或者是硬调。这个题在main_main处还不能f5,这个原因是有一条指令干扰了反汇编,经过尝试发现是下面这个汇编指令干扰了反汇编
将其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,然后提取出来
用下面的脚本提取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 { if ( v175 <= v19 ) sub_5DD1E0(v131, v132); v20 = *(_QWORD *)(*((_QWORD *)&opcode + 1 ) + 8 * pc + 8 ); *(_QWORD *)&opcode = pc + 2 ; 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 = [] 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生成文件
1 gcc opcode.c -g -O3 -o opcode
得到的文件如下:
只剩不到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 angrimport sysdef 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