-
-
[原创]第八题 挖宝
-
发表于:
2019-3-23 03:04
4127
-
用ida打开该程序,初步分析发现程序是由go语音编写,使用开源工具golang_loader_assist对程序进行函数名识别,能够看到绝大多数程序的名称,主函数如下:
Ida里面的go程序,可以看出每个函数的真实传参是从第7个开始,也就是64位下栈传参的位置,这样就能看出函数的真正传参过程。
通过分析和运行得知,该程序是一个游戏,在6*6大小的格子里面随意移动,有四个宝藏点,其中Treasure1、2、3三个是固定的,分别在(5,0)(5,5)(0,5),而Treasure4是随机的,在main_randtreasure里面进行了随机化,如下:
且在程序游戏开始的时候,启动了一个main_joker线程,如下:
Joker线程的作用是,每隔一秒检测一次,判断当前的位置是否接近了Treasure4(距离小于等于1步),如果是就再次随机化Treasure4的位置,如下:
游戏每次到达一个Treasure的位置时,都能留下信息,游戏的过程就是上述逻辑。
当游戏到达Treasure点后,留消息时代码如下:
其中main_memcpy的实现如下:
拷贝是按照size来定的,而size的传入是有scan来决定的,所以如果scan输入的长度大于dst缓冲区时,就能够产生溢出。
通过分析Treasure1、2、3、4,发现前三种都是在堆上,只有4是在栈上,如下:
由于go语言里面的堆申请和释放比较麻烦,所以在此采用栈的利用方法,虽然程序开启了canary check,但是go代码里面并没有,因此可以直接使用,不需要泄露canary,此外程序要到达Treasure4才能触发栈溢出,前面分析过,虽然存在随机化的问题,但是检测时sleep1秒还是比较长,可以通过多次尝试来解决。
由于程序开启了地址随机化,因此需要泄露地址信息,观察栈可以看出来,地址指针在缓冲区的下方,如下:
在输入后,会将该指针里面的数据转换为string,如下:
因此如果能够更改dst的指针,就能泄露信息,通过改写dst的低字节(1字节),可以泄露栈上数据,包括栈地址等,然后根据栈地址,实现任意栈上数据泄露,从而实现程序基址和libc基址,后续利用直接就是最基本的栈溢出即可,
具体见利用代码。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)