【DASCTF-2025上半年】RE-xuans

加密部分

输入给v6,经过一些格式和长度检查,截取{}内部分,进行加密
在这里插入图片描述
进入key_expand或sm4_encrypt中看看,移位、常数等很明显的SM4特征
在这里插入图片描述
把几个盒子,常数表,位移等都检查了一遍,没有魔改。因为本题重点不在加密上。

密钥修改

直接拿明文和密钥解密不行,显然被改了。前面有一大坨if,看到里面出现了key,应该是在这里被修改了。
在这里插入图片描述
于是拿ida尝试动调。结果失败,进不来main函数直接退出了。
还以为是有反调试,结果找了半天并没有,后来才知道该程序是个多进程,不知道是不是这个导致的。
433b10是fork,if是父进程的操作,父进程在执行完if后exit了,这可以通过pwndbg得知。于是不难猜测父进程修改了子进程的key。
于是拿pwndbg调试。这里由其要注意的一点是不能主动调试,虽然在父进程结束后能跟到子进程,但是似乎由于gdb托管以后父进程的改写操作写不到子进程去,要在输入时附加调试。
在4033cd下个断点看一下新key。
![[Pasted image 20250703184811.png]]
再解密,得到假flag,还没完。

check处修改

在这里插入图片描述
查看strcmp中的跳转偏移量的引用会发现它可能也被修改了,因此gdb继续跟进。
在这里插入图片描述
跳转到0x4019a5,发现是解方程,z3直接梭出密文。
在这里插入图片描述

from z3 import *

  

def solve_group(coefficients):

    # 创建变量

    a0, a1, a2, a3 = Ints('a0 a1 a2 a3')

    # 创建求解器

    s = Solver()

    # 添加约束条件

    for coeff in coefficients:

        expr = coeff[0]*a0 + coeff[1]*a1 + coeff[2]*a2 + coeff[3]*a3

        s.add(expr == coeff[4])

    # 检查是否有解

    if s.check() == sat:

        m = s.model()

        return (m[a0].as_long(), m[a1].as_long(), m[a2].as_long(), m[a3].as_long())

    else:

        return None

  

# 定义所有组的系数和常数项

groups = [

    # 第一组: a1[0], a1[1], a1[2], a1[3]

    [

        (173, 48, 118, 193, 66131),

        (68, 196, 104, 10, 52620),

        (22, 37, 88, 71, 36011),

        (89, 141, 59, 194, 61842)

    ],

    # 第二组: a1[4], a1[5], a1[6], a1[7]

    [

        (40, 88, 175, 89, 65258),

        (82, 166, 26, 78, 58176),

        (73, 10, 149, 116, 62478),

        (198, 80, 176, 193, 114069)

    ],

    # 第三组: a1[8], a1[9], a1[10], a1[11]

    [

        (83, 100, 178, 30, 56170),

        (148, 148, 143, 168, 70647),

        (33, 194, 10, 186, 53174),

        (128, 33, 32, 152, 26118)  # 注意: a1[8] << 7 是 128*a1[8]

    ],

    # 第四组: a1[12], a1[13], a1[14], a1[15]

    [

        (164, 115, 184, 29, 81254),

        (35, 129, 129, 165, 78646),

        (54, 134, 39, 18, 29827),

        (80, 133, 106, 43, 53660)

    ],

    # 第五组: a1[16], a1[17], a1[18], a1[19]

    [

        (187, 32, 121, 2, 24667),

        (66, 170, 58, 36, 44188),

        (103, 120, 12, 175, 52310),

        (83, 92, 129, 143, 46020)

    ],

    # 第六组: a1[20], a1[21], a1[22], a1[23]

    [

        (100, 54, 141, 122, 66732),

        (171, 85, 69, 7, 46817),

        (197, 48, 128, 132, 83536),  # a1[22] << 7 是 128*a1[22]

        (101, 181, 79, 144, 80587)

    ],

    # 第七组: a1[24], a1[25], a1[26], a1[27]

    [

        (149, 187, 24, 142, 92687),

        (118, 86, 49, 50, 49285),

        (70, 170, 164, 193, 92711),

        (96, 198, 95, 1, 61904)

    ],

    # 第八组: a1[28], a1[29], a1[30], a1[31]

    [

        (114, 179, 37, 163, 53864),

        (49, 94, 132, 99, 36980),

        (43, 113, 150, 128, 40829),  # a1[31] << 7 是 128*a1[31]

        (1, 139, 115, 44, 22448)

    ]

]

  

# 解决所有组

solution = [0] * 32

for i, group in enumerate(groups):

    result = solve_group(group)

    if result:

        base_index = i * 4

        solution[base_index] = result[0]

        solution[base_index+1] = result[1]

        solution[base_index+2] = result[2]

        solution[base_index+3] = result[3]

    else:

        print(f"Group {i} has no solution")

  

# 打印结果

print("Full solution:")

for i in solution:

    print(hex(i), end=' ')
0x1d 0x7f 0xea 0x8e 0x9b 0x89 0x91 0xf3 0x50 0xe6 0x91 0x18 0xd7 0x32 0xb3 0xfc 0x49 0xc1 0x26 0x79 0xa8 0x71 0x62 0xf6 0xa1 0xd4 0x2d 0xc5 0xe4 0x3b 0x59 0x56 

解密即可。
在这里插入图片描述

DASCTF{9d78b5507187421a48de8f6ef24a8d4b}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值