Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1297171
  • 博文数量: 196
  • 博客积分: 4141
  • 博客等级: 中将
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-21 20:04
文章存档

2019年(31)

2016年(1)

2014年(16)

2011年(8)

2010年(25)

2009年(115)

分类: 网络与安全

2009-03-22 14:09:58

说明    :简单的缓冲溢出实验,程序通过main()函数进入,调用test()函数,在test()函数中通过覆盖堆栈值,修改返回地址,使他跳入shellcode()函数中。然后在shellcode插入一定的嵌入式汇编代码,使之能够安全返回.
实验环境:
          操作系统: ubuntu 8.04
          编译器  : gcc 4.2.3
          编译命令 : gcc -g overflow.c -o overflow.o


#include "stdio.h"

int shellcode()
{
int value = 0;

printf("%x\n", &value);
printf("Overflow Successful!\n");
/* __asm__(
"addl $0x24,%esp\n\t"
"popl %ecx\n\t"
"popl %ebp\n\t"
"leal -0x4(%ecx),%esp\n\t"
"ret"
);*/

return 0;
}

int test()
{
int i;
unsigned int stack[10];

printf("%x\n", &stack);
for (i = 0; i < 10; i++)
stack[i] = 0;

for (i = 0; i < 20; i++)
{
printf("Index = %d:%x\n", i,stack[i]);
}

stack[12] = 0x80483b1;

return 0;
}

int main()
{
int value = 0;

printf("%x\n", &value);
test();
printf("Overflow Failed\n");

return 0;
}
运行结果:

bfc1c130
bfc1c0dc
Index = 0:0
Index = 1:0
Index = 2:0
Index = 3:0
Index = 4:0
Index = 5:0
Index = 6:0
Index = 7:0
Index = 8:0
Index = 9:0
Index = 10:a
Index = 11:bfc1c138
Index = 12:804847d
Index = 13:8048560
Index = 14:bfc1c130
Index = 15:bfc1c128
Index = 16:80482c8
Index = 17:b7f0fff4
Index = 18:8049684
Index = 19:bfc1c148
bfc1c134
Overflow
下面我们来介绍为何是在 stack[12] 插入 0x80483b1:

micklongen@micklongen-desktop:~/桌面/overflow/初级缓冲溢出实验/系列1$ gdb overflow.o

GNU gdb 6.8-debian

Copyright (C) 2008 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>


This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

and "show warranty" for details.

This GDB was configured as "i486-linux-gnu"...

(gdb) disas main

Dump of assembler code for function main:

0x0804844d <main+0>: lea 0x4(%esp),%ecx

0x08048451 <main+4>: and $0xfffffff0,%esp

0x08048454 <main+7>: pushl -0x4(%ecx)

0x08048457 <main+10>: push %ebp

0x08048458 <main+11>: mov %esp,%ebp

0x0804845a <main+13>: push %ecx

0x0804845b <main+14>: sub $0x24,%esp

0x0804845e <main+17>: movl $0x0,-0x8(%ebp)

0x08048465 <main+24>: lea -0x8(%ebp),%eax

0x08048468 <main+27>: mov %eax,0x4(%esp)

0x0804846c <main+31>: movl $0x8048560,(%esp)

0x08048473 <main+38>: call 0x80482fc <printf@plt>

0x08048478 <main+43>: call 0x80483d7 <test>

0x0804847d <main+48>: movl $0x8048588,(%esp)

0x08048484 <main+55>: call 0x804830c <puts@plt>

0x08048489 <main+60>: mov $0x0,%eax

0x0804848e <main+65>: add $0x24,%esp

0x08048491 <main+68>: pop %ecx

0x08048492 <main+69>: pop %ebp

0x08048493 <main+70>: lea -0x4(%ecx),%esp

0x08048496 <main+73>: ret

End of assembler dump.

由反汇编代码可知call test的下一条指令的地址是 0x0804847d ,再看运行结果,可见 Index = 12:804847d ,即在stack[12]存放的是返回地址,这就是我们选这 stack[12] 的原因。

小结:
    缓冲溢出原理其实就是内存操作。该程序能够在溢出的同时正常退出,主要原因是在内存操作方面做了一点手脚。我看过的一些缓冲溢出的文章在修改函数返回地址的同时都破坏了esp的值,这样往往在函数返回的时候会出现 段错误 。而在该程序中,仅仅修改了返回地址,并没有破快esp的值。
    另外,看到一些朋友在实验的过程中,经常受困于gcc添加的一些关于缓冲溢出保护的语句的困扰。或许我们可以在C代码中添加嵌入式汇编语句,提早ret(个人想法,还未充分证明是否可行)以避开这些语句。

阅读(2129) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~