NSCTF 2017-pwn2
1.常规checksec,开启了NX和canary,IDA打开找漏洞,sub_80487FA()函数中存在两个漏洞:
(1)格式化字符串漏洞:
1 | #注释头 |
(2)栈溢出漏洞:
1 | #注释头 |
2.由于canary的关系,栈溢出没办法利用,但是这里可以通过格式化字符串漏洞直接泄露canary,之后再实际操作。这里为了学习爆破canary的方式,先用爆破的方式来获取canary。
3.如果直接爆破canary,由于canary随机刷新,就算去掉最后一个字节\x00,在32位条件下我们假定一个canary的值,那么canary随机生成为我们假定的值的概率应该为1/(2^24-1)所以从概率上讲应该需要爆破2^24-1次,也就是16,777,215-1次,而且还只是概率上的期望值,如果不考虑canary的实际生成机制,并且运气不好的话,可能无穷大,等爆出来黄花菜都凉了,这鬼能接受。所以一般使用爆破canary都需要一个fork子进程。
4.子进程的崩溃并不会影响到父进程,并且由于子进程的数据都是从父进程复制过来的,canary也一样,只要父进程不结束,子进程无论崩溃多少次其初始化的数据还是父进程的数据,canary就不会发生改变,这样就为快速爆破canary创造了前提。刚好这个程序有fork一个子进程:
(1)观察汇编代码:
main函数主体中先call fork,由于函数的结果基本都是传给eax,所以这里的eax就代表fork的成功与否,返回ID代表fork成功,然后将调用结果赋值给局部变量[esp+1ch],之后拿0与局部变量[esp+1ch]比较。这里涉及到JNZ影响的标志位ZF,CF等,不细介绍。总而言之就是会fork一个子进程,成功就跳转到我们之前说过的有漏洞的函数中,失败则等待,一会然后依据while重开程序。
(2)观察伪代码也可以
▲fork机制:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
5.爆破canary原理:
(1)最开始我认为就算canary不变,那么从024开始尝试,一直到canary的值,那么需要尝试canary值这么多次,最少1次,最多2^24次,就算取期望,那也应该是(1/2)(2^24)次。也没办法接受啊。
(2)之后看了canary的检查机制和生成机制:在sub_80487FA汇编代码中:
生成的时候是将栈上指定地方[ebp+var_C]给修改成canary。
检查的时候,是从栈上取[ebp+var_C]的值传给eax和最开始随机生成的canary(large gs:14h)来比较,所以当我们用栈溢出的时候,我们可以只溢出一个字节来修改[ebp+var_C]的第1个字节,(第0个字节是\x00),然后启动检查机制。由于只修改了栈上[ebp+var_C]的第1个字节数据,第3,2个字节仍然还是之前被保存的canary的值。所以我们获取第1个字节需要尝试最少1次,最多2^8次,平均(1/2)(2^8)次,也就是128次,可以接受。之后将爆破成功的第1个字节加到栈溢出内容中,再溢出一个字节修改[ebp+var_C]上的第2个字节,同理,完成爆破需要128次,总的来说平均需要1283=384次,完全可以接受。
(3)爆破一般形式程序,两个循环:
1 | #注释头 |
6.之后不同程序不太一样,有的程序没有循环,是直接fork一个子进程,监听其它端口,这时候只要连接该端口就可以进行爆破,失败了关闭端口就是。
有的程序只是在程序中fork一个子进程,但是有循环,那么我们就需要在循环里跑出来canary。然后直接进行下一步payload,不然断开连接的话,程序又重新生成canary,等于没用。
7.总结一下,程序最开始需要输入Y,然后跳转到有漏洞的函数sub_80487FA中,之后可以获取输入name,这里的输入的name在下一条[*] Welcome to the game之后会被打印出来,并且打印的方式存在格式化字符串漏洞。所以可以通过调试,输入%p来获取栈上的指定的libc地址内容,泄露libc从而获取libc基地址。
8.由于每次子程序崩溃后都会从头开始,都需要再输入Y和name,那么直接将该段泄露代码放在爆破循环中即可:
1 | canary = '\x00' |
9.爆破结束后,得到libc基地址,canary,以及一个可以利用的栈溢出,程序循环从最开始。那么利用栈溢出返回到system函数,由于32位程序,栈传参,那么可以提前布置好栈,使得system函数直接从我们布置的栈上读取binsh字符串,直接getshell。
1 | #注释头 |
参考资料:
https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=157