/ reverse

breizhctf2k16 - CompileMe

On commence le chall en récupérant un .pyc

guy@kali:$ ./compileme test
Nope sugar daddy ;)

on décompile avec pycdc

guy@kali:/home/ctf/breizhctf2016/compileMe$ pycdc compileme > out.py

on trouve un bout de code intéressant :

REDACTED = "\ndis.dis(gimme_the_flag)\n    2         0 LOAD_CONST               1 (252)\n              3 LOAD_CONST               2 (236)\n              6 LOAD_CONST               3 (251)\n              9 LOAD_CONST               4 (247)\n             12 LOAD_CONST               5 (228)\n             15 LOAD_CONST               6 (246)\n             18 LOAD_CONST               7 (253)\n             21 LOAD_CONST               8 (234)\n             24 LOAD_CONST               9 (248)\n             27 LOAD_CONST              10 (197)\n             30 LOAD_CONST              11 (218)\n             33 LOAD_CONST              12 (142)\n             36 LOAD_CONST              13 (219)\n             39 LOAD_CONST              14 (205)\n             42 LOAD_CONST              15 (225)\n             45 LOAD_CONST              16 (237)\n             48 LOAD_CONST              17 (223)\n             51 LOAD_CONST              18 (198)\n             54 LOAD_CONST              19 (230)\n             57 LOAD_CONST              15 (225)\n             60 LOAD_CONST              20 (206)\n             63 LOAD_CONST              21 (204)\n             66 LOAD_CONST              12 (142)\n             69 LOAD_CONST              22 (217)\n             72 LOAD_CONST              21 (204)\n             75 LOAD_CONST              23 (138)\n             78 LOAD_CONST              24 (211)\n             81 LOAD_CONST              15 (225)\n             84 LOAD_CONST              21 (204)\n             87 LOAD_CONST              25 (141)\n             90 LOAD_CONST              23 (138)\n             93 LOAD_CONST              26 (210)\n             96 LOAD_CONST              26 (210)\n             99 LOAD_CONST              27 (231)\n            102 LOAD_CONST              15 (225)\n            105 LOAD_CONST              28 (221)\n            108 LOAD_CONST              12 (142)\n            111 LOAD_CONST              24 (211)\n            114 LOAD_CONST              20 (206)\n            117 LOAD_CONST              29 (215)\n            120 LOAD_CONST              26 (210)\n            123 LOAD_CONST              13 (219)\n            126 LOAD_CONST              30 (129)\n            129 LOAD_CONST              11 (218)\n            132 LOAD_CONST              12 (142)\n            135 LOAD_CONST              31 (214)\n            138 LOAD_CONST              32 (159)\n            141 LOAD_CONST              32 (159)\n            144 LOAD_CONST              32 (159)\n            147 LOAD_CONST              33 (195)\n            150 BUILD_LIST              50\n            153 STORE_FAST               0 (flag)\n\n  3         156 BUILD_LIST               0\n            159 STORE_FAST               1 (realflag)\n\n  4         162 SETUP_LOOP              31 (to 196)\n            165 LOAD_FAST                0 (flag)\n            168 GET_ITER            \n        >>  169 FOR_ITER                23 (to 195)\n            172 STORE_FAST               2 (c)\n\n  5         175 LOAD_FAST                1 (realflag)\n            178 LOAD_ATTR                0 (append)\n            181 LOAD_FAST                2 (c)\n            184 LOAD_CONST              34 (190)\n            187 BINARY_XOR          \n            188 CALL_FUNCTION            1\n            191 POP_TOP             \n            192 JUMP_ABSOLUTE          169\n        >>  195 POP_BLOCK           \n\n  6     >>  196 LOAD_CONST              35 ('')\n            199 LOAD_ATTR                1 (join)\n            202 LOAD_GLOBAL              2 (map)\n            205 LOAD_GLOBAL              3 (chr)\n            208 LOAD_FAST                1 (realflag)\n            211 CALL_FUNCTION            2\n            214 CALL_FUNCTION            1\n            217 PRINT_ITEM          \n            218 PRINT_NEWLINE       \n            219 LOAD_CONST               0 (None)\n            222 RETURN_VALUE\n"

on nettoie un peu


