题目给了一个Pyc文件,我们使用 uncompyle6 对他进行反编译,但是报错了
用010看一下文件头
可以发现文件头被清零了
那我们就自己给他填上文件头即可,他是用的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....
把头弄好后就可以反编译了
# 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)