【GWCTF】pyre
收获
关于对 python 的 .pyc 反编译时,uncompyle6 的 python 版本问题
python 中的转义字符 “\x” 的含义
例如:’ \x1f ‘ 代表的是一个 char 字符型,这个字符的 ASCii 码为 0x1F
思路
解压得到 .pyc 文件,用本机 uncompyle6 反编译
提示 python 3.10.4 版本不对
用虚拟机 python 3.8.2 反编译成功
python 3.10.4 反编译经常出问题,可能是兼容性不好,还是建议用虚拟机的 python 3.8
此外,也可以使用在线反编译网站进行反编译
得到代码:
print('Welcome to Re World!')
print('Your input1 is your flag~')
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num
for i in range(l - 1):
code[i] = code[i] ^ code[(i + 1)]
print(code)
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
注意这里 code 的写法:
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
code 是一个列表,而 “\x” 是python 中的转义字符,\x1f 代表值为十六进制 0x1F 所对应的字符
将 code 列表中的字符元素统一转为十六进制:
code = [0x1f, 0x12, 0x1d, 0x28, 0x30, 0x34, 0x01, 0x06, 0x14, 0x34, 0x2C, 0x1b, 0x55, 0x3F,
0x6F, 0x36, 0x2A, 0x3A, 0x01, 0x44, 0x3B, 0x25, 0x13]
逆向代码即可,题目已知最后的 code 列表状态,先通过:
for i in range(l - 1):
code[i] = code[i] ^ code[(i + 1)]
对 code 进行初始化
注意这里,刚开始是通过正向异或得到 code,返回去需要逆向异或,即逆向 for 循环:
for i in reversed(range(0, 22)):
code[i] = code[i] ^ code[(i + 1)]
得到:[71, 88, 74, 87, 127, 79, 123, 122, 124, 104, 92, 112, 107, 62, 1, 110, 88, 114, 72, 73, 13, 54, 19]
然后根据 code 的长度为 23,推测 input1 的长度也为 23
通过正向暴力破解,寻找满足条件:code[i] == ((j + i) % 128 + 128) % 128
的字符,将其输出即可得到 flag
脚本
print('Welcome to Re World!')
print('Your input1 is your flag~')
code = [0x1f, 0x12, 0x1d, 0x28, 0x30, 0x34, 0x01, 0x06, 0x14, 0x34, 0x2C, 0x1b, 0x55, 0x3F,
0x6F, 0x36, 0x2A, 0x3A, 0x01, 0x44, 0x3B, 0x25, 0x13]
for i in reversed(range(0, 22)):
code[i] = code[i] ^ code[(i + 1)]
for i in range(23):
for j in range(32, 127):
if code[i] == ((j + i) % 128 + 128) % 128:
print(chr(j), end='')
break
结果
GWHT{Just_Re_1s_Ha66y!}
评论