VNCTF2022-BabyMaze
pyc相关知识-https://zhuanlan.zhihu.com/p/145811103
pyc混淆-https://blog.csdn.net/weixin_44222568/article/details/111672799
使用uncompyle6发现无法反编译,应该是添加了花指令
先查看字节码
脚本
1 2 3 4 import marshal, disf = open ("D:\\new\\AD\\game\\vnctf2022\\re\\BabyMaze.pyc" , "rb" ).read() code = marshal.loads(f[16 :]) dis.dis(code)
发现这一段就是花指令
去python的包里面搜索opcode.h,找到对应的字节码
转为十六进制后去010editor修改,去掉即可
但是发现还是不行,这是因为
pyc文件有co_code,所以修改长度之后要修改它
先打印出来长度,然后计算后修改
2030-6=7E8
重新uncompyle6
反编译成功,接下来就是maze图,打印出来之后手打
Pyc字节码阅读-unctf2021-pytrade
得到两个txt文件,一个是py的字节码,一个是输出
对字节码进行分析
https://www.jianshu.com/p/557cfe36f0f0
https://bbs.pediy.com/thread-246683.htm
https://docs.python.org/zh-cn/3/library/dis.html 这是python3的
1 2 0 LOAD_CONST 1 ('XXXXXX' ) //This is flag,try to figure it out ! Don't forget to fill it in flag{} ! 2 STORE_FAST 0 (flag)
LOAD_CONST加载const变量,比如数值、字符串等,一般用于传给函数参数
STORE_FAST 一般用于保存值到局部变量
这句话意思是
第二段
1 2 3 4 5 4 LOAD_CONST 2 (0 ) const变量,一般用于传给函数的参数 6 BUILD_LIST 1 创建列表 8 LOAD_CONST 3 (18 ) const变量 num=[0 ]*18 10 BINARY_MULTIPLY 12 STORE_FAST 1 (num) 保存值到局部变量中
BINARY_MULTIPLY 是二元运算,即将栈顶的前两个元素取出进行计算,结果压回栈中
BUILD_LIST 创建列表
第三段
1 2 14 LOAD_CONST 2 (0 ) 16 STORE_FAST 2 (k)
第四段
1 2 3 4 5 6 7 8 18 LOAD_GLOBAL 0 (range ) 加载全局变量 20 LOAD_GLOBAL 1 (len ) 22 LOAD_FAST 0 (flag) 24 CALL_FUNCTION 1 调用一个函数,在此之前要先赋值 len (flag) 26 CALL_FUNCTION 1 range (len (flag)) 28 GET_ITER 取迭代器 >> 30 FOR_ITER 112 (to 144 ) 一直到144 都是for 循环 32 STORE_FAST 3 (i)
LOAD_GLOBAL 用来加载全局变量,包括指定函数名,类名,模块名等全局符号。当和函数搭配时,要注意有CALL_FUNCTION
LOAD_FAST一般加载局部变量的值,也就是读取值,用于计算或者函数调用传参等。这里调用完len之后,要使用其传值,这里传入flag
前半段意思是
GET_ITER创建迭代器,一般是for循环
FOR_ITER(to 144)表示迭代器一直到144
STORE_FAST 创建局部变量,这里作为for循环的索引
1 for i in range (len (flag)):
第五段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 7 34 LOAD_GLOBAL 2 (ord ) 36 LOAD_FAST 0 (flag) 38 LOAD_FAST 3 (i) 40 BINARY_SUBSCR 索引运算 42 CALL_FUNCTION 1 ord (flag[i]) 44 LOAD_FAST 3 (i) 46 BINARY_ADD +i 48 LOAD_FAST 2 (k) 50 LOAD_CONST 4 (3 ) 52 BINARY_MODULO //取模运算 k%3 54 LOAD_CONST 5 (1 ) 56 BINARY_ADD (k%3 )+1 58 BINARY_XOR (ord (flag[i])+i)^(k%3 +1 ) 60 LOAD_FAST 1 (num) 62 LOAD_FAST 3 (i) 64 STORE_SUBSCR num[i]
BINARY_SUBSCR下标 访问操作
BINARY_ADD也是二元运算,相加
BINARY_MODULO,二元运算取模
BINARY_XOR二元运算异或
STORE_SUBSCR下标访问操作
1 num[i]= (ord (flag[i]) + i) ^ (k % 3 + 1 )
第六段
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 8 66 LOAD_GLOBAL 2 (ord ) 68 LOAD_FAST 0 (flag) 70 LOAD_GLOBAL 1 (len ) 72 LOAD_FAST 0 (flag) 74 CALL_FUNCTION 1 len (flag) 76 LOAD_FAST 3 (i) len (flag)-i 78 BINARY_SUBTRACT 80 LOAD_CONST 5 (1 ) 82 BINARY_SUBTRACT 减法 len (flag)-i-1 84 BINARY_SUBSCR 索引运算 flag[len (flag)-i-1 ] 86 CALL_FUNCTION 1 ord (flag[len (flag)-i-1 ]) 88 LOAD_GLOBAL 1 (len ) 90 LOAD_FAST 0 (flag) 92 CALL_FUNCTION 1 len (flag) 94 BINARY_ADD ord (flag[len (flag)-i-1 ])+len (flag)-i-1 96 LOAD_FAST 3 (i) 98 BINARY_SUBTRACT 100 LOAD_CONST 5 (1 ) 102 BINARY_SUBTRACT 104 LOAD_FAST 2 (k) 106 LOAD_CONST 4 (3 ) 108 BINARY_MODULO k%3 110 LOAD_CONST 5 (1 ) 112 BINARY_ADD k%3 +1 114 BINARY_XOR ord (flag[len (flag)-i-1 ])+(len (flag)-i-1 )^(k%3 +1 ) 116 LOAD_FAST 1 (num) 118 LOAD_GLOBAL 1 (len ) 120 LOAD_FAST 0 (flag) len (flag) 122 CALL_FUNCTION 1 124 LOAD_FAST 3 (i) 126 BINARY_SUBTRACT len (flag)-i 128 LOAD_CONST 5 (1 ) 130 BINARY_SUBTRACT len (flag)-i-1 132 STORE_SUBSCR num[len (flag)-i-1 ]=ord (flag[len (flag)-i-1 ])+(len (flag)-i-1 )^(k%3 +1 )
BINARY_SUBTRACT二元运算减法
1 num[len (flag)-i-1 ]=ord (flag[len (flag)-i-1 ])+(len (flag)-i-1 )^(k%3 +1 )
第七段
1 2 3 4 5 6 9 134 LOAD_FAST 2 (k) 136 LOAD_CONST 5 (1 ) 138 INPLACE_ADD k++ 140 STORE_FAST 2 (k) 142 JUMP_ABSOLUTE 30 //循环结束
JUMP_ABSOLUTE绝对跳转,结束循环
INPLACE_ADD 计算结果可以被操作数引用的到,每一个 二元运算,都对应一个inplace 运算
第八段
1 2 3 4 5 6 10 >> 144 LOAD_GLOBAL 3 (print ) 146 LOAD_FAST 1 (num) 148 CALL_FUNCTION 1 print (num) 150 POP_TOP 152 LOAD_CONST 0 (None ) 154 RETURN_VALUE
Easy_Re
python3.9,无法uncompyle6,使用pycdc翻译成字节码
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 main.pyc (Python 3.9 ) [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: 4 Flags: 0x00000040 (CO_NOFREE) [Names] 'base64' 'encode' 'enCodeAgain' 'correct' 'flag' 'print' 'input' [Var Names] [Free Vars] [Cell Vars] [Constants] 0 None [Code] File Name: main.py Object Name: encode Arg Count: 1 Pos Only Arg Count: 0 KW Only Arg Count: 0 Locals: 4 Stack Size: 5 Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE) [Names] 'chr' 'base64' 'b64encode' 'encode' [Var Names] 'message' 's' 'i' 'x' [Free Vars] [Cell Vars] [Constants] None '' 32 16 'utf-8' [Disassembly] 0 LOAD_CONST 1 : '' 2 STORE_FAST 1 : s s='' 4 LOAD_FAST 0 : message 6 GET_ITER 8 FOR_ITER 32 (to 42 ) for i in message: 10 STORE_FAST 2 : i 12 LOAD_FAST 2 : i 14 LOAD_CONST 2 : 32 16 BINARY_XOR i^32 18 STORE_FAST 3 : x x=i^32 20 LOAD_FAST 3 : x 22 LOAD_CONST 3 : 16 24 BINARY_ADD x+16 26 STORE_FAST 3 : x x=x+16 28 LOAD_FAST 1 : s 30 LOAD_GLOBAL 0 : chr 32 LOAD_FAST 3 : x 34 CALL_FUNCTION 1 chr (x) 36 INPLACE_ADD s+chr (x) 38 STORE_FAST 1 : s s=s+chr (x) 40 JUMP_ABSOLUTE 8 循环结束 42 LOAD_GLOBAL 1 : base64 44 LOAD_METHOD 2 : b64encode base64.b64 46 LOAD_FAST 1 : s 48 LOAD_METHOD 3 : encode LOAD_METHOD是加载类,CALL调用 50 LOAD_CONST 4 : 'utf-8' 52 CALL_METHOD 1 54 CALL_METHOD 1 base64.b64(s.encode('utf-8' )) 56 RETURN_VALUE return base64.b64(s.encode('utf-8' )) 'encode' [Code] File Name: main.py Object Name: enCodeAgain Arg Count: 2 Pos Only Arg Count: 0 KW Only Arg Count: 0 Locals: 5 Stack Size: 5 Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE) [Names] 'str' 'range' 'len' [Var Names] 'string' 'space' 's' 'i' 'j' [Free Vars] [Cell Vars] [Constants] None '' 'utf-8' 0 [Disassembly] 0 LOAD_CONST 1 : '' 2 STORE_FAST 2 : s s='' 4 LOAD_GLOBAL 0 : str 6 LOAD_FAST 0 : string 8 LOAD_CONST 2 : 'utf-8' 10 CALL_FUNCTION 2 //参数个数 str (string,'utf-8' ) 12 STORE_FAST 0 : string string=str (string,'utf-8' ) 14 LOAD_GLOBAL 1 : range 16 LOAD_CONST 3 : 0 18 LOAD_FAST 1 : space 20 CALL_FUNCTION 2 range (0 ,space) 22 GET_ITER //创建迭代器 24 FOR_ITER 50 (to 76 ) 26 STORE_FAST 3 : i for i range (0 ,space): 28 LOAD_GLOBAL 1 : range 30 LOAD_FAST 3 : i 32 LOAD_GLOBAL 2 : len 34 LOAD_FAST 0 : string 36 CALL_FUNCTION 1 len (string) 38 LOAD_FAST 1 : space 40 CALL_FUNCTION 3 42 GET_ITER 44 FOR_ITER 28 (to 74 ) 46 STORE_FAST 4 : j for j in range (i,len (string),space) 48 LOAD_FAST 4 : j 50 LOAD_GLOBAL 2 : len 52 LOAD_FAST 0 : string 54 CALL_FUNCTION 1 len (string) 56 COMPARE_OP 0 (<) if (j<len (string)) 58 POP_JUMP_IF_FALSE 44 跳转 60 LOAD_FAST 2 : s 62 LOAD_FAST 0 : string 64 LOAD_FAST 4 : j 66 BINARY_SUBSCR string[j] 68 INPLACE_ADD 70 STORE_FAST 2 : s s+=string[j] 72 JUMP_ABSOLUTE 44 第二个循环 74 JUMP_ABSOLUTE 24 第一个循环 76 LOAD_FAST 2 : s 78 RETURN_VALUE return s 'enCodeAgain' 'VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ=' '' 'Input flag:' 'utf-8' 2 'correct' 'wrong' [Disassembly] 0 LOAD_CONST 0 : 0 2 LOAD_CONST 1 : None 4 IMPORT_NAME 0 : base64 6 STORE_NAME 0 : base64 import base64 8 LOAD_CONST 2 : <CODE> encode 10 LOAD_CONST 3 : 'encode' //函数 12 MAKE_FUNCTION 0 14 STORE_NAME 1 : encode 16 LOAD_CONST 4 : <CODE> enCodeAgain 18 LOAD_CONST 5 : 'enCodeAgain' 20 MAKE_FUNCTION 0 //第二个函数 22 STORE_NAME 2 : enCodeAgain 24 LOAD_CONST 6 : 'VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ=' 26 STORE_NAME 3 : correct correct=VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ= 28 LOAD_CONST 7 : '' 30 STORE_NAME 4 : flag flag='' 32 LOAD_NAME 5 : print 34 LOAD_CONST 8 : 'Input flag:' 36 CALL_FUNCTION 1 print ('Int flag:' ) 38 POP_TOP 40 LOAD_NAME 6 : input 42 CALL_FUNCTION 0 input () 44 STORE_NAME 4 : flag flag=input () 46 LOAD_NAME 4 : flag 48 LOAD_METHOD 1 : encode 50 LOAD_CONST 9 : 'utf-8' 52 CALL_METHOD 1 54 STORE_NAME 4 : flag flag=flag.encode('utf-8' ) 56 LOAD_NAME 5 : print 58 LOAD_NAME 2 : enCodeAgain 60 LOAD_NAME 1 : encode 62 LOAD_NAME 4 : flag 64 CALL_FUNCTION 1 66 LOAD_CONST 10 : 2 其中一个参数 68 CALL_FUNCTION 2 //两个参数 70 CALL_FUNCTION 1 print (enCodeAgain(encodee(flag),2 )) 72 POP_TOP 函数栈顶元素出栈 74 LOAD_NAME 2 : enCodeAgain 76 LOAD_NAME 1 : encode 78 LOAD_NAME 4 : flag 80 CALL_FUNCTION 1 82 LOAD_CONST 10 : 2 84 CALL_FUNCTION 2 (enCodeAgain(encodee(flag),2 )) 86 LOAD_NAME 3 : correct 88 COMPARE_OP 2 (==) //比较 90 POP_JUMP_IF_FALSE 102 跳转 92 LOAD_NAME 5 : print 94 LOAD_CONST 11 : 'correct' 96 CALL_FUNCTION 1 print ('correct' ) 98 POP_TOP 100 JUMP_FORWARD 8 (to 110 ) 结束 102 LOAD_NAME 5 : print 104 LOAD_CONST 12 : 'wrong' 106 CALL_FUNCTION 1 print ('wrong) 108 POP_TOP 110 LOAD_CONST 1: None 112 RETURN_VALUE
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 import base64def encode (message ): s = '' for i in message: x = i ^ 32 x += 16 s += chr (x) return (base64.b64encode(s.encode('utf-8' ))) def enCodeAgain (string, space ): s = '' string = str (string, 'utf-8' ) for i in range (0 , space): for j in range (i, len (string), space): if j < len (string): s += string[j] return s correct = 'VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ=' flag = '' print ('Input flag:' )flag = input () flag = flag.encode('utf-8' ) print (enCodeAgain(encode(flag), 2 ))if enCodeAgain(encode(flag), 2 ) == correct: print (correct) else : print ('wrong' )