dis.dis(gimme_the_flag)
    2         0 LOAD_CONST               1 (252)
              3 LOAD_CONST               2 (236)
              6 LOAD_CONST               3 (251)
              9 LOAD_CONST               4 (247)
             12 LOAD_CONST               5 (228)
             15 LOAD_CONST               6 (246)
             18 LOAD_CONST               7 (253)
             21 LOAD_CONST               8 (234)
             24 LOAD_CONST               9 (248)
             27 LOAD_CONST              10 (197)
             30 LOAD_CONST              11 (218)
             33 LOAD_CONST              12 (142)
             36 LOAD_CONST              13 (219)
             39 LOAD_CONST              14 (205)
             42 LOAD_CONST              15 (225)
             45 LOAD_CONST              16 (237)
             48 LOAD_CONST              17 (223)
             51 LOAD_CONST              18 (198)
             54 LOAD_CONST              19 (230)
             57 LOAD_CONST              15 (225)
             60 LOAD_CONST              20 (206)
             63 LOAD_CONST              21 (204)
             66 LOAD_CONST              12 (142)
             69 LOAD_CONST              22 (217)
             72 LOAD_CONST              21 (204)
             75 LOAD_CONST              23 (138)
             78 LOAD_CONST              24 (211)
             81 LOAD_CONST              15 (225)
             84 LOAD_CONST              21 (204)
             87 LOAD_CONST              25 (141)
             90 LOAD_CONST              23 (138)
             93 LOAD_CONST              26 (210)
             96 LOAD_CONST              26 (210)
             99 LOAD_CONST              27 (231)
            102 LOAD_CONST              15 (225)
            105 LOAD_CONST              28 (221)
            108 LOAD_CONST              12 (142)
            111 LOAD_CONST              24 (211)
            114 LOAD_CONST              20 (206)
            117 LOAD_CONST              29 (215)
            120 LOAD_CONST              26 (210)
            123 LOAD_CONST              13 (219)
            126 LOAD_CONST              30 (129)
            129 LOAD_CONST              11 (218)
            132 LOAD_CONST              12 (142)
            135 LOAD_CONST              31 (214)
            138 LOAD_CONST              32 (159)
            141 LOAD_CONST              32 (159)
            144 LOAD_CONST              32 (159)
            147 LOAD_CONST              33 (195)
            150 BUILD_LIST              50
            153 STORE_FAST               0 (flag)

  3         156 BUILD_LIST               0
            159 STORE_FAST               1 (realflag)

  4         162 SETUP_LOOP              31 (to 196)
            165 LOAD_FAST                0 (flag)
            168 GET_ITER            
        >>  169 FOR_ITER                23 (to 195)
            172 STORE_FAST               2 (c)

  5         175 LOAD_FAST                1 (realflag)
            178 LOAD_ATTR                0 (append)
            181 LOAD_FAST                2 (c)
            184 LOAD_CONST              34 (190)
            187 BINARY_XOR          
            188 CALL_FUNCTION            1
            191 POP_TOP             
            192 JUMP_ABSOLUTE          169
        >>  195 POP_BLOCK           

  6     >>  196 LOAD_CONST              35 ('')
            199 LOAD_ATTR                1 (join)
            202 LOAD_GLOBAL              2 (map)
            205 LOAD_GLOBAL              3 (chr)
            208 LOAD_FAST                1 (realflag)
            211 CALL_FUNCTION            2
            214 CALL_FUNCTION            1
            217 PRINT_ITEM          
            218 PRINT_NEWLINE       
            219 LOAD_CONST               0 (None)
            222 RETURN_VALUE

on a visiblement le resultat de la fonction dis.dis(gimme_the_flag) (voir dis)

le programme charge plusieurs entier
132 LOAD_CONST 12 (XXX)̀
puis le programme fait une liste à partir des entiers, et les xor avec 190

        >>  169 FOR_ITER                23 (to 195)
            172 STORE_FAST               2 (c)

  5         175 LOAD_FAST                1 (realflag)
            178 LOAD_ATTR                0 (append)
            181 LOAD_FAST                2 (c)
            184 LOAD_CONST              34 (190)
            187 BINARY_XOR          
            188 CALL_FUNCTION            1
            191 POP_TOP             
            192 JUMP_ABSOLUTE          169
        >>  195 POP_BLOCK           

on effectue la même opération pour voir le résultat :

key=190
consts='''
252
            236
            251
            247
            228
            246
            253
            234
            248
            197
            218
            142
            219
            205
            225
            237
            223
            198
            230
            225
            206
            204
            142
            217
            204
            138
            211
            225
            204
            141
            138
            210
            210
            231
            225
            221
            142
            211
            206
            215
            210
            219
            129
            218
            142
            214
            159
            159
            159
            195    
'''

for c in consts[1:-1].split("\n"):
    print chr(int(c.strip())^key),
    

tadam ! B R E I Z H C T F { d 0 e s _ S a x X _ p r 0 g r 4 m _ r 3 4 l l Y _ c 0 m p i l e ? d 0 h ! ! ! }