首页
论坛
课程
招聘
[原创]看雪10月ctf2017 TSRC 第二题——一道有PWN影子的CrackMe
2017-10-28 06:50 2606

[原创]看雪10月ctf2017 TSRC 第二题——一道有PWN影子的CrackMe

2017-10-28 06:50
2606
这道题真是坑啊!!!我前面一天都踩坑里了,踩到怀疑人生。。。(可能是因为我菜(逃
这道题,看起来很简单!!!打开发现是一个二元方程组



OK,4个线性方程组,解出来,就是答案,对吧?
不对!!!!!!
因为就算考虑溢出(MOD 0X100000000之后),这个方程组仍然无解!!
然后我就怀疑人生了。。。
但其实这是有道理的,
1.大家看,这个输入是有缓冲区溢出漏洞的,输入12个字符之后会触发缓冲区溢出漏洞,这就是为什么输入12个字符会重新跳到开头执行,是因为最后的0x00覆盖到了第13个字节,这本来是返回地址的最低字节,所以返回地址被改成了0x401000,即开始处。
2.我们假设,这4个线性方程组有解,那么能影响到结果的只有前8个字节(二元,每个是个int,4字节),而9到12这几个字节就会被verify()的push ebp覆盖掉,那么这4个字节就不会影响结果!即,这个答案多解。好,那么我们反过来想一想,看雪的CTF是不可能多解的,所以,这种常规的套路必然不可得出正确答案!
再来考虑一下,什么时候有可能会用到9-12这些字节?scanf的时候获取输入,verify() push ebp的时候破坏9-12这些字节的数据,那么说明,这些数据的使用只有可能在调用scanf到调用verify这之间!

retn之后就直接是verify了,然后push ebp破坏9-12的数据
我是想到两种可能性:
1.作者修改了_scanf的代码,获取input数据,并且以此修改key处的数据。
2.利用缓冲区溢出漏洞,retn跳转到其他地方,在那里输入的值被获取,并且处理,然后影响注册的成败
我其实一开始以为的是第一种可能性,就差逆出scanf算法看他有什么猫腻了。。结果想想其实不是,因为IDA识别出了他是_scanf这个函数。。。如果作者修改了这个函数,IDA可能识别不出来这是个_scanf。
这个时候再看看IDA,

注意这里直接从401130到413131跳了很多个字节!!(413131之后的这些代码本来在IDA是数据形式显示的,我自己c成代码的
c成代码之后,想一想,这些代码不像是正常编译器能生成的,很可能是作者弄的。再看看他的地址413131,有没有feel到什么,没错,就是ASCII字符串"11A"!作为二进制研究人员,我们对0x30(0) 0x41(A) 0x61(a)这些范围的数要非常的敏感!
那我们试一试,利用缓冲区溢出在retn的时候把eip跳转到这里,输入11112222333311A,回车

看esp,指向输入,这边直接ctrl+F11,看看会发生什么。。。我一开始是一步一步跟的,但是花指令太多了,跟着很累,所以直接run跟踪了。。。
结果发现,这个对输入操作是有规律可循的!

花指令去掉,汇编是这样的。。。最后那个jmp

15行sub了一个很奇葩的常数,然后有个je,我们随便输入数的话这个je是不会跳转的,在jnz跳转的话,必然会掉到走向错误注册的道路里去(18行的pop eax),有兴趣大家可以跟一下。还有,这个对[0x41b034]的处理貌似没什么用,虽然这就是前面的全局变量key。。。

OD里面,执行15行指令前,把eax改成0xeaf917e2,ctrl+F11发现,有新的汇编代码,然而最后又跳入pop eax那个走向错误的道路。。。

再来一次,这次sub eax,0xe8f508c8下断,这次我们把eax也改成0xe8f508c8,ctrl+F11,发现又有这么一堆类似的东西,也是类似的运算,减一个魔数,熟悉的味道,后面这个的代码跟前面两个差不多,我就不放上来了。。。但是最后一次暴力改的话会扔出异常。我猜是因为我们输入还是111122223333,他可能是用输入的值动态生成跳转到的成功代码块的地址的,没研究,因为这样的三块玩意已经足够我们就得到一个三元的线性方程组了。。。

(input0-input1)*3+input0-input2 == 0xc0a3c68

(input0-input1)*3+input0+input2 == 0xe8f508c8

(input0-input1)*4+input0+input2 == 0xeaf917e2

直接上网找个解方程的网站(http://www.yunsuanzi.com/matrixcomputations/solvelinearsystems.html)

# 您输入的问题如下:

# 系数矩阵A:

# 第1列 第2列 第3列

# 4.0000 -3.0000 -1.0000

# 4.0000 -3.0000 1.0000

# 5.0000 -4.0000 1.0000

# 右边向量b:

# 201997416.0000

# 3908372680.0000

# 3942193122.0000 #

您所输入问题的解如下: # x1 = 1953723722.0000 # x2 = 1919903280.0000 # x3 = 1853187632.0000

def printAsHex(iInt):
	str = []
	str.append(chr(iInt & 0xff))
	str.append(chr((iInt >> 8) & 0xff))
	str.append(chr((iInt >> 16) & 0xff))
	str.append(chr((iInt >> 24) & 0xff))
	print "".join(str)


x1	=	1953723722
x2	=	1919903280
x3	=	1853187632


printAsHex(x1)
printAsHex(x2)
printAsHex(x3)

Just

0for

0fun

所以flag就是 Just0for0fun11A









[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

收藏
点赞0
打赏
分享
最新回复 (10)
雪    币: 5653
活跃值: 活跃值 (369)
能力值: ( LV17,RANK:1165 )
在线值:
发帖
回帖
粉丝
holing 活跃值 15 2017-10-28 06:51
2
0
PS:看雪这个编辑器是真的不行。。。复制进来的东西连回车都消失了。。。建议改进一下。。。。
雪    币: 1317
活跃值: 活跃值 (2049)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2017-10-28 19:29
3
0
holing PS:看雪这个编辑器是真的不行。。。复制进来的东西连回车都消失了。。。建议改进一下。。。。
主要是过滤了一些word复制进来的垃圾信息
雪    币: 6809
活跃值: 活跃值 (152)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
聖blue 活跃值 2017-10-28 22:26
4
0
不错!
雪    币: 2
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Antibac 活跃值 2017-11-6 15:30
5
0
如何才能像你一样看见0x413131处的代码?
雪    币: 11417
活跃值: 活跃值 (763)
能力值: ( LV13,RANK:703 )
在线值:
发帖
回帖
粉丝
大帅锅 活跃值 3 2017-11-6 18:45
6
1
Antibac 如何才能像你一样看见0x413131处的代码?
右键从模块删除分析!
雪    币: 2
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Antibac 活跃值 2017-11-6 19:07
7
0
大帅锅 右键从模块删除分析!
多谢~!!!自己绕了好久,差点就要用笨办法,把这些一个一个机器码转成汇编码了
雪    币: 2362
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
petersonhz 活跃值 2018-5-28 00:58
8
0
为什么用ollyICE,不用ollydbg?
雪    币: 5653
活跃值: 活跃值 (369)
能力值: ( LV17,RANK:1165 )
在线值:
发帖
回帖
粉丝
holing 活跃值 15 2018-5-28 01:06
9
0
petersonhz 为什么用ollyICE,不用ollydbg?
老哥,能不能别挖我坟贴了。。。。
雪    币: 2362
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
petersonhz 活跃值 2018-5-28 01:16
10
0
好吧,你现在主要用ollyice么?
雪    币: 5653
活跃值: 活跃值 (369)
能力值: ( LV17,RANK:1165 )
在线值:
发帖
回帖
粉丝
holing 活跃值 15 2018-5-28 03:49
11
0
petersonhz 好吧,你现在主要用ollyice么?
都差不多,顺手就好
游客
登录 | 注册 方可回帖
返回