继续填坑ing,是强网杯的一道Misc题ExtremelySlow,跟npy合力做的一道杂项题(双双转行Misc手就离谱x),当时捞了个七血,可惜这个题最后被打穿了(
赛中的大概思路就是把传的一个一个字节按顺序提取出来并复原出传输的文件,因为两个工具都不兼容python3.10所以直接手逆pyc+手抠隐写字节码,最后拿到flag。
这里还进行了一点赛后改进,包括魔改stegosaurus兼容到3.10。
【Misc】ExtremelySlow 赛中思路 流量包中提取复原出文件 查看流量包,注意到HTTP/1.1 206 Partial Content的包都是对get包的回答,并且都是/latest文件的一个字节。
(一字节一字节地传,难怪叫ExtremelySlow= =)
双击HTTP/1.1 206 Partial Content包查看(以No.10这个包为例):
可以知道这个包返回的是文件的第0字节0x6f,其余包同理。
所以选中所有这样的回复包,然后导出为纯文本,保存在out.txt中。
然后写脚本从txt里提取这些字节并按顺序还原出源文件(直接把npy脚本搬过来了):
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 import  jsonimport  rewith  open ('./out.txt' , 'r' ) as  f:    data = f.read() data = data.split('\n' ) r1 = [] r2 = [] for  d in  data:    if  'content-range:'  in  d:         r1.append(d)     if  '0000  '  in  d and  not  '0.290470000'  in  d:         r2.append(d) data = [] for  i in  range (len (r1)):    data.append((re.findall(r"\d+\.?\d*" ,r1[i])[0 ], '0x' +r2[i][6 :8 ])) data = sorted (data, key=lambda  t: int (t[0 ])) result = [int (d[1 ],16 ) for  d in  data] with  open ('./res' , 'wb' ) as  f:    f.write(bytes (result)) 
pyc逆向 拿到这个文件,用010打开看到经典第二行E3000000…, 逆向手dna狂喜, 直接猜测是pyc文件,加上pyc后缀。
用uncompyle6和pycdc反编译,但是都由于魔数不对报错,于是把第一个字节改成0x55,假装这是3.8的pyc,反编译依然失败,于是只能用pycdas(zrax/pycdc: C++ python bytecode disassembler and decompiler )反汇编出字节码。
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 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 res.pyc (Python 3.8 ) [Code]     File Name: main.py     Object Name: <module>     Arg Count: 0      Pos Only Arg Count: 0      KW Only Arg Count: 0      Locals: 0      Stack Size: 7      Flags: 0x00000040  (CO_NOFREE)     [Names]         'sys'          'hashlib'          'sha256'          'KSA'          'PRGA'          'RC4'          'xor'          '__name__'          'w'          'e'          'b'          's'          't'          'm'          'n'          'list'          'map'          'sorted'          'items'          'stream'          'print'          'decode'          'stdin'          'buffer'          'read'          'p'          'c'          'digest'      [Var Names]     [Free Vars]     [Cell Vars]     [Constants]         0          None          (             'sha256'          )         [Code]             File Name: main.py             Object Name: KSA             Arg Count: 1              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 5              Stack Size: 5              Flags: 0x00000043  (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)             [Names]                 'len'                  'list'                  'range'              [Var Names]                 'key'                  'keylength'                  'S'                  'j'                  'i'              [Free Vars]             [Cell Vars]             [Constants]                 None                  256                  0              [Disassembly]                 0        LOAD_GLOBAL             0 : len                  2        LOAD_FAST               0 : key                 4        CALL_FUNCTION           1                  6        STORE_FAST              1 : keylength                 8        LOAD_GLOBAL             1 : list                  10       LOAD_GLOBAL             2 : range                  12       LOAD_CONST              1 : 256                  14       CALL_FUNCTION           1                  16       CALL_FUNCTION           1                  18       STORE_FAST              2 : S                 20       LOAD_CONST              2 : 0                  22       STORE_FAST              3 : j                 24       LOAD_GLOBAL             2 : range                  26       LOAD_CONST              1 : 256                  28       CALL_FUNCTION           1                  30       GET_ITER                                 32       FOR_ITER                29  (to 63 )                 34       STORE_FAST              4 : i                 36       LOAD_FAST               3 : j                 38       LOAD_FAST               2 : S                 40       LOAD_FAST               4 : i                 42       BINARY_SUBSCR                            44       BINARY_ADD                               46       LOAD_FAST               0 : key                 48       LOAD_FAST               4 : i                 50       LOAD_FAST               1 : keylength                 52       BINARY_MODULO                            54       BINARY_SUBSCR                            56       BINARY_ADD                               58       LOAD_CONST              1 : 256                  60       BINARY_MODULO                            62       STORE_FAST              3 : j                 64       LOAD_FAST               2 : S                 66       LOAD_FAST               3 : j                 68       BINARY_SUBSCR                            70       LOAD_FAST               2 : S                 72       LOAD_FAST               4 : i                 74       BINARY_SUBSCR                            76       ROT_TWO                                  78       LOAD_FAST               2 : S                 80       LOAD_FAST               4 : i                 82       STORE_SUBSCR                             84       LOAD_FAST               2 : S                 86       LOAD_FAST               3 : j                 88       STORE_SUBSCR                             90       JUMP_ABSOLUTE           16                  92       LOAD_FAST               2 : S                 94       RETURN_VALUE                     'KSA'          [Code]             File Name: main.py             Object Name: PRGA             Arg Count: 1              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 4              Stack Size: 4              Flags: 0x00000063  (CO_OPTIMIZED | CO_NEWLOCALS | CO_GENERATOR | CO_NOFREE)             [Names]             [Var Names]                 'S'                  'i'                  'j'                  'K'              [Free Vars]             [Cell Vars]             [Constants]                 None                  0                  True                  1                  256              [Disassembly]                 0        <INVALID>                                2        LOAD_CONST              1 : 0                  4        STORE_FAST              1 : i                 6        LOAD_CONST              1 : 0                  8        STORE_FAST              2 : j                 10       NOP                                      12       LOAD_FAST               1 : i                 14       LOAD_CONST              3 : 1                  16       BINARY_ADD                               18       LOAD_CONST              4 : 256                  20       BINARY_MODULO                            22       STORE_FAST              1 : i                 24       LOAD_FAST               2 : j                 26       LOAD_FAST               0 : S                 28       LOAD_FAST               1 : i                 30       BINARY_SUBSCR                            32       BINARY_ADD                               34       LOAD_CONST              4 : 256                  36       BINARY_MODULO                            38       STORE_FAST              2 : j                 40       LOAD_FAST               0 : S                 42       LOAD_FAST               2 : j                 44       BINARY_SUBSCR                            46       LOAD_FAST               0 : S                 48       LOAD_FAST               1 : i                 50       BINARY_SUBSCR                            52       ROT_TWO                                  54       LOAD_FAST               0 : S                 56       LOAD_FAST               1 : i                 58       STORE_SUBSCR                             60       LOAD_FAST               0 : S                 62       LOAD_FAST               2 : j                 64       STORE_SUBSCR                             66       LOAD_FAST               0 : S                 68       LOAD_FAST               0 : S                 70       LOAD_FAST               1 : i                 72       BINARY_SUBSCR                            74       LOAD_FAST               0 : S                 76       LOAD_FAST               2 : j                 78       BINARY_SUBSCR                            80       BINARY_ADD                               82       LOAD_CONST              4 : 256                  84       BINARY_MODULO                            86       BINARY_SUBSCR                            88       STORE_FAST              3 : K                 90       LOAD_FAST               3 : K                 92       YIELD_VALUE                              94       POP_TOP                                  96       JUMP_ABSOLUTE           6          'PRGA'          [Code]             File Name: main.py             Object Name: RC4             Arg Count: 1              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 2              Stack Size: 2              Flags: 0x00000043  (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)             [Names]                 'KSA'                  'PRGA'              [Var Names]                 'key'                  'S'              [Free Vars]             [Cell Vars]             [Constants]                 None              [Disassembly]                 0        LOAD_GLOBAL             0 : KSA                 2        LOAD_FAST               0 : key                 4        CALL_FUNCTION           1                  6        STORE_FAST              1 : S                 8        LOAD_GLOBAL             1 : PRGA                 10       LOAD_FAST               1 : S                 12       CALL_FUNCTION           1                  14       RETURN_VALUE                     'RC4'          [Code]             File Name: main.py             Object Name: xor             Arg Count: 2              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 2              Stack Size: 5              Flags: 0x00000003  (CO_OPTIMIZED | CO_NEWLOCALS)             [Names]                 'bytes'                  'map'              [Var Names]                 'p'                  'stream'              [Free Vars]             [Cell Vars]                 'stream'              [Constants]                 None                  [Code]                     File Name: main.py                     Object Name: <lambda >                     Arg Count: 1                      Pos Only Arg Count: 0                      KW Only Arg Count: 0                      Locals: 1                      Stack Size: 3                      Flags: 0x00000013  (CO_OPTIMIZED | CO_NEWLOCALS | CO_NESTED)                     [Names]                         '__next__'                      [Var Names]                         'x'                      [Free Vars]                         'stream'                      [Cell Vars]                     [Constants]                         None                      [Disassembly]                         0        LOAD_FAST               0 : x                         2        LOAD_DEREF              0 : stream                         4        LOAD_METHOD             0 : __next__                         6        CALL_METHOD             0                          8        BINARY_XOR                                       10       RETURN_VALUE                             'xor.<locals>.<lambda>'              [Disassembly]                 0        LOAD_GLOBAL             0 : bytes                  2        LOAD_GLOBAL             1 : map                  4        LOAD_CLOSURE            0 : stream                 6        BUILD_TUPLE             1                  8        LOAD_CONST              1 : <CODE> <lambda >                 10       LOAD_CONST              2 : 'xor.<locals>.<lambda>'                  12       MAKE_FUNCTION           8                  14       LOAD_FAST               0 : p                 16       CALL_FUNCTION           2                  18       CALL_FUNCTION           1                  20       RETURN_VALUE                     'xor'          '__main__'          b'\xf6\xef\x10H\xa9\x0f\x9f\xb5\x80\xc1xd\xae\xd3\x03\xb2\x84\xc2\xb4\x0e\xc8\xf3<\x151\x19\n\x8f'          b'$\r9\xa3\x18\xddW\xc9\x97\xf3\xa7\xa8R~'          b'geo'          b'}\xce`\xbej\xa2\x120\xb5\x8a\x94\x14{\xa3\x86\xc8\xc7\x01\x98\xa3_\x91\xd8\x82T*V\xab\xe0\xa1\x141'          b"Q_\xe2\xf8\x8c\x11M}'<@\xceT\xf6?_m\xa4\xf8\xb4\xea\xca\xc7:\xb9\xe6\x06\x8b\xeb\xfabH\x85xJ3$\xdd\xde\xb6\xdc\xa0\xb8b\x961\xb7\x13=\x17\x13\xb1"          115          97          117          114          (             2              8              11              10          )         119          116          124          127          (             3              7              9              12          )         [Code]             File Name: main.py             Object Name: <dictcomp>             Arg Count: 1              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 2              Stack Size: 6              Flags: 0x00000043  (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)             [Names]                 'n'              [Var Names]                 '.0'                  'x'              [Free Vars]             [Cell Vars]             [Constants]             [Disassembly]                 0        BUILD_MAP               0                  2        LOAD_FAST               0 : .0                  4        FOR_ITER                9  (to 15 )                 6        STORE_FAST              1 : x                 8        LOAD_FAST               1 : x                 10       LOAD_FAST               1 : x                 12       LOAD_GLOBAL             0 : n                 14       LOAD_FAST               1 : x                 16       BINARY_SUBSCR                            18       BINARY_XOR                               20       MAP_ADD                 2                  22       JUMP_ABSOLUTE           2                  24       RETURN_VALUE                     '<dictcomp>'          [Code]             File Name: main.py             Object Name: <genexpr>             Arg Count: 1              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 2              Stack Size: 3              Flags: 0x00000063  (CO_OPTIMIZED | CO_NEWLOCALS | CO_GENERATOR | CO_NOFREE)             [Names]                 'bit_count'              [Var Names]                 '.0'                  'i'              [Free Vars]             [Cell Vars]             [Constants]                 None              [Disassembly]                 0        <INVALID>                                2        LOAD_FAST               0 : .0                  4        FOR_ITER                9  (to 15 )                 6        STORE_FAST              1 : i                 8        LOAD_FAST               1 : i                 10       LOAD_METHOD             0 : bit_count                 12       CALL_METHOD             0                  14       LOAD_FAST               1 : i                 16       BUILD_TUPLE             2                  18       YIELD_VALUE                              20       POP_TOP                                  22       JUMP_ABSOLUTE           2                  24       LOAD_CONST              0 : None                  26       RETURN_VALUE                     '<genexpr>'          [Code]             File Name: main.py             Object Name: <lambda >             Arg Count: 1              Pos Only Arg Count: 0              KW Only Arg Count: 0              Locals: 1              Stack Size: 2              Flags: 0x00000043  (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)             [Names]             [Var Names]                 'x'              [Free Vars]             [Cell Vars]             [Constants]                 None                  1              [Disassembly]                 0        LOAD_FAST               0 : x                 2        LOAD_CONST              1 : 1                  4        BINARY_SUBSCR                            6        RETURN_VALUE                     '<lambda>'      [Disassembly]         0        LOAD_CONST              0 : 0          2        LOAD_CONST              1 : None          4        IMPORT_NAME             0 : sys         6        STORE_NAME              0 : sys         8        LOAD_CONST              0 : 0          10       LOAD_CONST              2 : ('sha256' ,)         12       IMPORT_NAME             1 : hashlib         14       IMPORT_FROM             2 : sha256         16       STORE_NAME              2 : sha256         18       POP_TOP                          20       LOAD_CONST              3 : <CODE> KSA         22       LOAD_CONST              4 : 'KSA'          24       MAKE_FUNCTION           0          26       STORE_NAME              3 : KSA         28       LOAD_CONST              5 : <CODE> PRGA         30       LOAD_CONST              6 : 'PRGA'          32       MAKE_FUNCTION           0          34       STORE_NAME              4 : PRGA         36       LOAD_CONST              7 : <CODE> RC4         38       LOAD_CONST              8 : 'RC4'          40       MAKE_FUNCTION           0          42       STORE_NAME              5 : RC4         44       LOAD_CONST              9 : <CODE> xor         46       LOAD_CONST              10 : 'xor'          48       MAKE_FUNCTION           0          50       STORE_NAME              6 : xor         52       LOAD_NAME               7 : __name__         54       LOAD_CONST              11 : '__main__'          56       COMPARE_OP              2  (==)         58       POP_JUMP_IF_FALSE       139          60       LOAD_CONST              12 : b'\xf6\xef\x10H\xa9\x0f\x9f\xb5\x80\xc1xd\xae\xd3\x03\xb2\x84\xc2\xb4\x0e\xc8\xf3<\x151\x19\n\x8f'          62       STORE_NAME              8 : w         64       LOAD_CONST              13 : b'$\r9\xa3\x18\xddW\xc9\x97\xf3\xa7\xa8R~'          66       STORE_NAME              9 : e         68       LOAD_CONST              14 : b'geo'          70       STORE_NAME              10 : b         72       LOAD_CONST              15 : b'}\xce`\xbej\xa2\x120\xb5\x8a\x94\x14{\xa3\x86\xc8\xc7\x01\x98\xa3_\x91\xd8\x82T*V\xab\xe0\xa1\x141'          74       STORE_NAME              11 : s         76       LOAD_CONST              16 : b"Q_\xe2\xf8\x8c\x11M}'<@\xceT\xf6?_m\xa4\xf8\xb4\xea\xca\xc7:\xb9\xe6\x06\x8b\xeb\xfabH\x85xJ3$\xdd\xde\xb6\xdc\xa0\xb8b\x961\xb7\x13=\x17\x13\xb1"          78       STORE_NAME              12 : t         80       LOAD_CONST              17 : 115          82       LOAD_CONST              18 : 97          84       LOAD_CONST              19 : 117          86       LOAD_CONST              20 : 114          88       LOAD_CONST              21 : (2 , 8 , 11 , 10 )         90       BUILD_CONST_KEY_MAP     4          92       STORE_NAME              13 : m         94       LOAD_CONST              22 : 119          96       LOAD_CONST              23 : 116          98       LOAD_CONST              24 : 124          100      LOAD_CONST              25 : 127          102      LOAD_CONST              26 : (3 , 7 , 9 , 12 )         104      BUILD_CONST_KEY_MAP     4          106      STORE_NAME              14 : n         108      LOAD_NAME               13 : m         110      LOAD_CONST              27 : <CODE> <dictcomp>         112      LOAD_CONST              28 : '<dictcomp>'          114      MAKE_FUNCTION           0          116      LOAD_NAME               14 : n         118      GET_ITER                         120      CALL_FUNCTION           1          122      INPLACE_OR                       124      STORE_NAME              13 : m         126      LOAD_NAME               13 : m         128      LOAD_CONST              29 : <CODE> <genexpr>         130      LOAD_CONST              30 : '<genexpr>'          132      MAKE_FUNCTION           0          134      LOAD_NAME               10 : b         136      GET_ITER                         138      CALL_FUNCTION           1          140      INPLACE_OR                       142      STORE_NAME              13 : m         144      LOAD_NAME               5 : RC4         146      LOAD_NAME               15 : list          148      LOAD_NAME               16 : map          150      LOAD_CONST              31 : <CODE> <lambda >         152      LOAD_CONST              32 : '<lambda>'          154      MAKE_FUNCTION           0          156      LOAD_NAME               17 : sorted          158      LOAD_NAME               13 : m         160      LOAD_METHOD             18 : items         162      CALL_METHOD             0          164      CALL_FUNCTION           1          166      CALL_FUNCTION           2          168      CALL_FUNCTION           1          170      CALL_FUNCTION           1          172      STORE_NAME              19 : stream         174      LOAD_NAME               20 : print          176      LOAD_NAME               6 : xor         178      LOAD_NAME               8 : w         180      LOAD_NAME               19 : stream         182      CALL_FUNCTION           2          184      LOAD_METHOD             21 : decode         186      CALL_METHOD             0          188      CALL_FUNCTION           1          190      POP_TOP                          192      LOAD_NAME               0 : sys         194      LOAD_ATTR               22 : stdin         196      LOAD_ATTR               23 : buffer         198      LOAD_METHOD             24 : read         200      CALL_METHOD             0          202      STORE_NAME              25 : p         204      LOAD_NAME               6 : xor         206      LOAD_NAME               9 : e         208      LOAD_NAME               19 : stream         210      CALL_FUNCTION           2          212      STORE_NAME              9 : e         214      LOAD_NAME               6 : xor         216      LOAD_NAME               25 : p         218      LOAD_NAME               19 : stream         220      CALL_FUNCTION           2          222      STORE_NAME              26 : c         224      LOAD_NAME               2 : sha256         226      LOAD_NAME               26 : c         228      CALL_FUNCTION           1          230      LOAD_METHOD             27 : digest         232      CALL_METHOD             0          234      LOAD_NAME               11 : s         236      COMPARE_OP              2  (==)         238      POP_JUMP_IF_FALSE       131          240      LOAD_NAME               20 : print          242      LOAD_NAME               6 : xor         244      LOAD_NAME               12 : t         246      LOAD_NAME               19 : stream         248      CALL_FUNCTION           2          250      LOAD_METHOD             21 : decode         252      CALL_METHOD             0          254      CALL_FUNCTION           1          256      POP_TOP                          258      LOAD_CONST              1 : None          260      RETURN_VALUE                     262      LOAD_NAME               20 : print          264      LOAD_NAME               9 : e         266      LOAD_METHOD             21 : decode         268      CALL_METHOD             0          270      CALL_FUNCTION           1          272      POP_TOP                          274      LOAD_CONST              1 : None          276      RETURN_VALUE                     278      LOAD_CONST              1 : None          280      RETURN_VALUE             
看到行数不算太多,而且有很多都是赋值操作,比较容易逆,干脆直接手逆出源码
逆出来的main.py:
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 import  sysfrom  hashlib import  sha256def  KSA (key ):    keylength=len (key)     S=list (range (256 ))     j=0      for  i in  range (256 ):         j=(S[i]+j+key[i%keylength])%256          S[i],S[j]=S[j],S[i]     return  S def  PRGA (S ):    i=0      j=0      while  True :         i=(i+1 )%256          j=(j+S[i])%256          S[j],S[i]=S[i],S[j]         K=S[(S[i]+S[j])%256 ]         yield  K def  RC4 (key ):    S=KSA(key)     return  PRGA(S) def  xor (p,stream ):    return  bytes (map (lambda  x:x^stream.__next__(),p)) if  __name__=='__main__' :    w=b'\xf6\xef\x10H\xa9\x0f\x9f\xb5\x80\xc1xd\xae\xd3\x03\xb2\x84\xc2\xb4\x0e\xc8\xf3<\x151\x19\n\x8f'      e=b'$\r9\xa3\x18\xddW\xc9\x97\xf3\xa7\xa8R~'      b=b'geo'      s=b'}\xce`\xbej\xa2\x120\xb5\x8a\x94\x14{\xa3\x86\xc8\xc7\x01\x98\xa3_\x91\xd8\x82T*V\xab\xe0\xa1\x141'      t=b"Q_\xe2\xf8\x8c\x11M}'<@\xceT\xf6?_m\xa4\xf8\xb4\xea\xca\xc7:\xb9\xe6\x06\x8b\xeb\xfabH\x85xJ3$\xdd\xde\xb6\xdc\xa0\xb8b\x961\xb7\x13=\x17\x13\xb1"      m={2 :115 ,8 :97 ,11 :117 ,10 :114 }     n={3 :119 ,7 :116 ,9 :124 ,12 :127 }     m|={x:x^n[x] for  x in  n}     m|=((i.bit_count(),i) for  i in  b)     stream=RC4(list (map (lambda  x:x[1 ],sorted (m.items()))))     print(xor(w,stream).decode())     p=sys.stdin.buffer.read()     e=xor(e,stream)     c=xor(p,stream)     if  sha256(c).digest()==s:         print(xor(t,stream).decode())     else :         print(e.decode()) 
逆的过程中发现bit_count()是python 3.10的新方法,一查才发现6f 0d 0d 0a是3.10版本的魔数(还以为第一字节被魔改了x
这里python文件的逻辑是用m、n、b生成了一个key,给rc4初始化密钥流,然后xor加密数据(其实就是把rc4加密拆开了),最后验证密文的sha256值是否等于所给的值即可。
由于yield的特性,我们可以爆破出p是26位(其他长度的输入都不能正常输出xor(t,stream).decode())
pyc隐写 爆破sha256显然是不可行的,于是猜测到有pyc隐写,把key打印出来也能看到有提示:
stegosaurus是一个pyc隐写工具(AngelKitty/stegosaurus: A steganography tool for embedding payloads within Python bytecode. ),拿工具来用发现又报错,查了一下发现是工具不兼容高版本的问题。
研究了一下这个工具的隐写原理,然后直接手抠隐写payload(
用自己逆出来的main.py生成pyc文件,来跟题目提出来的pyc文件在010里做对比,题目中有值且自己的pyc文件中为00的部分很大可能是隐写的字节,比如这种:(其他以此类推)
拿到一串乱序的payload:b'\xf0\xb4\x55\x16\x36\xc5\x6f\xdb\xc9\xea\x64\x04\x15\x62\x11\xa2\xb0\xcd\xf0\x7d\x49\x32\xd6\x22\xe5\x0a'
因为顺序问题无从下手,只好用stegosaurus工具自己生成了一个隐写版本的两个pyc做对比,为了方便看顺序,payload设置成”ABCDEFGHIJKLMNOPQRSTUVWXYZ“:
拿到两个pyc文件,很容易就对比出这26个字母的顺序,比如:
最后拿到顺序
按顺序排列payload填入p中,由rc4的特性加密和解密流程相同,所以可以直接拿源码改出exp:
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 import  sysfrom  hashlib import  sha256def  KSA (key ):    keylength=len (key)     S=list (range (256 ))     j=0      for  i in  range (256 ):         j=(S[i]+j+key[i%keylength])%256          S[i],S[j]=S[j],S[i]     return  S def  PRGA (S ):    i=0      j=0      while  True :         i=(i+1 )%256          j=(j+S[i])%256          S[j],S[i]=S[i],S[j]         K=S[(S[i]+S[j])%256 ]         yield  K def  RC4 (key ):    S=KSA(key)     return  PRGA(S) def  xor (p,stream ):    return  bytes (map (lambda  x:x^stream.__next__(),p)) if  __name__=='__main__' :    w=b'\xf6\xef\x10H\xa9\x0f\x9f\xb5\x80\xc1xd\xae\xd3\x03\xb2\x84\xc2\xb4\x0e\xc8\xf3<\x151\x19\n\x8f'      e=b'$\r9\xa3\x18\xddW\xc9\x97\xf3\xa7\xa8R~'      b=b'geo'      s=b'}\xce`\xbej\xa2\x120\xb5\x8a\x94\x14{\xa3\x86\xc8\xc7\x01\x98\xa3_\x91\xd8\x82T*V\xab\xe0\xa1\x141'      t=b"Q_\xe2\xf8\x8c\x11M}'<@\xceT\xf6?_m\xa4\xf8\xb4\xea\xca\xc7:\xb9\xe6\x06\x8b\xeb\xfabH\x85xJ3$\xdd\xde\xb6\xdc\xa0\xb8b\x961\xb7\x13=\x17\x13\xb1"      m={2 :115 ,8 :97 ,11 :117 ,10 :114 }     n={3 :119 ,7 :116 ,9 :124 ,12 :127 }     m|={x:x^n[x] for  x in  n}     m|=((i.bit_count(),i) for  i in  b)     stream=RC4(list (map (lambda  x:x[1 ],sorted (m.items()))))     print(xor(w,stream).decode())          p=b'\xe5\x0a\x32\xd6\x22\xf0\x7d\x49\xb0\xcd\xa2\x11\xf0\xb4\x55\x16\x36\xc5\x6f\xdb\xc9\xea\x64\x04\x15\x62'      e=xor(e,stream)     c=xor(p,stream)     print(c)     if  sha256(c).digest()==s:         print(xor(t,stream).decode())     else :         print(e.decode()) 
拿到flag :flag{P0w5rFu1_0pEn_50urcE}
赛后改进 用python提取pcapng 比赛的时候是直接硬提取的流量包里的纯文本的,写脚本比较麻烦XD
后来看到Nu1l的wp调用了一个库python-pcapng,感觉可行,来学着写一下脚本试试。
再后来报错搞不定,找了另一个包pyshark写脚本有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import  pysharkimport  recap=pyshark.FileCapture('./ExtremelySlow.pcapng' ,display_filter="data" ) data=[] for  packet in  cap:    content=packet['HTTP' ].get_field_by_showname('content-range' ).showname_value     key=int (re.findall(r"\d+" ,content)[0 ])     try :         val=packet['DATA' ].data.binary_value     except  AttributeError:         val=bytes (chr (packet['DATA' ].tcp_reassembled_data.binary_value[-1 ]),encoding='utf-8' )     finally :         data.append((key,val)) data=sorted (data,key=lambda  t:t[0 ]) with  open ('./res' ,'wb' ) as  f:    for  t in  data:         f.write(t[1 ]) 
反汇编pyc文件 反汇编pyc还可以用以下的小脚本(来自python - How can I understand a .pyc file content - Stack Overflow ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import  dis, marshal, sysheader_sizes = [               (8 ,  (0 , 9 , 2 )),       (12 , (3 , 6 )),                         (16 , (3 , 7 )),                ] header_size = next (s for  s, v in  reversed (header_sizes) if  sys.version_info >= v) with  open (pycfile, "rb" ) as  f:    metadata = f.read(header_size)       code = marshal.load(f)           dis.dis(code) 
魔改stegosaurus 反编译器魔改估计得写很长,有空专门开一篇文章(咕咕咕)。
这里魔改一下stegosaurus,让它支持3.10版本。
(仓库指路:c10udlnk/stegosaurus: 添加python3.10支持。A steganography tool for embedding payloads within Python bytecode. 
首先执行python3.10 stegosaurus.py res.pyc -x,报错:
在stegosaurus.py定位到出错代码:
从这里(Python代码保护 | pyc 混淆从入门到工具实现 - 知乎 )可以知道,3.5和3.6的header有12字节,而3.7开始支持校验hash值,又多了4字节出来,所以header这里要加一行版本的判断。
然后继续报错:
这里可以知道是编码的问题
而payload里有不可见字符,所以干脆就直接把转码去掉就好。
魔改get √