2023 强网杯 re wp
今昔是何年
整理之前wp的时候,发现了这篇文之前像没发过,于是打算水水博客...
dotdot
值得记录的部分就是ILspy保存代码到Visual Studio 、差分故障分析破解AES白盒
差分故障分析破解AES白盒 在之前的文章中已经讲过了,直接贴exp
exp
import phoenixAES
with open('tracefile', 'wb') as t:
t.write("""
D679E5A02E32F14DF5CC278581653274
3879E5A02E32F185F5CC818581703274
4F79E5A02E32F1B5F5CC1B8581F03274
2979E5A02E32F1ADF5CCCC8581533274
3D79E5A02E32F131F5CCEC8581123274
D6E8E5A0C232F14DF5CC271881650A74
D622E5A0A932F14DF5CC274881652174
D674E5A08F32F14DF5CC276981655474
D6FAE5A07532F14DF5CC27C88165C674
D67975A02E8AF14D8CCC2785816532B2
D679E9A02EBBF14DDACC27858165324C
D6796BA02E3EF14DE1CC278581653259
D67924A02EA5F14DF0CC278581653294
D679E5932E32AF4DF5142785C4653274
D679E5BD2E32184DF559278558653274
D679E5152E32F64DF59627859D653274
D679E58F2E329F4DF5DE27858C653274
""".encode('utf8'))
phoenixAES.crack_file('tracefile')
# Last round key #N found:
# EA9F6BE2DF5C358495648BEAB9FCFF81
aes_cip = bytes([97, 147, 49, 123, 248, 150, 224, 0, 165, 39,183, 55, 74, 227, 3, 168])
aes_key = bytes.fromhex("51574232303233486170707947616D65")
print(f"aes_key => {aes_key}")
def deaes(cip:bytes,key:bytes):
from Crypto.Cipher import AES
Set_AES = AES.new(key,AES.MODE_ECB)
m = Set_AES.decrypt(cip)
return m
def enaes(cip:bytes,key:bytes):
from Crypto.Cipher import AES
Set_AES = AES.new(key,AES.MODE_ECB)
m = Set_AES.encrypt(cip)
return m
# m1 = deaes(aes_cip,aes_key)
# print(m1)
license = bytes.fromhex('''00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 0C 02 00 00 00 49 53 79 73 74 65 6D 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 05 01 00 00 00 84 01 53 79 73 74 65 6D 2E 43 6F 6C 6C 65 63 74 69 6F 6E 73 2E 47 65 6E 65 72 69 63 2E 53 6F 72 74 65 64 53 65 74 60 31 5B 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 5D 04 00 00 00 05 43 6F 75 6E 74 08 43 6F 6D 70 61 72 65 72 07 56 65 72 73 69 6F 6E 05 49 74 65 6D 73 00 03 00 06 08 8D 01 53 79 73 74 65 6D 2E 43 6F 6C 6C 65 63 74 69 6F 6E 73 2E 47 65 6E 65 72 69 63 2E 43 6F 6D 70 61 72 69 73 6F 6E 43 6F 6D 70 61 72 65 72 60 31 5B 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 5D 08 02 00 00 00 02 00 00 00 09 03 00 00 00 02 00 00 00 09 04 00 00 00 04 03 00 00 00 8D 01 53 79 73 74 65 6D 2E 43 6F 6C 6C 65 63 74 69 6F 6E 73 2E 47 65 6E 65 72 69 63 2E 43 6F 6D 70 61 72 69 73 6F 6E 43 6F 6D 70 61 72 65 72 60 31 5B 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 5D 01 00 00 00 0B 5F 63 6F 6D 70 61 72 69 73 6F 6E 03 22 53 79 73 74 65 6D 2E 44 65 6C 65 67 61 74 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 09 05 00 00 00 11 04 00 00 00 02 00 00 00 06 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 05 00 00 00 22 53 79 73 74 65 6D 2E 44 65 6C 65 67 61 74 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 03 00 00 00 08 44 65 6C 65 67 61 74 65 07 6D 65 74 68 6F 64 30 07 6D 65 74 68 6F 64 31 03 03 03 30 53 79 73 74 65 6D 2E 44 65 6C 65 67 61 74 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 2B 44 65 6C 65 67 61 74 65 45 6E 74 72 79 2F 53 79 73 74 65 6D 2E 52 65 66 6C 65 63 74 69 6F 6E 2E 4D 65 6D 62 65 72 49 6E 66 6F 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 2F 53 79 73 74 65 6D 2E 52 65 66 6C 65 63 74 69 6F 6E 2E 4D 65 6D 62 65 72 49 6E 66 6F 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 09 08 00 00 00 09 09 00 00 00 09 0A 00 00 00 04 08 00 00 00 30 53 79 73 74 65 6D 2E 44 65 6C 65 67 61 74 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 2B 44 65 6C 65 67 61 74 65 45 6E 74 72 79 07 00 00 00 04 74 79 70 65 08 61 73 73 65 6D 62 6C 79 06 74 61 72 67 65 74 12 74 61 72 67 65 74 54 79 70 65 41 73 73 65 6D 62 6C 79 0E 74 61 72 67 65 74 54 79 70 65 4E 61 6D 65 0A 6D 65 74 68 6F 64 4E 61 6D 65 0D 64 65 6C 65 67 61 74 65 45 6E 74 72 79 01 01 02 01 01 01 03 30 53 79 73 74 65 6D 2E 44 65 6C 65 67 61 74 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 2B 44 65 6C 65 67 61 74 65 45 6E 74 72 79 06 0B 00 00 00 A4 02 53 79 73 74 65 6D 2E 46 75 6E 63 60 33 5B 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 2C 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 2C 5B 53 79 73 74 65 6D 2E 49 6E 74 33 32 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 5D 06 0C 00 00 00 4B 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 0A 06 0D 00 00 00 5D 41 63 74 69 76 69 74 79 53 75 72 72 6F 67 61 74 65 53 65 6C 65 63 74 6F 72 47 65 6E 65 72 61 74 6F 72 54 65 73 74 2C 20 56 65 72 73 69 6F 6E 3D 31 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 6E 75 6C 6C 06 0E 00 00 00 16 53 6F 72 74 65 64 4C 69 73 74 54 65 73 74 2E 50 72 6F 67 72 61 6D 06 0F 00 00 00 03 46 46 46 09 10 00 00 00 04 09 00 00 00 2F 53 79 73 74 65 6D 2E 52 65 66 6C 65 63 74 69 6F 6E 2E 4D 65 6D 62 65 72 49 6E 66 6F 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 48 6F 6C 64 65 72 07 00 00 00 04 4E 61 6D 65 0C 41 73 73 65 6D 62 6C 79 4E 61 6D 65 09 43 6C 61 73 73 4E 61 6D 65 09 53 69 67 6E 61 74 75 72 65 0A 53 69 67 6E 61 74 75 72 65 32 0A 4D 65 6D 62 65 72 54 79 70 65 10 47 65 6E 65 72 69 63 41 72 67 75 6D 65 6E 74 73 01 01 01 01 01 00 03 08 0D 53 79 73 74 65 6D 2E 54 79 70 65 5B 5D 09 0F 00 00 00 09 0D 00 00 00 09 0E 00 00 00 06 14 00 00 00 27 49 6E 74 33 32 20 46 46 46 28 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 29 06 15 00 00 00 2E 53 79 73 74 65 6D 2E 49 6E 74 33 32 20 46 46 46 28 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 29 08 00 00 00 0A 01 0A 00 00 00 09 00 00 00 06 16 00 00 00 07 43 6F 6D 70 61 72 65 09 0C 00 00 00 06 18 00 00 00 0D 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 06 19 00 00 00 2B 49 6E 74 33 32 20 43 6F 6D 70 61 72 65 28 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 29 06 1A 00 00 00 32 53 79 73 74 65 6D 2E 49 6E 74 33 32 20 43 6F 6D 70 61 72 65 28 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 29 08 00 00 00 0A 01 10 00 00 00 08 00 00 00 06 1B 00 00 00 71 53 79 73 74 65 6D 2E 43 6F 6D 70 61 72 69 73 6F 6E 60 31 5B 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39 5D 5D 09 0C 00 00 00 0A 09 0C 00 00 00 09 18 00 00 00 09 16 00 00 00 0A 0B''')
# print(len(license))
fp = open("./new_license","wb")
fp.write(license)
fp.close()
tea_cip = v28 = [
69, 182, 171, 33, 121, 107, 254, 150, 92, 29,
4, 178, 138, 166, 184, 106, 53, 241, 42, 191,
23, 211, 3, 107
]
v10 = [
59, 65, 108, 110, 223, 90, 245, 226, 6, 122,
219, 170, 147, 176, 22, 190, 60, 24, 58, 86,
150, 97, 188, 166, 113, 104, 232, 197, 234, 225,
22, 183, 40, 78, 102, 116
]
#tea
from ctypes import *
def encrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 3735928559
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(0)
for i in range(32):
total.value += delta
v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ ((v1.value>>5) + k1)
v1.value += ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ ((v0.value>>5) + k3)
return v0.value, v1.value
def decrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 3735928559
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v1.value -= ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ ((v0.value>>5) + k3)
v0.value -= ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ ((v1.value>>5) + k1)
total.value -= delta
return v0.value, v1.value
def tea(inp:bytes,key:bytes):
from struct import pack,unpack
k = unpack("<4I",key)
inp_len = len(inp) // 4
value = unpack(f"<{inp_len}I",inp)
res = b""
for i in range(0,inp_len,2):
v = [value[i],value[i+1]]
# x = encrypt(v,k)
x = decrypt(v,k)
res += pack("<2I",*x)
return res
print(len(tea_cip))
inp = bytes(tea_cip)
key = b"WelcomeToQWB2023"
ret = tea(inp,key)
print(ret)
ezre
sm4一眼秒
需要注意的是,我们需要加上填充模式 padding_mode 这个字段,不然下面这段代码梭哈不成功的
from struct import pack,unpack
key1 = 0xEFCDAB8967452301
key2 = 0xEFCDAB8967452301
key = b""
key += pack("<Q",key1) + pack("<Q",key2)
print(key.hex())
cip = pack("<Q",0x7C88631647197506) + pack("<Q",0x4A0D7D3FFF55668B) + pack("<Q",0xDEC2E93F384ED2F5) + pack("<Q",0x3C1FB1746F7F7CDB)
print(cip.hex())
from gmssl.sm4 import CryptSM4, SM4_DECRYPT,SM4_ENCRYPT
sm4 = CryptSM4(padding_mode=1)
sm4.set_key(key, SM4_DECRYPT)
m = sm4.crypt_ecb(cip)
print(m)
fancy
这道题目挺好玩的
解题步骤
修复rust符号表
这里有几种修复方法:
-
flair 制作 rust的sig来修复部分符号表。
-
下载对应版本的rust,用rust语言随便写几个程序,之后bindiff一下,修复部分符号表。
-
xpoint战队的博客,他们使用的是这款工具来修复的rust符号表: https://github.com/h311d1n3r/Cerberus
./cerberus ./fancy -output ./new_fancy # 我是在ubuntu24下进行的,感觉效果不错
算法分析
0x000555555563255 (关闭 aslr地址随机化后的地址) 处的地址对应的函数,是在获取当前的时间,真实的时间戳应该看文件的
加密流程如下:
# 加密流程如下:
# 1、把输入的字符串分别拆分为前后4位并分别放入一个数组中 (inp)
# 2、inp[i]+=key[i%len(key)] for i in range(len(inp))
# 3、enc[i] = random_mp[inp[i]]
# 4、write back
# 加密流程如下:
inp = b""
key = b"C0de_is_fancy"
box = [0x88, 0xE0, 0x09, 0xBE, 0x42, 0xA4, 0x83, 0x34, 0xC1, 0xEA, 0x21, 0x50, 0x4B, 0xC0, 0xD2, 0x30, 0x69, 0x15, 0xB0, 0x18, 0x01, 0x3F, 0x6B, 0x00, 0xEE, 0x97, 0xF5, 0x78, 0x1F, 0x85, 0x68, 0x5E, 0xA0, 0x56, 0xB4, 0x70, 0x48, 0x66, 0x6E, 0xF2, 0x96, 0x8E, 0x16, 0x1D, 0xD1, 0x81, 0x87, 0xA9, 0x19, 0x94, 0xCA, 0xB7, 0x4A, 0x80, 0xFB, 0xE8, 0xAF, 0x14, 0x04, 0x9B, 0x45, 0xDB, 0x60, 0x6D, 0x44, 0xD8, 0xCE, 0x05, 0xFD, 0x7A, 0xF7, 0x3D, 0xE7, 0x17, 0xB9, 0x4E, 0x76, 0xC4, 0xDA, 0x54, 0x99, 0x58, 0x6C, 0x7D, 0xB6, 0x2A, 0x5F, 0xA2, 0xCD, 0xA1, 0x59, 0x91, 0xB3, 0xCF, 0x26, 0xAC, 0x36, 0x9A, 0x25, 0x2F, 0xA6, 0x6A, 0xDF, 0x06, 0x5C, 0xD6, 0xB1, 0x03, 0xD0, 0x1A, 0xE6, 0x20, 0xD3, 0xAB, 0xD5, 0xE1, 0xBC, 0x24, 0x41, 0x9E, 0x37, 0x2D, 0x28, 0x9F, 0x7E, 0x1E, 0xE5, 0xFC, 0xC5, 0x63, 0x8B, 0xB5, 0x11, 0xBF, 0x31, 0xA8, 0x2B, 0x62, 0x7C, 0x8C, 0x4D, 0x93, 0xB2, 0x95, 0x9D, 0xF9, 0xE2, 0x61, 0x35, 0x9C, 0x46, 0xAE, 0x13, 0x98, 0x65, 0x0F, 0xEF, 0x22, 0xA5, 0xBB, 0x00, 0xF0, 0x49, 0x64, 0xDE, 0x8F, 0x67, 0x3A, 0x71, 0x0D, 0x47, 0x77, 0xD7, 0xBD, 0xC7, 0xCB, 0xF6, 0x79, 0x73, 0x51, 0xC9, 0x43, 0x1C, 0xA3, 0xAD, 0x3C, 0x89, 0x72, 0x29, 0xAA, 0xF1, 0x7F, 0x84, 0xED, 0xC6, 0xFE, 0xA7, 0x1B, 0x90, 0xE4, 0xC3, 0xB8, 0xBA, 0x38, 0x2C, 0x0A, 0x02, 0xE9, 0x86, 0x7B, 0x74, 0xE3, 0xF4, 0xC8, 0xD4, 0xDD, 0xDC, 0xC2, 0x32, 0xF8, 0x23, 0x75, 0x33, 0x0B, 0x27, 0x4C, 0xEC, 0x92, 0x6F, 0x4F, 0xD9, 0x0E, 0x2E, 0x57, 0x5D, 0x12, 0x53, 0xEB, 0xCC, 0xF3, 0x07, 0x5B, 0x0C, 0x08, 0x40, 0x55, 0x10, 0x82, 0x3B, 0x52, 0x39, 0x8D, 0xFA, 0x5A, 0x8A, 0x3E]
new_inp_data = []
for i in range(len(inp)):
bdata = inp[i]
b1 = bdata // 10
b2 = bdata % 10
new_inp_data.append(b1)
new_inp_data.append(b2)
fin_cip = []
for i in range(len(new_inp_data)):
inp_add_nkey = new_inp_data[i] + key[i%len(key)]
chh = box[inp_add_nkey]
fin_cip.append(chh)
# fp = open("./cipher","wb")
# fp.write(bytes(fin_cip))
# fp.close()
exp
# 解密流程如下
key = b"C0de_is_fancy"
box = [0x88, 0xE0, 0x09, 0xBE, 0x42, 0xA4, 0x83, 0x34, 0xC1, 0xEA, 0x21, 0x50, 0x4B, 0xC0, 0xD2, 0x30, 0x69, 0x15, 0xB0, 0x18, 0x01, 0x3F, 0x6B, 0x00, 0xEE, 0x97, 0xF5, 0x78, 0x1F, 0x85, 0x68, 0x5E, 0xA0, 0x56, 0xB4, 0x70, 0x48, 0x66, 0x6E, 0xF2, 0x96, 0x8E, 0x16, 0x1D, 0xD1, 0x81, 0x87, 0xA9, 0x19, 0x94, 0xCA, 0xB7, 0x4A, 0x80, 0xFB, 0xE8, 0xAF, 0x14, 0x04, 0x9B, 0x45, 0xDB, 0x60, 0x6D, 0x44, 0xD8, 0xCE, 0x05, 0xFD, 0x7A, 0xF7, 0x3D, 0xE7, 0x17, 0xB9, 0x4E, 0x76, 0xC4, 0xDA, 0x54, 0x99, 0x58, 0x6C, 0x7D, 0xB6, 0x2A, 0x5F, 0xA2, 0xCD, 0xA1, 0x59, 0x91, 0xB3, 0xCF, 0x26, 0xAC, 0x36, 0x9A, 0x25, 0x2F, 0xA6, 0x6A, 0xDF, 0x06, 0x5C, 0xD6, 0xB1, 0x03, 0xD0, 0x1A, 0xE6, 0x20, 0xD3, 0xAB, 0xD5, 0xE1, 0xBC, 0x24, 0x41, 0x9E, 0x37, 0x2D, 0x28, 0x9F, 0x7E, 0x1E, 0xE5, 0xFC, 0xC5, 0x63, 0x8B, 0xB5, 0x11, 0xBF, 0x31, 0xA8, 0x2B, 0x62, 0x7C, 0x8C, 0x4D, 0x93, 0xB2, 0x95, 0x9D, 0xF9, 0xE2, 0x61, 0x35, 0x9C, 0x46, 0xAE, 0x13, 0x98, 0x65, 0x0F, 0xEF, 0x22, 0xA5, 0xBB, 0x00, 0xF0, 0x49, 0x64, 0xDE, 0x8F, 0x67, 0x3A, 0x71, 0x0D, 0x47, 0x77, 0xD7, 0xBD, 0xC7, 0xCB, 0xF6, 0x79, 0x73, 0x51, 0xC9, 0x43, 0x1C, 0xA3, 0xAD, 0x3C, 0x89, 0x72, 0x29, 0xAA, 0xF1, 0x7F, 0x84, 0xED, 0xC6, 0xFE, 0xA7, 0x1B, 0x90, 0xE4, 0xC3, 0xB8, 0xBA, 0x38, 0x2C, 0x0A, 0x02, 0xE9, 0x86, 0x7B, 0x74, 0xE3, 0xF4, 0xC8, 0xD4, 0xDD, 0xDC, 0xC2, 0x32, 0xF8, 0x23, 0x75, 0x33, 0x0B, 0x27, 0x4C, 0xEC, 0x92, 0x6F, 0x4F, 0xD9, 0x0E, 0x2E, 0x57, 0x5D, 0x12, 0x53, 0xEB, 0xCC, 0xF3, 0x07, 0x5B, 0x0C, 0x08, 0x40, 0x55, 0x10, 0x82, 0x3B, 0x52, 0x39, 0x8D, 0xFA, 0x5A, 0x8A, 0x3E]
fp = open("./cipher","rb")
AllData = fp.read()
length = len(AllData)
inp = []
for i in range(0,length,2):
b1 = AllData[i]
b2 = AllData[i+1]
idx1 = box.index(b1)
idx2 = box.index(b2)
d1 = idx1 -key[i%len(key)]
d2 = idx2 -key[(i+1)%len(key)]
inp.append(d1*0x10 + d2)
print(bytes(inp))
mpp = [0] * 257
for i in box:
mpp[i]+=1
print(mpp)
第二种做法
参考 Arr3stY0u 战队的wp,解题者直接发现了密文与输入之间的关系,进而进行逐字节爆破
师傅的hook手段是一大亮点:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <dlfcn.h>
#include <time.h>
typedef int (*PFN_clock_gettime)(clockid_t clock_id, struct timespec *tp);
int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
void *handle = dlopen("libc.so.6", RTLD_LAZY);
PFN_clock_gettime real = (PFN_clock_gettime)dlsym(handle, "clock_gettime");
int res = real(clock_id, tp);
int ts = atoi(getenv("TS_VALUE"));
tp->tv_sec = ts;
// printf("clock_gettime: %ld\n", tp->tv_sec);
return res;
}
// gcc hook.c -shared -o hook.so
根据下面exp,可以看到,爆破的时候就是通过向system函数中传入 TS_VALUE={correct_ts} LD_PRELOAD=./hook.so ./fancy --input=1.bin 字符串命令来爆破的
import os
enc_flag = open('./cipher_', 'rb').read()
ts_start = 1702565186 # 密文文件的时间戳
correct_ts = 0
for off in range(0, -10, -1):
ts = ts_start + off
for ch in range(0x20, 0x80, 0x10):
open('./1.bin', 'wb').write(bytes([ch]))
# time.sleep(0.5)
os.system(f'TS_VALUE={ts} LD_PRELOAD=./hook.so ./fancy --input=1.bin')
# time.sleep(0.5)
cipher = open('./cipher', 'rb').read()
if cipher[0] == enc_flag[0]:
print('correct_ts: ', ts, hex(cipher[0]), hex(ch))
correct_ts = ts
break
# correct_ts: 1702565185 0x3d 0x40
if not correct_ts:
print('???')
exit(0)
flag = b''
size = len(enc_flag) // 2
for idx in range(size-0x30, size): # 跳过前言
# 先爆破高位
for high in range(0x20, 0x80, 0x10):
open('./1.bin', 'wb').write(b'A'*idx+bytes([high]))
os.system(f'TS_VALUE={correct_ts} LD_PRELOAD=./hook.so ./fancy --input=1.bin')
cipher = open('./cipher', 'rb').read()
if cipher[idx*2] == enc_flag[idx*2]:
# print(f'high: {high:02X}')
break
# 再爆破低位
for low in range(0x10):
open('./1.bin', 'wb').write(b'A'*idx+bytes([low]))
os.system(f'TS_VALUE={correct_ts} LD_PRELOAD=./hook.so ./fancy --input=1.bin')
cipher = open('./cipher', 'rb').read()
if cipher[idx*2+1] == enc_flag[idx*2+1]:
# print(f'low: {low:02X}')
break
flag += bytes([high|low])
print('\r'+flag.decode())
实际上可以直接单字节爆破
我根据师傅的hook方法,重写了一份爆破脚本:
import os
fp = open("./cipher1","rb")
cip = fp.read()
fp.close()
flag_len = len(cip) // 2
blast_flag =bytearray(b"X"* flag_len)
correct_ts = 1702565185
for idx in range(flag_len):
for ch in range(0x20,0x80):
blast_flag[idx] = ch
fp = open("./111.bin","wb")
fp.write(blast_flag)
fp.close()
os.system(f'TS_VALUE={correct_ts} LD_PRELOAD=./hook.so ./fancy --input=111.bin')
fp = open("./cipher","rb")
cip_mid = fp.read()
fp.close()
if cip_mid[idx*2:idx*2+2] == cip[idx*2:idx*2+2]:
print(blast_flag)
break
else:
continue
print(blast_flag)
结果如下:
...
unname
逆了一下午写出的exp脚本找不到了。。
依稀记得,主要是逆向这一段代码,其他没什么技巧可言,只能硬逆
我一个师弟逆向的代码:
优雅至极
xrtFuze
这道题很费时间。
看着像vm,但不好写vm解析器,考虑再三后,我选择用gdb硬调,通过不断的下watchpoint,监视输入字符串的内存读写与转移情况,并手动记录监视的trace:
在长达10个小时的人工trace后,得到了这个:
flag{0123456789abcdef}
1、pc: 0x804ac49 、 mem: 0x8068320
awatch *(int*)0x8068320
2、pc: 0x8048def-1 、 mem: 0x80683b4
3、pc: 0x804922a-1 、 mem: 0x80683b4(no) <= xor edx, ecx (0x2b)
特殊操作:
0x8049241 xor edx, ecx
其中 edx来自:
pwndbg> x /10wx 0x80683bc
0x80683bc: 0x0000001b 0x000000c6 0x00000001 0x00000000
0x80683cc: 0x00000000 0x00000000 0x00000000 0x00000000
0x80683dc: 0x00000000 0x08068880
而ecx就是我们的输入 0x30
4、pc: 0x804a4ca-1 、 mem: 0x80683b4(no)
5、pc: 0x8048ec2-1 、 mem: 0x806b890 <= 0x2a
6、pc: 0x80683b4-1 、 delete mem: 0x80683b4
###################################### 自定义的简单异或操作 ######################################
7、pc: 0x80683b4-1、mem:0x80683b4 <= 0x31
8、pc: 0x804922a-1、 mem:0x80683b4(no) <= 0x60
0x8049241 xor edx, ecx
其中edx来自:
pwndbg> x /10wx 0x80683bc
0x80683bc: 0x00000051 0x000000b0 0x00000002 0x00000001
0x80683cc: 0x00000000 0x000000c6 0x00000000 0x00000001
0x80683dc: 0x00000000 0x08068880
ecx就是我们输入的 0x31
9、pc: 0x804a4ca-1 、 mem: 0x80683b4(no) <= 0x60
10、pc: 0x8048ec2 -1 、mem: 0x806b890+1 <= 0x60
11、pc: 0x80683b4-1 、 delete mem: 0x80683b4
12、pc: 0x8048def-1、mem:0x80683b4 <= 0x32
13、pc: 0x804922a-1、 mem:0x80683b4(no) <= 0x1d
0x8049241 xor edx, ecx ==> 0x1d
其中edx来自:
pwndbg> x /10wx 0x80683bc
0x80683bc: 0x0000002f 0x00000025 0x00000003 0x00000002
0x80683cc: 0x00000000 0x000000b0 0x00000000 0x00000002
0x80683dc: 0x00000000 0x08068880
ecx就是我们输入的 0x32
14、pc: 0x804a4ca-1 、 mem: 0x80683b4(no) <= 0x1d
15、pc: 0x8048ec2 -1 、mem: 0x806b890+2 <= 0x1d
16、pc: 0x804a5f5-1 、 delete mem: 0x80683b4
17、pc: 0x8048def-1 、 mem: 0x80683b4 <= 0x33
从这里开始切换断点
bc
b *0x804923F
awatch *(long long int*)0x806b890
18、
xor 0x33,0xf3 => 0xc0
19、
xor 0x34, xx=> 0x9d
20、
xor 0x35, xx => 0xfb
21、
xor 0x36, xx => 0xca
22、
xor 0x37, xx => 0x33
23、
xor 0x38, xx => 0x7a
24、
xor 0x39, xx => 0x79
25、
xor 0x61, xx => 0x8d
26、
xor 0x62, xx => 0x79
27、
xor 0x63, xx => 0x19
28、
xor 0x64, xx => 0xb4
29、
xor 0x65, xx => 0xef
30、
xor 0x66, xx => 0x8c
pwndbg> x /16bx 0x806b890
0x806b890: 0x2b 0x60 0x1d 0xc0 0x9d 0xfb 0xca 0x33
0x806b898: 0x7a 0x79 0x8d 0x79 0x19 0xb4 0xef 0x8c
###################################### 自定义的简单异或操作 ######################################
###################################### 大小端转化 ######################################
31、
pc: 0x8048def-1 、 mem: 0x8068420 <= 0xc0
awatch *(int*)0x8068420
32、
pc: 0x8048df4-1 、mem: 0x8068420(no) <= 0xc0
call_back
33、
pc: 0x804a635-1 、 mem: 0x8068420(no) <= 0xc0
34、
pc: 0x8048df4-1、 mem: 0x8068440 <= 0x1d
35、
pc: 0x804a635-1、 mem: 0x8068440 <= 0x1d
36、
pc: 0x80493c1-1、mem: 0x8068440 <= 0x1d00
0x80493c9 shl ebx, cl => 0x1d00
其中ebx是0x1d,cl是0x8
37、0x804927f
pc: 0x804927f-1 、mem: 0x8068420 <= 0x1dc0
0x8049296 or edx, ecx => 0x1dc0
其中edx是 0x1d00,ecx是0xc0
38、 d mem: 0x8068420
40、
pc: 0x8048dec、 rmem: 0x806b890+0x1(0x60) 、wmem: 0x8068440 <= 0x60
41、
pc: 0x8048df4-1、wmem: 0x8068440 <= 0x60
42、
43、
44、
pc: 0x80493c1-1、wmem:0x8068440 <= 0x600000
0x80493c9 shl ebx, cl
ebx: 0x60、 ecx: 0x10 ==> 0x600000
45、0x804927f-1: wmem: 0x8068420 <=== 0x601dc0
► 0x8049296 or edx, ecx
or 0x600000,0x1dc0 ==> 0x601dc0
46、
0x8048dec; rmem: 0x806b890+0x0(0x2b) ; wmem: 0x8068440
47、
0x80493c1 ; wmem(0x8068440) <=== 0x2b000000
0x80493c9 shl ebx, cl
shl 0x2b,0x18 ===> 0x2b000000
48、
0x804927f ; wmem(0x8068420) <=== 0x2b601dc0
0x8049296 or edx, ecx ==> 0x2b601dc0
or 0x2b000000 , 0x601dc0 ==> 0x2b601dc0
49、
0x8048d1c ; wmem(0x806bc70) <== 0x2b601dc0
50、
delete mem(0x8068420)
51、
delete mem(0x8068440)
52、
0x8048dec ; rmem(0x806b890 + 0x7) : 0x33 ; wmem(0x8068420) <= 0x33
awatch 0x8068420
53、
54、
55、
call_back
56、
57、
0x8048dec; rmem(0x806b890 + 0x6) : 0xca ; wmem(0x8068440) <= 0xca
58、
shl ebx, cl => 0x1d00
shl 0xca,0x8 ==> 0xca00
59、
0x804927f ;
0x8049296 or edx, ecx
or 0xca00 , 0x33 ==》 0xca33
60、
61、
62、
0x8048dec; rmem(0x806b890 + 0x5) : 0xfb ; wmem(0x8068440) <= 0xfb
awatch *(int*)0x8068440
63、
64、
65、
0x80493c1; wmem(0x8068440) <= 0xfb0000
0x80493c9 shl ebx, cl
shl 0xfb , 0x10 ==> 0xfb0000
66、
0x804927f ; wmem(0x8068420) <= 0xfbca33
0x8049296 or edx, ecx
or 0xfb0000,0xca33 => 0xfbca33
67、
0x8048dec; rmem(0x806b890 + 0x4) : 0x9d ; wmem(0x8068440) <= 0x9d
68、
0x80493c1 ; rmem(0x8068440) <= 0x9d000000
0x80493c9 shl ebx, cl
shl 0x9d,0x18 => 0x9d000000
69、
0x804927f ; wmem(0x8068420) <=0x9dfbca33
0x8049296 or edx, ecx
or 0x9d000000 , 0xfbca33 ==> 0x9dfbca33
70、
0x8048d1c; rmem(0x806bc70 + 0x4) <= 0x9dfbca33
bc
再次下断点:
26 acc watchpoint keep y *(long long int *)0x806bc70
27 acc watchpoint keep y *(long long int *)0x806bc78
之后
c
c
数据全部写入 0x806bc70 后
pwndbg> x /4wx 0x806bc70
0x806bc70: 0x2b601dc0 0x9dfbca33 0x7a798d79 0x19b4ef8c
flag{0123456789abcdef}
###################################### 大小端转化结束 ######################################
71、
0x8048d85; wmem(0x806bc0c) <= 0x2b601dc0
awatch *(int*)0x806bc0c
72、0x8048d85; wmem(0x806bc0c + 0x10) <= 0x9dfbca33
73、0x804a7c4 ; wmem(0x806bc0c + 0x4) <= 0x9dfbca33
74、。。
75、。。
----------------------------------------------------- tea -----------------------------------------------------
----------------------------------------------------- tea -----------------------------------------------------
----------------------------------------------------- tea -----------------------------------------------------
pwndbg> bl
Num Type Disp Enb Address What
6 acc watchpoint keep y *(long long int*)0x806bc08
7 acc watchpoint keep y *(long long int*)0x806bc10
pwndbg> x /10wx 0x806bc00
0x806bc00: 0x00000000 0x57429f48 0x2b601dc0 0x2b601dc0
0x806bc10: 0x9dfbca33 0x9dfbca33 0x00000000 0x00000000
0x806bc20: 0x00000000 0x00000000
76、
0x80493c1 ; wmem(0x806bbf4) <= 0xdfbca330
0x80493c9 shl ebx, cl
shl 0x9dfbca33,0x4 ==> 0xdfbca330
77、
0x8048fb2; wmem(0x806bbf4) <= 0x313fbc6
0x8048fc9 add edx, ecx
add 0x23575896(maby Native),0xdfbca330 ===> 0x313fbc6
0xf53e697b
78、
0x8048fb2; wmem(0x806bc00) <==0xf53e697b
0x8048fc9 add edx, ecx
add 0x57429f48,0x9dfbca33 ==> 0xf53e697b
79、
0x804922a; wmem(0x806bbf4) <===0xf62d92bd
0x8049241 xor edx, ecx
xor 0xf53e697b,0x313fbc6 ==> 0xf62d92bd
80、
0x8049376; wmem(0x806bc00) <== 0xfcefde51
0x804937e sar ebx, cl
sar 0x9dfbca33 ,0x5 ==> 0xfcefde51
81、
0x8048fb2; wmem(0x806bc00) <==0x86552379
0x8048fc9 add edx, ecx
add 0x89654528(N),0xfcefde51 ==> 0x86552379
82、
0x804922a; wmem(0x806bbf4) <==0x7078b1c4
0x8049241 xor edx, ecx
xor 0x86552379,0xf62d92bd => 0x7078b1c4
83、
0x8048fb2; wmem(0x806bc00) <==0x9bd8cf84
0x8048fc9 add edx, ecx
add 0x7078b1c4,0x2b601dc0 ==> 0x9bd8cf84
84、
d mem 0x806bbf4
85、
0x80493c1; wmem(0x806bbf4) <=0xbd8cf840
0x80493c9 shl ebx, cl
shl 0x9bd8cf84,0x4 ==> 0xbd8cf840
86、
0x8048c3c; wmem(0x806bbf4) <==0xcfe51d88
0x8048c53 add edx, ecx
add 0x12582548,0xbd8cf840 ==> 0xcfe51d88
87、
0x8048fb2; wmem(0x806bbfc) <==0xf31b6ecc
0x8048fc9 add edx, ecx
add 0x57429f48,0x9bd8cf84 ==> 0xf31b6ecc
88、
0x804922a; wmem(0x806bbf4) <==0x3cfe7344
0x8049241 xor edx, ecx
xor 0xf31b6ecc,0xcfe51d88 => 0x3cfe7344
89、
0x8049376; wmem(0x806bbfc) <== 0xfcdec67c
0x804937e sar ebx, cl
sar 0x806bbfc ,0x5 ==> 0xfcdec67c
90、
0x8048c3c; wmem(0x806bbfc) <==0x42683ed2
0x8048c53 add edx, ecx
add 0x45897856,0xfcdec67c ==> 0x42683ed2
91、
0x804922a; wmem(0x806bbf4) <==0x7e964d96
0x8049241 xor edx, ecx
xor 0x42683ed2,0x3cfe7344 => 0x7e964d96
92、
0x8048fb2; wmem(0x806bbfc) <==0x1c9217c9
0x8048fc9 add edx, ecx
add 0x7e964d96,0x9dfbca33 ==> 0x1c9217c9
93、
d mem 0x806bbf4
94、
0x804a7c4 ; wmem(0x806bc08) <= 0x9bd8cf84
awatch *(int*)0x806bc08
95、
0x804a7c4 ; wmem(0x806bc10) <== 0x1c9217c9
----------------------------------------------------- tea -----------------------------------------------------
----------------------------------------------------- tea -----------------------------------------------------
----------------------------------------------------- tea -----------------------------------------------------
###################################################### 大小端转化 ##########################################################
96、
0x80490fd; wmem(0x8068440) <== 0x79
0x8049104 and edx, ecx
and 0xff , 0x7a798d79 ==> 0x79
97、
98、
0x8048ec2; wmem(0x806bcd8+3) <== 0x79
99、
0x8049376; wmem(0x8068440) <== 0x7a798d
0x804937e sar ebx, cl
sar 0x7a798d79 ,0x8 ==> 0x7a798d
100、
0x80490fd; wmem(0x8068440) <== 0x8d
0x8049104 and edx, ecx
and 0xff , 0x7a798d ==> 0x8d
101、
0x806bcda ; wmeme(0x806bcd8+2) <=== 0x8d
102、
0x8048d85 ; wmem(0x8068440) <= 0x7a798d79
103、
0x8049376; wmem(0x8068440) <== 0x7a798d
0x804937e sar ebx, cl
sar 0x7a798d79 ,0x10 ==> 0x7a79
104、
0x8048ec2; wmem(0x806bcd8+1) <== 0x79
105、
0x8048ec2; wmem(0x806bcd8+0) <== 0x7a
106、
0x8048d85 ; wmem(0x8068440) <= 0x19b4ef8c
107、
0x8049376; wmem(0x8068440) <== 0x19b4ef
0x804937e sar ebx, cl
sar 0x19b4ef8c ,0x8 ==> 0x19b4ef
108、
0x80490fd; wmem(0x8068440) <== 0xef
0x8049104 and edx, ecx
and 0xff , 0x19b4ef ==> 0xef
109、
0x8048ec2 ; wmem(0x806bcd8+4+3) <== 0x8c
0x8048ec2 ; wmem(0x806bcd8+4+2) <== 0xef
0x8048ec2 ; wmem(0x806bcd8+4+2) <== 0xb4
0x8048ec2 ; wmem(0x806bcd8+4+0) <== 0x19
与上面那个类似
###################################################### 大小端转化结束 ##########################################################
flag{0123456789abcdef}
----------------------------------------------------- 与密文做比较 -----------------------------------------------------
pwndbg> x /32bx 0x806bcd0
0x806bcd0: 0x92 0xa2 0x9d 0x26 0xad 0xf6 0xcb 0x41
0x806bcd8: 0x7a 0x79 0x8d 0x79 0x19 0xb4 0xef 0x8c
0x806bce0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x806bce8: 0x00 0x00 0x00 0x00 0x11 0x00 0x00 0x00
110、
0x8048def; rmem(0x8068350) <= 0x92
111、
0x8048ec2; rmem(0x806bd60) <= 0x92
112、
0x8048def; rmem(0x8068350) <= 0x8
113、
0x8048ec2; rmem(0x806bd60) <= 0xa2
114、
0x8048def; rmem(0x8068424) <= 0x92
115、0x804aa12
0x804aa26 cmp edx, eax
cmp 0x92,0x9c
115、0x804aa12
0x804aa26 cmp edx, eax
cmp 0xa2,0x6c
116、
cmp 0x9d,0x48
117、
cmp 0x26,0x16
118、
cmp 0xad,0x70
119、
cmp 0xf6,0x12
120、
cmp 0xcb,0x5a
121、
cmp 0x41,0x2d
122、
cmp 0x49,0xe1
123、
cmp 0x79,0xd7
124、
cmp 0xe8,0xf5
125、
cmp 0x68,0x7c
126、
cmp 0xe3,0xc5
127、
cmp 0x12,0x46
128、
cmp 0x31,0x32
129、
cmp 0x8a,0x68
----------------------------------------------------- 与密文做比较 -----------------------------------------------------
###################################################### 另外八字节进行另一种魔改tea加密 ######################################################
# 这里一开始dbg的时候没有发现,后来才发现的,所以补到后面来了
0x7a 0x79 0x8d 0x79 0x19 0xb4 0xef 0x8c
===> reverse
0x79 0x8d 0x79 0x7a
79 8d 79 7a
130、
0x8048d85; wmem(0x806bc0c) <== 0x7a798d79
131、
0x804a7c4; wmem(0x806bc08) <= 0x7a798d79
132、
0x8048fb2; wmem(0x806bc00) <= 0xbedcc09f
0x8048fc9 add edx, ecx
add 0x44633326(maby Native),0x7a798d79 ===> 0xbedcc09f
add 0x687a58d5 ,0x7a304d91 ==> 0xe2aaa666
133、
0x80493c1; wmem(0x806bbf4) <=0xbd8cf840
0x80493c9 shl ebx, cl
shl 0xbedcc09f,0x4 ==> 0xedcc09f0
134、
0x8048c3c; wmem(0x806bbf4) <==0x242f38
0x8048c53 add edx, ecx
add 0x12582548(k0),0xedcc09f0 ==> 0x242f38
135、
0x8048fb2; wmem(0x806bc00) <= 0x161f5fe7
0x8048fc9 add edx, ecx
add 0x57429f48 ,0xbedcc09f ===> 0x161f5fe7
136、
0x804922a; wmem(0x806bbf4) <==0x163b70df
0x8049241 xor edx, ecx
xor 0x161f5fe7,0x242f38 => 0x163b70df
137、
0x8049376; wmem(0x806bbfc) <== 0xfdf6e604
0x804937e sar ebx, cl
sar 0xbedcc09f ,0x5 ==> 0xfdf6e604
146、
0x8048c3c; wmem(0x806bbfc) <==0x43805e5a
0x8048c53 add edx, ecx
add 0x45897856(k1),0xfdf6e604 ==> 0x43805e5a
147、
0x804922a; wmem(0x806bbf4) <==0x55bb2e85
0x8049241 xor edx, ecx
xor 0x43805e5a,0x163b70df => 0x55bb2e85
148、
0x8048fb2; wmem(0x806bbfc) <= 0x6f701e11
0x8048fc9 add edx, ecx
add 0x55bb2e85 ,0x19b4ef8c ===> 0x6f701e11
149、
0x804a7c4; wmem(0x806bc10) <= 0x6f701e11
150、
0x80493c1; wmem(0x806bbf4) <=0xf701e110
0x80493c9 shl ebx, cl
shl 0x6f701e11,0x4 ==> 0xf701e110
151、
0x8048fb2; wmem(0x806bbf4) <= 0x1a5939a6
0x8048fc9 add edx, ecx
add 0x23575896(k2) ,0xf701e110 ===> 0x1a5939a6
152、
0x8048fb2; wmem(0x806bc00) <= 0x1df55ca1
0x8048fc9 add edx, ecx
add 0xae853e90 ,0x6f701e11(v0) ===> 0x1df55ca1
153、
0x804922a; wmem(0x806bbf4) <==0x7ac6507
0x8049241 xor edx, ecx
xor 0x1df55ca1,0x1a5939a6 => 0x7ac6507
154、
0x8049376; wmem(0x806bc00) <== 0x37b80f0
0x804937e sar ebx, cl
sar 0x6f701e11 ,0x5 ==> 0x37b80f0
155、
0x8048fb2; wmem(0x806bc00) <= 0x8ce0c618
0x8048fc9 add edx, ecx
add 0x89654528(k3) ,0x37b80f0 ===> 0x8ce0c618
156、
0x804922a; wmem(0x806bbf4) <==0x7ac6507
0x8049241 xor edx, ecx
xor 0x8ce0c618,0x7ac6507 => 0x8b4ca31f
157、
0x8048fb2; wmem(0x806bc00) <= 0x4a2963be
0x8048fc9 add edx, ecx
add 0x8b4ca31f ,0xbedcc09f ===> 0x4a2963be
158、
0x80493c1; wmem(0x806bbf4) <=0xa2963be0
0x80493c9 shl ebx, cl
shl 0x4a2963be,0x4 ==> 0xa2963be0
159、
0x8048c3c; wmem(0x806bbf4) <==0xb4ee6128
0x8048c53 add edx, ecx
add 0x12582548(k0),0xa2963be0 ==> 0xb4ee6128
160、
0x8048fb2; wmem(0x806bbfc) <= 0xf8aea24e
0x8048fc9 add edx, ecx
add 0xae853e90 ,0x4a2963be ===> 0xf8aea24e
161、
0x804922a; wmem(0x806bbf4) <==0x4c40c366
0x8049241 xor edx, ecx
xor 0xf8aea24e,0xb4ee6128 => 0x4c40c366
162、
0x8049376; wmem(0x806bbfc) <== 0x2514b1d
0x804937e sar ebx, cl
sar 0x4a2963be ,0x5 ==> 0x2514b1d
...
...
...
###################################################### 另外八字节进行另一种魔改tea加密结束 ######################################################
通过逆向即可知道,程序主要是进行了一次异或、两次不同的魔改tea加密操作
加密逻辑如下:
from ctypes import *
from struct import pack,unpack
def dec1(inp:bytes):
xor_list = [0x0000001b,0x00000051,0x0000002f,0xf3,0x34^0x9d,0x35^0xfb,0x36^0xca,0x37^0x33,0x38^0x7a,0x39^0x79,0x61^0x8d,0x62^0x79,0x63^0x19,0x64^0xb4,0x65^0xef,0x66^0x8c]
# [0x1b,0x51,0x2f,0xf3,0xa9,0xce,0xfc,0x4,0x42,0x40,0xec,0x1b,0x7a,0xd0,0x8a,0xea]
assert len(xor_list) == 16
for i in xor_list:
print(hex(i),end = ",")
print()
x = bytearray(inp)
for i in range(len(x)):
x[i] ^= xor_list[i]
return bytes(x)
def Rshift(m:int,cnt:int):
if m & 0x80000000 != 0:
x = 0xffffffff
x <<= (32-cnt)
x &= 0xffffffff
return (m >> cnt) | x
else:
return m >> cnt
def encrypt1(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
print(0,": ",hex(v0.value),hex(v1.value))
total = c_uint32(0)
for i in range(32):
total.value += delta
v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
v1.value += ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
# print(i+1,": ",hex(v0.value),hex(v1.value))
return v0.value, v1.value
def decrypt1(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v1.value -= ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
v0.value -= ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
total.value -= delta
return v0.value, v1.value
def encrypt2(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
print(0,": ",hex(v0.value),hex(v1.value))
total = c_uint32(0)
for i in range(32):
total.value += delta
v1.value += ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
print(i+1,": ",hex(v0.value),hex(v1.value))
# v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
# print(32,": ",hex(v0.value),hex(v1.value))
return v0.value, v1.value
def decrypt2(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v0.value -= ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
v1.value -= ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
total.value -= delta
return v0.value, v1.value
def tea1(inp:bytes,key:bytes):
from struct import pack,unpack
k = unpack("<4I",key)
inp_len = len(inp) // 4
# print(inp_len)
value = unpack(f"<{inp_len}I",inp)
res = b""
for i in range(0,inp_len,2):
v = [value[i],value[i+1]]
x = encrypt1(v,k)
# x = decrypt1(v,k)
res += pack("<2I",*x)
return res
def tea2(inp:bytes,key:bytes):
from struct import pack,unpack
k = unpack("<4I",key)
inp_len = len(inp) // 4
# print(inp_len)
value = unpack(f"<{inp_len}I",inp)
res = b""
for i in range(0,inp_len,2):
v = [value[i],value[i+1]]
x = encrypt2(v,k)
# x = decrypt2(v,k)
res += pack("<2I",*x)
return res
def reverse(m):
return m[::-1]
k0 = 0x23575896
k1 = 0x89654528
k2 = 0x12582548
k3 = 0x45897856
key1 = pack("<I",k0) + pack("<I",k1) + pack("<I",k2) + pack("<I",k3)
k0 = 0x12582548
k1 = 0x45897856
k2 = 0x23575896
k3 = 0x89654528
key2 = pack("<I",k0) + pack("<I",k1) + pack("<I",k2) + pack("<I",k3)
exp如下:
from ctypes import *
from struct import pack,unpack
def dec1(inp:bytes):
xor_list = [0x0000001b,0x00000051,0x0000002f,0xf3,0x34^0x9d,0x35^0xfb,0x36^0xca,0x37^0x33,0x38^0x7a,0x39^0x79,0x61^0x8d,0x62^0x79,0x63^0x19,0x64^0xb4,0x65^0xef,0x66^0x8c]
# [0x1b,0x51,0x2f,0xf3,0xa9,0xce,0xfc,0x4,0x42,0x40,0xec,0x1b,0x7a,0xd0,0x8a,0xea]
assert len(xor_list) == 16
for i in xor_list:
print(hex(i),end = ",")
print()
x = bytearray(inp)
for i in range(len(x)):
x[i] ^= xor_list[i]
return bytes(x)
def Rshift(m:int,cnt:int):
if m & 0x80000000 != 0:
x = 0xffffffff
x <<= (32-cnt)
x &= 0xffffffff
return (m >> cnt) | x
else:
return m >> cnt
def encrypt1(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
print(0,": ",hex(v0.value),hex(v1.value))
total = c_uint32(0)
for i in range(32):
total.value += delta
v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
v1.value += ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
# print(i+1,": ",hex(v0.value),hex(v1.value))
return v0.value, v1.value
def decrypt1(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v1.value -= ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
v0.value -= ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
total.value -= delta
return v0.value, v1.value
def encrypt2(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
print(0,": ",hex(v0.value),hex(v1.value))
total = c_uint32(0)
for i in range(32):
total.value += delta
v1.value += ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
print(i+1,": ",hex(v0.value),hex(v1.value))
# v0.value += ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
# print(32,": ",hex(v0.value),hex(v1.value))
return v0.value, v1.value
def decrypt2(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x57429f48
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v0.value -= ((v1.value<<4) + k0) ^ (v1.value + total.value) ^ (Rshift(v1.value,5) + k1)
v1.value -= ((v0.value<<4) + k2) ^ (v0.value + total.value) ^ (Rshift(v0.value,5) + k3)
total.value -= delta
return v0.value, v1.value
def tea1(inp:bytes,key:bytes):
from struct import pack,unpack
k = unpack("<4I",key)
inp_len = len(inp) // 4
# print(inp_len)
value = unpack(f"<{inp_len}I",inp)
res = b""
for i in range(0,inp_len,2):
v = [value[i],value[i+1]]
# x = encrypt1(v,k)
x = decrypt1(v,k)
res += pack("<2I",*x)
return res
def tea2(inp:bytes,key:bytes):
from struct import pack,unpack
k = unpack("<4I",key)
inp_len = len(inp) // 4
# print(inp_len)
value = unpack(f"<{inp_len}I",inp)
res = b""
for i in range(0,inp_len,2):
v = [value[i],value[i+1]]
# x = encrypt2(v,k)
x = decrypt2(v,k)
res += pack("<2I",*x)
return res
def reverse(m):
return m[::-1]
k0 = 0x23575896
k1 = 0x89654528
k2 = 0x12582548
k3 = 0x45897856
key1 = pack("<I",k0) + pack("<I",k1) + pack("<I",k2) + pack("<I",k3)
k0 = 0x12582548
k1 = 0x45897856
k2 = 0x23575896
k3 = 0x89654528
key2 = pack("<I",k0) + pack("<I",k1) + pack("<I",k2) + pack("<I",k3)
# dec
cip = [0x9c,0x6c,0x48,0x16,0x70,0x12,0x5a,0x2d,0xe1,0xd7,0xf5,0x7c,0xc5,0x46,0x32,0x68]
assert len(cip)==16
cip1 = bytes(reverse(cip[0:4]))
cip2 = bytes(reverse(cip[4:8]))
cip3 = bytes(reverse(cip[8:12]))
cip4 = bytes(reverse(cip[12:16]))
cip_tea1 = cip1+cip2
cip_tea2 = cip4+cip3
m1 = tea1(cip_tea1,key1)
m1_part1 = (m1[0:4])[::-1]
m1_part2 = (m1[4:8])[::-1]
m1 = m1_part1 + m1_part2
m2 = tea2(cip_tea2,key2)
m2_part2 = m2[0:4]
m2_part1 = m2[4:8]
m2_part1 = unpack("<I",m2_part1)[0]
m2_part2 = unpack("<I",m2_part2)[0]
m2 = pack("<I",m2_part1)[::-1] + pack("<I",m2_part2)[::-1]
flag = b"flag{" + dec1(m1 +m2) + b"}"
print(flag)