0x00 前言 又是get新知识的一天呢
duilib逆向:Duilib逆向分析和按钮事件定位
0x01 pycode 拿到题目附件
是个txt文件 看到代码第一眼愣了一下 没见过
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 1 0 LOAD_CONST 0 (0) 2 LOAD_CONST 1 (('number',)) 4 IMPORT_NAME 0 (Crypto.Util) 6 IMPORT_FROM 1 (number) 8 STORE_NAME 1 (number) 10 POP_TOP 3 12 LOAD_CONST 2 ('8b2e4e858126bc8478d6a6a485215f03') 14 STORE_NAME 2 (enc) 5 16 LOAD_CONST 3 (<code object extract_number at 0x0000020F3AE81DB0, file "1.py", line 5>) 18 LOAD_CONST 4 ('extract_number') 20 MAKE_FUNCTION 0 22 STORE_NAME 3 (extract_number) 13 24 LOAD_CONST 5 (<code object transform at 0x0000020F3AE8F0C0, file "1.py", line 13>) 26 LOAD_CONST 6 ('transform') 28 MAKE_FUNCTION 0 30 STORE_NAME 4 (transform) 24 32 LOAD_NAME 5 (__name__) 34 LOAD_CONST 7 ('__main__') 36 COMPARE_OP 2 (==) 38 POP_JUMP_IF_FALSE 104 26 40 LOAD_NAME 6 (input) 42 LOAD_CONST 8 ('input your number:') 44 CALL_FUNCTION 1 46 STORE_NAME 7 (num) 27 48 LOAD_NAME 8 (bytes) 50 LOAD_METHOD 9 (fromhex) 52 LOAD_NAME 7 (num) 54 CALL_METHOD 1 56 STORE_NAME 10 (tmp) 28 58 LOAD_NAME 4 (transform) 60 LOAD_NAME 10 (tmp) 62 CALL_FUNCTION 1 64 LOAD_METHOD 11 (hex) 66 CALL_METHOD 0 68 STORE_NAME 12 (res) 29 70 LOAD_NAME 2 (enc) 72 LOAD_NAME 12 (res) 74 COMPARE_OP 2 (==) 76 POP_JUMP_IF_FALSE 96 30 78 LOAD_NAME 13 (print) 80 LOAD_CONST 9 ('ok,your flag : DASCTF{{{name}}}') 82 LOAD_ATTR 14 (format) 84 LOAD_NAME 7 (num) 86 LOAD_CONST 10 (('name',)) 88 CALL_FUNCTION_KW 1 90 CALL_FUNCTION 1 92 POP_TOP 94 JUMP_FORWARD 8 (to 104) 32 >> 96 LOAD_NAME 13 (print) 98 LOAD_CONST 11 ('wrong') 100 CALL_FUNCTION 1 102 POP_TOP >> 104 LOAD_CONST 12 (None) 106 RETURN_VALUE Disassembly of <code object extract_number at 0x0000020F3AE81DB0, file "1.py", line 5>: 6 0 LOAD_FAST 0 (x) 2 LOAD_FAST 0 (x) 4 LOAD_CONST 1 (11) 6 BINARY_RSHIFT 8 BINARY_XOR 10 STORE_FAST 0 (x) 7 12 LOAD_FAST 0 (x) 14 LOAD_FAST 0 (x) 16 LOAD_CONST 2 (7) 18 BINARY_LSHIFT 20 LOAD_CONST 3 (2022072721) 22 BINARY_AND 24 BINARY_XOR 26 STORE_FAST 0 (x) 8 28 LOAD_FAST 0 (x) 30 LOAD_FAST 0 (x) 32 LOAD_CONST 4 (15) 34 BINARY_LSHIFT 36 LOAD_CONST 5 (2323163360) 38 BINARY_AND 40 BINARY_XOR 42 STORE_FAST 0 (x) 9 44 LOAD_FAST 0 (x) 46 LOAD_FAST 0 (x) 48 LOAD_CONST 6 (18) 50 BINARY_RSHIFT 52 BINARY_XOR 54 STORE_FAST 0 (x) 10 56 LOAD_FAST 0 (x) 58 RETURN_VALUE Disassembly of <code object transform at 0x0000020F3AE8F0C0, file "1.py", line 13>: 14 0 LOAD_CONST 1 (b'') 2 STORE_FAST 1 (new_message) 15 4 LOAD_GLOBAL 0 (len) 6 LOAD_FAST 0 (m) 8 CALL_FUNCTION 1 10 STORE_FAST 2 (l) 16 12 SETUP_LOOP 82 (to 96) 14 LOAD_GLOBAL 1 (range) 16 LOAD_FAST 2 (l) 18 LOAD_CONST 2 (4) 20 BINARY_FLOOR_DIVIDE 22 CALL_FUNCTION 1 24 GET_ITER >> 26 FOR_ITER 66 (to 94) 28 STORE_FAST 3 (i) 17 30 LOAD_FAST 0 (m) 32 LOAD_FAST 3 (i) 34 LOAD_CONST 2 (4) 36 BINARY_MULTIPLY 38 LOAD_FAST 3 (i) 40 LOAD_CONST 2 (4) 42 BINARY_MULTIPLY 44 LOAD_CONST 2 (4) 46 BINARY_ADD 48 BUILD_SLICE 2 50 BINARY_SUBSCR 52 STORE_FAST 4 (enc) 18 54 LOAD_GLOBAL 2 (number) 56 LOAD_METHOD 3 (bytes_to_long) 58 LOAD_FAST 4 (enc) 60 CALL_METHOD 1 62 STORE_FAST 4 (enc) 19 64 LOAD_GLOBAL 4 (extract_number) 66 LOAD_FAST 4 (enc) 68 CALL_FUNCTION 1 70 STORE_FAST 4 (enc) 20 72 LOAD_GLOBAL 2 (number) 74 LOAD_METHOD 5 (long_to_bytes) 76 LOAD_FAST 4 (enc) 78 LOAD_CONST 2 (4) 80 CALL_METHOD 2 82 STORE_FAST 4 (enc) 21 84 LOAD_FAST 1 (new_message) 86 LOAD_FAST 4 (enc) 88 INPLACE_ADD 90 STORE_FAST 1 (new_message) 92 JUMP_ABSOLUTE 26 >> 94 POP_BLOCK 22 >> 96 LOAD_FAST 1 (new_message) 98 RETURN_VALUE
百度了解过后知道了是python 的字节码,类似汇编的一种东西
推荐相关文章:Python3 字节码详解_sid10t.的博客-CSDN博客_python字节码
对照python官方文档对字节码进行还原,即可拿到python代码
还原出的python代码如下:
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 from Crypto.Util import numberenc = '8b2e4e858126bc8478d6a6a485215f03' def extract_number (x ) : x = x ^ x >> 11 x = x ^ x << 7 & 2022072721 x = x ^ x << 15 & 2323163360 x = x ^ x >> 18 return x def transform (m ): new_message = b'' l = len (m) for i in range (l // 4 ): enc = m[i * 4 : i * 4 + 4 ] enc = number.bytes_to_long············(enc) enc = extract_number(enc) enc = number.long_to_bytes(enc, 4 ) new_message += enc return new_message if __name__ == '__main__' : num = input ("input your number:" ) tmp = bytes .fromhex(num) res = transform(tmp).hex () if enc == res: print ('ok,your flag : DASCTF{{{name}}}' .format (name=num)) else : print ("wrong" )
加密算法是mt算法中提取伪随机数的过程,其中的常数有些许更改
我们从最后一步开始看
1 x1 = x ^ x >> 18 // >> 位运算符
算式中,x的(32-18)位以上异或0即不改变,所以我们就可以知道 x1的高18位(14-32)
x1的15-32位不变
x1的1-14位由x的1-14位与x的18-32位异或所得
官方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 from Crypto.Util import numberdef right_back (e,shift,a ): tmp = e tmp1 = e for i in range (32 //shift): t = (tmp1 >> shift) & a tmp = t ^ tmp tmp1 = t return tmp def left_back (e,shift,a ): tmp = e tmp1 =e for i in range (32 //shift): t = (tmp1 << shift) & a tmp = t ^ tmp tmp1 = t return tmp def convert (e ): e = right_back(e,18 ,0xffffffff ) e = left_back(e,15 ,2323163360 ) e = left_back(e,7 ,2022072721 ) e = right_back(e,11 ,0xffffffff ) return e def transform (message ): assert len (message) % 4 == 0 new_message = b'' for i in range (len (message) // 4 ): block = message[i * 4 : i * 4 +4 ] block = number.bytes_to_long(block) block = convert(block) block = number.long_to_bytes(block) new_message += block return new_message enc = '8b2e4e858126bc8478d6a6a485215f03' enc = bytes .fromhex(enc) flag=transform(enc) print (flag)a = flag print (a.hex ())
贪玩CTF 常规查壳 没有加壳
丢进IDA看一看主函数
只看到一堆duilib调用 没找到啥有用的信息