-
-
[原创]KCTF2021第10题 生命的馈赠
-
2021-12-12 12:11
18569
-
输入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):
return (T >> 128 ) * 0x1A994BC5D + (T & 0xffffffffffffffffffffffffffffffff )
Z = 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):
return (T >> 128 ) * 0x1A994BC5D + (T & 0xffffffffffffffffffffffffffffffff )
Z = 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()
|
倒回去排查
最后这两个数都是没有解的
结合上面mod会出错的地方,和12741741990437692346这个结果相较于其他数太小了,猜测B这时可能为0xffffffffffffffffffffffffffffffff + 1 + 12741741990437692346,即为 0X10000000000000000B0D3C2D4E7B7A3BA
得到两个解FA593397309F169F9E6A166D2AAC1079和05A6CC68CF60E9606195E9912BBF332A
运行程序验证下发现FA593397309F169F9E6A166D2AAC1079正确
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课