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符号表

这里有几种修复方法:

  1. flair 制作 rust的sig来修复部分符号表。

  2. 下载对应版本的rust,用rust语言随便写几个程序,之后bindiff一下,修复部分符号表。

  3. 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)

结果如下:

image-20241101102526512

...

image-20241101102501041

unname

逆了一下午写出的exp脚本找不到了。。

依稀记得,主要是逆向这一段代码,其他没什么技巧可言,只能硬逆

image-20241031155030167

我一个师弟逆向的代码:

image-20241031231542196

优雅至极

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)

posted @ 2025-05-15 15:59  TLSN  阅读(59)  评论(0)    收藏  举报