linux缓冲区溢出保护机制说明
来源:互联网 发布:网络课程 知乎 编辑:程序博客网 时间:2024/06/05 00:08
http://blog.sina.com.cn/s/blog_63fe2708010171t3.html
再较新的linux版本中引入了一些缓冲区溢出保护机制,试图将缓冲区溢出的危害降到最低,这对于使用系统的我们来说当然是件好事,但是如果想通过系统来做缓冲区溢出实验则会遇到一些麻烦,下面通过《网络渗透技术》的一个例子对此进行说明。
代码如下:
#include
#include
char largebuff[] =
"1234512345123451234512345===ABCD";
void main (void)
{
char smallbuff[16];
strcpy (smallbuff, largebuff);
}
原理很简单,将一个长数组内容复制到一个小数组中,造成溢出。
1.内存地址随机化机制
在Ubuntu和其他基于Linux内核的系统中,目前都采用内存地址随机化的机制来初始化堆栈,这将会使得猜测具体的内存地址变得十分困难。
关闭内存地址随机化机制的方法是:
sysctl –w kernel.randomize_va_space=0
2.可执行程序的屏蔽保护机制
对于Federal系统,默认会执行可执行程序的屏蔽保护机制,该机制不允许执行存储在栈中的代码,这会使得缓冲区溢出攻击变得无效。而Ubuntu系统中默认没有采用这种机制。
关闭可执行程序的屏蔽保护机制的方法是:
sysctl –w kernel.exec-shield=0
此保护机制尚未在程序中找到直接证据,留着好好研究。
3.gcc编译器gs验证码机制
gcc编译器专门为防止缓冲区溢出而采取的保护措施,具体方法是gcc首先在缓冲区被写入之前在buf的结束地址之后返回地址之前放入随机的gs验证码,并在缓冲区写入操作结束时检验该值。通常缓冲区溢出会从低地址到高地址覆写内存,所以如果要覆写返回地址,则需要覆写该gs验证码。这样就可以通过比较写入前和写入后gs验证码的数据,判断是否产生溢出。
关闭gcc编译器gs验证码机制的方法是:
在gcc编译时采用-fno-stack-protector选项。
hufeng@hufeng:~$ gcc -z execstack simple_overflow.c -o simple_overflow
hufeng@hufeng:~$ gdb simple_overflow
(gdb) disassemble main
Dump of assembler code for function main:
0x08048434 <+0>: push ebp
0x08048435 <+1>: mov esp, ebp
0x08048437 <+3>: and $0xfffffff0, esp
0x0804843a <+6>: sub $0x30, esp
0x0804843d <+9>: mov gs:0x14, eax
0x08048443 <+15>: mov eax,0x2c( esp)
0x08048447 <+19>: xor eax, eax
0x08048449 <+21>: mov $0x804a040, eax
0x0804844e <+26>: mov eax,0x4( esp)
0x08048452 <+30>: lea 0x1c( esp), eax
0x08048456 <+34>: mov eax,( esp)
0x08048459 <+37>: call 0x8048350
0x0804845e <+42>: mov 0x2c( esp), eax
0x08048462 <+46>: xor gs:0x14, eax
0x08048469 <+53>: je 0x8048470
0x0804846b <+55>: call 0x8048340 <__stack_chk_fail@plt>
0x08048470 <+60>: leave
0x08048471 <+61>: ret
End of assembler dump.
hufeng@hufeng:~$ gcc -fno-stack-protector -z execstack simple_overflow.c -o simple_overflow
hufeng@hufeng:~$ gdb simple_overflow
(gdb) disassemble main
Dump of assembler code for function main:
0x080483e4 <+0>: push ebp
0x080483e5 <+1>: mov esp, ebp
0x080483e7 <+3>: and $0xfffffff0, esp
0x080483ea <+6>: sub $0x20, esp
0x080483ed <+9>: mov $0x804a040, eax
0x080483f2 <+14>: mov eax,0x4( esp)
0x080483f6 <+18>: lea 0x10( esp), eax
0x080483fa <+22>: mov eax,( esp)
0x080483fd <+25>: call 0x8048300
0x08048402 <+30>: leave
0x08048403 <+31>: ret
End of assembler dump.
比较上面在两段main函数的汇编代码,可以发现主要的区别就在于下面几条语句:
mov gs:0x14, eax
mov eax,0x2c( esp)
mov 0x2c( esp), eax
xor gs:0x14, eax
je 0x8048470
call 0x8048340 <__stack_chk_fail@plt>
前两句从gs:0x14取值放入0x2c( esp)中,程序执行后再将0x2c( esp)的值与gs:0x14处的值对比,如果发生变化则说明缓冲区溢出,第一段汇编代码中为栈留出了足够的空间,原本不需要用到的地址如果发生变化则说明缓冲区溢出,然后调用__stack_chk_fail@plt函数进行处理。
4.ld链接器堆栈段不可执行机制
ld链接器在链接程序的时候,如果所有的.o文件的堆栈段都标记为不可执行,那么整个库的堆栈段才会被标记为不可执行;相反,即使只有一个.0文件的堆栈段被标记为可执行,那么整个库的堆栈段将被标记为可执行。检查堆栈段可执行性的方法是:
如果是检查ELF库:readelf -lW $BIN | grep GNU_STACK查看是否有E标记
如果是检查生成的.o文件:scanelf -e $BIN查看是否有X标记
ld链接器如果将堆栈段标记为不可执行,即使控制了eip产生了跳转,依然会产生段错误。
关闭ld链接器不可执行机制的方法是:
在gcc编译时采用-z execstack选项。
见下面例子:
hufeng@hufeng:~$ gcc -fno-stack-protector -z execstack simple_overflow.c -o simple_overflow
hufeng@hufeng:~$ readelf -lW simple_overflow | grep GNU_STACK
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
hufeng@hufeng:~$ gcc -fno-stack-protector simple_overflow.c -o simple_overflow
hufeng@hufeng:~$ readelf -lW simple_overflow | grep GNU_STACK
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
参考:
http://www.linuxidc.com/Linux/2011-10/44534.htm
http://www.win.tue.nl/~aeb/linux/hh/protection.html
- linux缓冲区溢出保护机制说明
- 缓冲区溢出的保护机制
- 缓冲区溢出保护
- 一些关于内存缓冲区溢出的保护机制
- 缓冲区溢出的保护方法
- windows server2003 基于栈缓冲区溢出的攻击保护机制研究
- Linux缓冲区溢出
- Linux缓冲区溢出问题
- linux下缓冲区溢出
- 缓冲区溢出之返回地址保护
- linux下缓冲区溢出实例
- linux上缓冲区溢出实验
- Windows 缓冲区溢出与数据执行保护DEP
- Windows 缓冲区溢出与数据执行保护DEP
- 缓冲区溢出与数据执行保护DEP介绍
- Windows 缓冲区溢出与数据执行保护DEP
- Windows 缓冲区溢出与数据执行保护DEP
- Windows 缓冲区溢出与数据执行保护DEP
- AndroidStudio使用第三方包报错
- poj 1080 DP
- 对象能够直接访问其私有成员变量
- C# WinForm开发系列 - Open-Source Controls
- Android学习网站以及源码下载
- linux缓冲区溢出保护机制说明
- struts
- “年月日”录入时的一个小漏洞
- block的使用
- Hello World!
- PYTHON之Ordered Dict
- Android USB下的Accessory模式
- 玩转iPhone网络通讯之BSD Socket篇
- 【数据结构与算法】自己动手实现图的BFS和DFS(附完整源码)