收获

  • 关于对 python 的 .pyc 反编译时,uncompyle6 的 python 版本问题

  • python 中的转义字符 “\x” 的含义
    例如:’ \x1f ‘ 代表的是一个 char 字符型,这个字符的 ASCii 码为 0x1F


【GWCTF】pyre


思路

解压得到 .pyc 文件,用本机 uncompyle6 反编译

GWCTF-pyre1.png

提示 python 3.10.4 版本不对

用虚拟机 python 3.8.2 反编译成功

GWCTF-pyre2.png

python 3.10.4 反编译经常出问题,可能是兼容性不好,还是建议用虚拟机的 python 3.8

此外,也可以使用在线反编译网站进行反编译

GWCTF-pyre3.png

得到代码:

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 所对应的字符

GWCTF-pyre4.png

将 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!}

GWCTF-pyre5.png