【困难】Python 茶话会
我看 wp ,好多 GPT ,好吧我承认这个题目 GPT 确实可以秒杀,其实我就是想和大家介绍一个在 CTF 中很常见的算法—— TEA。
本题是 TEA 家族中最简单的,原滋原味,如果你想要知道更多,可以去了解一下 XTEA 和 XXTEA 。
题目给了一个 pyd 文件,和一个出题人的友善的 md 提示文件(为了减低难度)。
第一步,pyd 反编译,可以用 pycdc,当然,用在线的网站也可以 在线Python pyc文件编译与反编译 。
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.9
from ctypes import c_uint32
encrypted_flag = [
1887071573,
1987092183,
528573895,
0xAAD682E7L,
1514065471,
1557533937,
2022731508,
0xC695EC0EL,
0xFF36F6EAL,
0xE7B3EC45L,
2120747857,
0xE5D2379DL]
def str_to_ints(s):
return (lambda .0 = None: [ int.from_bytes(s[i:i + 4].encode(), 'little', **('byteorder',)) for i in .0 ])(range(0, len(s), 4))
def ints_to_str(ints):
return ''.join((lambda .0: [ int.to_bytes(i, 4, 'little', **('length', 'byteorder')).decode() for i in .0 ])(ints))
def encrypt(v, k):
v0 = c_uint32(v[0])
v1 = c_uint32(v[1])
sum_val = c_uint32(0)
delta = c_uint32(289739793)
(k0, k1, k2, k3) = (c_uint32(k[0]), c_uint32(k[1]), c_uint32(k[2]), c_uint32(k[3]))
for _ in range(32):
sum_val.value += delta.value
v0.value += (v1.value << 4) + k0.value ^ v1.value + sum_val.value ^ (v1.value >> 5) + k1.value
v1.value += (v0.value << 4) + k2.value ^ v0.value + sum_val.value ^ (v0.value >> 5) + k3.value
return [
v0.value,
v1.value]
def check_flag(text):
if len(text) % 8 != 0:
return False
text_ints = None(text)
encrypted_ints = []
for i in range(0, len(text_ints), 2):
pair = encrypt([
text_ints[i],
text_ints[i + 1]], key)
encrypted_ints.extend(pair)
return encrypted_ints == encrypted_flag
if __name__ == '__main__':
print('👋 Welcome to the Tea Party! ☕️')
print("💡 Hint: Remember to bring your own 'tea' to the party! 🫖 👩🍳")
print('👉 Please enter your secret tea recipe:')
user_input = input()
print('🔍 Let me check your secret tea recipe...')
key = [
305419896,
0x9ABCDEF0L,
0xFEDCBA98L,
1985229328]
if check_flag(user_input):
print("🎉 Your tea recipe is correct! You're the Tea Master now! 🏆")
else:
print("😔 Oops! It seems like you've brought the wrong blend. Try again? ☕️")
反编译有问题的地方,用出题人给的提示,加一点点 python 的经验(如果你想看python的字节码也不是不行),可以恢复为如下的代码:
from ctypes import c_uint32
encrypted_flag = [
1887071573, 1987092183,
528573895, 2866184935,
1514065471, 1557533937,
2022731508, 3331714062,
4281792234, 3887328325,
2120747857, 3855759261
]
# 将字符串转换成整数
def str_to_ints(s):
return [int.from_bytes(s[i:i+4].encode(), byteorder='little') for i in range(0, len(s), 4)]
# 将整数转换回字符串
def ints_to_str(ints):
return ''.join([int.to_bytes(i, length=4, byteorder='little').decode() for i in ints])
# 加密函数
def encrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
sum_val = c_uint32(0)
delta = c_uint32(0x11451411)
k0, k1, k2, k3 = c_uint32(k[0]), c_uint32(k[1]), c_uint32(k[2]), c_uint32(k[3])
for _ in range(32):
sum_val.value += delta.value
v0.value += ((v1.value << 4) + k0.value) ^ (v1.value + sum_val.value) ^ ((v1.value >> 5) + k1.value)
v1.value += ((v0.value << 4) + k2.value) ^ (v0.value + sum_val.value) ^ ((v0.value >> 5) + k3.value)
return [v0.value, v1.value]
# 检查函数
def check_flag(text):
if len(text) % 8 != 0: return False
# 将text转换成整数
text_ints = str_to_ints(text)
# 对每个整数进行加密
encrypted_ints = []
for i in range(0, len(text_ints), 2):
pair = encrypt([text_ints[i], text_ints[i+1]], key)
encrypted_ints.extend(pair)
return encrypted_ints == encrypted_flag
if __name__ == "__main__":
print("👋 Welcome to the Tea Party! ☕️")
print("💡 Hint: Remember to bring your own 'tea' to the party! 🫖 👩🍳")
print("👉 Please enter your secret tea recipe:")
user_input = input()
print("🔍 Let me check your secret tea recipe...")
# 定义密钥
key = [0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x76543210]
if check_flag(user_input):
print("🎉 Your tea recipe is correct! You're the Tea Master now! 🏆")
else:
print("😔 Oops! It seems like you've brought the wrong blend. Try again? ☕️")
接下来,简单的写一个 TEA 解密脚本就可以了:
from ctypes import c_uint32
encrypted_flag = [1887071573, 1987092183, 528573895, 2866184935, 1514065471, 1557533937, 2022731508, 3331714062, 4281792234, 3887328325, 2120747857, 3855759261]
# 将字符串转换成整数
def str_to_ints(s):
return [int.from_bytes(s[i:i+4].encode(), byteorder='little') for i in range(0, len(s), 4)]
# 将整数转换回字符串
def ints_to_str(ints):
return ''.join([int.to_bytes(i, length=4, byteorder='little').decode() for i in ints])
def decrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
sum_val = c_uint32(0x11451411*32)
delta = c_uint32(0x11451411)
k0, k1, k2, k3 = c_uint32(k[0]), c_uint32(k[1]), c_uint32(k[2]), c_uint32(k[3])
for _ in range(32):
v1.value -= ((v0.value << 4) + k2.value) ^ (v0.value + sum_val.value) ^ ((v0.value >> 5) + k3.value)
v0.value -= ((v1.value << 4) + k0.value) ^ (v1.value + sum_val.value) ^ ((v1.value >> 5) + k1.value)
sum_val.value -= delta.value
return [v0.value, v1.value]
if __name__ == "__main__":
key = [0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x76543210]
decrypted_ints = []
for i in range(0, len(encrypted_flag), 2):
decrypted_ints.extend(decrypt([encrypted_flag[i], encrypted_flag[i+1]], key))
decrypted_flag = ints_to_str(decrypted_ints)
print("Decrypted flag:", decrypted_flag)
运行结果:nex{7ime_F0R_@_Tea_PARTY_W1TH_pyth0n_Bytec0de!!}