首页
论坛
课程
招聘
[原创]KCTF2021第10题 生命的馈赠
2021-12-12 12:11 16613

[原创]KCTF2021第10题 生命的馈赠

2021-12-12 12:11
16613

输入name和serial,在输入的时候暂停程序,暂停后返回到程序领空
图片描述
vfscanf输入的,这里下个断
程序最后会输出验证成功,找到字符串,下硬件断点,暂停后返回到程序领空
图片描述
vfprintf输出的,下个断点
搜索字符串引用,发现一处,正好代码没有混淆到
图片描述
从第2次输入结束 开始,到这个字符串引用,开始trace
40 minutes later...
534w条 trace记录,x64dbg搜索都能卡死的
将这些记录导出到一个文件里...
6 hours later...
成功导出1个G的大小的trace记录
IDA打开搜一下密码学常量,发现有MD5
图片描述
在结果比较前,搜索到了提供的name的MD5值
在trace记录里跟着这个值倒着搜 ,以ef16d5f4为例子
找到这个值第一次出现的地方,发现是个add操作
图片描述
是第4AEE73条记录,找到ecx,eax值
图片描述
递归搜索这ecx,eax值是哪里出现的,直到最后能够找到输入
图片描述
发现全是add,mul操作 ,怀疑就是个乘法
乘法操作只有一种
004748BB | mul dword ptr ds:[edx+ecx*4],发现有576次
图片描述
下个断记录下
图片描述
图片描述
再结合别的一些输入,和trace记录,可以整理下进行了哪些运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
X = 0xEEA43B9D52515B49838AFAA50490DA0B
def calc(T):
    #print(hex(T >> 128),hex(T & 0xffffffffffffffffffffffffffffffff))
    return (T >> 128) * 0x1A994BC5D + (T & 0xffffffffffffffffffffffffffffffff)
 
= X * X
A = calc(Z)
B = calc(A)
C = B * 0x6805A57D5B006445AC1B0675EB188435 + 0x4362F6846292652664A4CBBDC44FD283
D = calc(C)
E = calc(D)
F = E **2
G = calc(F)
R = calc(G)
 
print("X*X",hex(X*X))
print("B",hex(B))
print("C",hex(C))
print("D",hex(D))
print("E",hex(E))
print("F",hex(F))
print("G",hex(G))
print(hex(R))
 
print(R == 0x4f5a512668e16eb6931155ceef16d5f4)

测试发现输入0xffffffffffffffffffffffffffffffff,结果不对了,一查发现 B 截断了
改一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
X = 0xEEA43B9D52515B49838AFAA50490DA0B
def calc(T):
    #print(hex(T >> 128),hex(T & 0xffffffffffffffffffffffffffffffff))
    return (T >> 128) * 0x1A994BC5D + (T & 0xffffffffffffffffffffffffffffffff)
 
= X * X
A = calc(Z)
B = calc(A)
C = (B & 0xffffffffffffffffffffffffffffffff) * 0x6805A57D5B006445AC1B0675EB188435 + 0x4362F6846292652664A4CBBDC44FD283
D = calc(C)
E = calc(D)
F = (E & 0xffffffffffffffffffffffffffffffff) **2
G = calc(F)
R = calc(G)
 
print("X*X",hex(X*X))
print("B",hex(B))
print("C",hex(C))
print("D",hex(D))
print("E",hex(E))
print("F",hex(F))
print("G",hex(G))
print(hex(R))
 
print(R == 0x4f5a512668e16eb6931155ceef16d5f4)

calc功能可以近似为mod(0xffffffffffffffffffffffffffffffff - 0x1A994BC5D +1),两次基本上足够了,但是对0xffffffffffffffffffffffffffffffff会出错,先忽略
sage求解,发现给出的name是有4个解的,而KCTF没解

1
2
3
4
5
6
7
8
9
10
11
12
n=340282366920938463463374607424628147107
R.<x>=GF(n)[]
f=(R(x^2)* R(0x6805A57D5B006445AC1B0675EB188435) + R(0x4362F6846292652664A4CBBDC44FD283))^2
ANS = R(0x4f5a512668e16eb6931155ceef16d5f4)
(f - ANS).monic().roots()
 
'''
[(317209008808073944558421099888442923531, 1),
 (252926835306764223276296582400547582395, 1),
 (87355531614174240187078025024080564712, 1),
 (23073358112864518904953507536185223576, 1)]
'''

倒回去排查
图片描述
图片描述
图片描述
最后这两个数都是没有解的
结合上面mod会出错的地方,和12741741990437692346这个结果相较于其他数太小了,猜测B这时可能为0xffffffffffffffffffffffffffffffff + 1 + 12741741990437692346,即为 0X10000000000000000B0D3C2D4E7B7A3BA
图片描述
得到两个解FA593397309F169F9E6A166D2AAC1079和05A6CC68CF60E9606195E9912BBF332A
运行程序验证下发现FA593397309F169F9E6A166D2AAC1079正确


看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

收藏
点赞2
打赏
分享
最新回复 (1)
雪    币: 5125
活跃值: 活跃值 (67)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Gaojun13579 活跃值 2021-12-14 12:13
2
0
游客
登录 | 注册 方可回帖
返回