03-【攻防世界】bad_python

题目给了一个Pyc文件,我们使用 uncompyle6 对他进行反编译,但是报错了
Pasted image 20250518232813

用010看一下文件头
可以发现文件头被清零了
Pasted image 20250518232905

那我们就自己给他填上文件头即可,他是用的3.6版本的python,我们也用3.6的python编写一个Pyc文件

使用 pyenv 创一个3.6的python

pyenv install 3.6.0
pyenv shell 3.6.0
┌──(root㉿kali)-[~/Desktop/RE/bad_python]
└─# python -V
Python 3.6.0

建一个py脚本 生成Pyc文件

print(123)

执行命令创建Pyc文件

┌──(root㉿kali)-[~/Desktop/RE/bad_python]
└─# python -m compileall /root/Desktop/RE/bad_python
Listing '/root/Desktop/RE/bad_python'...
Compiling '/root/Desktop/RE/bad_python/create_pyc.py'...

查看16进制

┌──(root㉿kali)-[~/Desktop/RE/bad_python/__pycache__]
└─# xxd create_pyc.cpython-36.pyc 
00000000: 330d 0d0a 34ff 2968 0b00 0000 e300 00030  3...4.)h........
00000010: 0000 0000 0000 0000 0002 0000 0040 0000  .............@..
00000020: 0073 0c00 0000 6500 6400 8301 0100 6401  .s....e.d.....d.
00000030: 5300 2902 e97b 0000 004e 2901 da05 7072  S.)..{...N)...pr
00000040: 696e 74a9 0072 0300 0000 7203 0000 00fa  int..r....r.....
00000050: 292f 726f 6f74 2f44 6573 6b74 6f70 2f52  )/root/Desktop/R
00000060: 452f 6261 645f 7079 7468 6f6e 2f63 7265  E/bad_python/cre
00000070: 6174 655f 7079 632e 7079 da08 3c6d 6f64  ate_pyc.py..<mod
00000080: 756c 653e 0100 0000 7300 0000 00         ule>....s....

把头弄好后就可以反编译了
Pasted image 20250518234543

# uncompyle6 version 3.9.2
# Python bytecode version base 3.6 (3379)
# Decompiled from: Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)]
# Embedded file name: pyre.py
# Compiled at: 2025-05-18 23:39:32
# Size of source mod 2**32: 11 bytes
from ctypes import *
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import long_to_bytes

def encrypt(v, k):
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    sum1 = c_uint32(0)
    delta = 195935983
    for i in range(32):
        v0.value += (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]
        sum1.value += delta
        v1.value += (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]

    return (
     v0.value, v1.value)


if __name__ == "__main__":
    flag = input("please input your flag:")
    k = [255, 187, 51, 68]
    if len(flag) != 32:
        print("wrong!")
        exit(-1)
    a = []
    for i in range(0, 32, 8):
        v1 = bytes_to_long(bytes(flag[i:i + 4], "ascii"))
        v2 = bytes_to_long(bytes(flag[i + 4:i + 8], "ascii"))
        a += encrypt([v1, v2], k)

    enc = [
     4006073346L, 2582197823L, 2235293281L, 558171287, 2425328816L, 
     1715140098, 986348143, 1948615354]
    for i in range(8):
        if enc[i] != a[i]:
            print("wrong!")
            exit(-1)

    print("flag is flag{%s}" % flag)

# okay decompiling .\pyre.cpython-36.pyc

直接叫ai写一个解密脚本就行了

from ctypes import *  
from Cryptodome.Util.number import bytes_to_long, long_to_bytes  
  
def decrypt(v, k):  
    v0 = c_uint32(v[0])  
    v1 = c_uint32(v[1])  
    delta = 195935983  
    sum1 = c_uint32(delta * 32)  # 初始sum值为delta * 32轮  
  
    for i in range(32):  
        # 逆向操作,先解密v1再解密v0  
        v1.value -= (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]  
        sum1.value -= delta  
        v0.value -= (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]  
  
    return (v0.value, v1.value)  
  
def solve():  
    k = [255, 187, 51, 68]  
    enc = [4006073346, 2582197823, 2235293281, 558171287,  
           2425328816, 1715140098, 986348143, 1948615354]  
  
    flag = ""  
    # 每对加密值解密  
    for i in range(0, 8, 2):  
        v0, v1 = decrypt([enc[i], enc[i+1]], k)  
        # 将整数转回字符  
        flag += long_to_bytes(v0).decode('ascii') + long_to_bytes(v1).decode('ascii')  
  
    return flag  
  
if __name__ == "__main__":  
    flag = solve()  
    print("flag is flag{%s}" % flag)

Pasted image 20250519000056