Windows平台下的缓冲区溢出漏洞分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第27卷 第2期2003年2月 信 息 技 术
I NFORMATI ON TECHNOLOGY
VOL.27 NO.2
Feb.2003
Windows平台下的缓冲区溢出漏洞分析
邵 丹,唐世钢,林 枫
(哈尔滨理工大学测试技术与通信工程学院,哈尔滨150080)
摘 要:就windows平台下利用缓冲区溢出漏洞发起攻击时遇到的几个技术问题提出了一些想法和解决思路,这些问题包括:子函数返回时原缓冲区释放导致攻击代码shellcode无效问题; shellcode中跳转指令地址问题;shellcode所使用函数问题。
关键词:Windo ws;缓冲区溢出;漏洞
中图分类号:TP393.08 文献标识码:B 文章编号:1009-2552(2003)02-0017-03 The Analysis of Buffer Overflow Exploit under Windows OS
Shao Dan,Tang Shigang,Lin Feng
(College of Measure-control Technology&C ommunication Eng ineering,Harbin Univ.Sci.Tech,Harbin150080,China) Abstract:This article analyze some technical problems about overflow exploit under Windows OS and brings for word some ideas about how to solve them.These proble ms include:The function stack be released when func tion return;that result in the invalidation of shellcode,The proble m about jump address in shellcode,The problem about the function used in shellcode.
Key words:Windows;Overflow;Exploit
1 缓冲区溢出
缓冲区溢出指的是一种系统攻击的手段。通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。据统计,通过缓冲区溢出进行的攻击占所有系统攻击总数的80%以上。
造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序:
e xample1.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(),get char()等。当然,随便往缓冲区中填东西造成它溢出一般只会出现Segmentation fault错误,而不能达到攻击的目的。最常见的手段是通过制造缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令。如果该程序属于root且有suid权限的话,攻击者就获得了一个有root权限的shell,可以对系统进行任意操作了。
2 制造缓冲区溢出
一个程序在内存中通常分为程序段,数据端和堆栈三部分。程序段里放着程序的机器码和只读数据。数据段放的是程序中的静态数据。动态数据则通过堆栈来存放。在内存中,它们的位置是:
收稿日期:2002-10-15
作者简介:邵丹(1978-),男,2000年哈尔滨理工大学硕士研究生,研究方向:计算机网络安全。
当程序中发生子函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保存指令寄存器(EIP)中的内容做为返回地址(RET);第三个放入堆栈的是基址寄存器(EBP)中的内容;然后把当前的栈指针寄存器(ESP)中的内容拷贝到EBP,做为新的基地址;最后为本地变量留出一定空间,把ESP中的内容减去适当的数值。以下面程序为例:
e xample2.c
--------------
void function(char*str){
char buffer[16];
strcpy(buffer,str);
}
void main(){
char large-string[256];
int i;
for(i=0;i<255;i++)
large-string[i]=A;
func tion(large-string);
}
---------------
当调用函数function()时,堆栈如下:
栈顶 buffer EBP1 RET *str
<---[ ][ ] [ ] [ ]
large-string i EBP0 RET 栈底
[ ][][ ][ ]
注:EB P0代表0时刻EBP寄存器中的内容, EBP1代表1时刻EBP寄存器内容。
不用说,程序执行的结果是!Segmentation fault (core dumped)∀或类似的出错信息。因为从buffer开始的256个字节都将被*str的内容A覆盖,包括EBP1,RE T,甚至*str。A的十六进值为0x41,所以子函数的返回地址变成了0x41414141,这超出了程序的地址空间,所以出现段错误。
3 通过缓冲区溢出获得用户SHELL
利用缓冲区漏洞进行系统攻击的基本思想是:用精心计算好的地址替代堆栈中的RE T,使子函数返回时跳去执行shellcode。绝大多数有关缓冲区溢出漏洞的文章会告知通过如下步骤达到目的:在溢出的缓冲区中写入想执行的代码,再覆盖返回地址(RET)的内容,使它指向缓冲区的开头,就可以达到运行其它指令的目的,如下图所示:
栈顶 buffer EB P1 RE T *str
<---[SSSSSSSSS][S] [A] [ ]
large-string i EB P0 RE T 栈底
[ ][][ ][ ]
注:S代表shellcode,A代表返回地址
以下面程序为例:
exa mple3.c
-------------------
char shellcode[]={
0x8B,0xE5, mov esp,ebp
0x55, push ebp
0x8B,0xEC, mov ebp,esp
0x83,0xEC,0x0C, sub esp,0000000C
0xB8,0x63,0x6F,0x6D,0x6D, mov eax,
6D6D6F63
0x89,0x45,0xF4, m ov d word ptr[ebp-0C],ea x
0xB8,0x61,0x6E,0x64,0x2E, mov eax,
2E646E61
0x89,0x45,0xF8, mov d word ptr[ebp-08],ea x
0xB8,0x63,0x6F,0x6D,0x22, mov ea x,226D6F63
0x89,0x45,0xFC, mov d word ptr[e bp-04],ea x
0x33,0xD2, xor edx,edx
0x88,0x55,0xFF, mov byte ptr[ebp-01],dl 0x8D,0x45,0xF4, lea eax,dword ptr[ebp-0C]
0x50, push ea x
0xB8,0xad,0xaa,0x01,0x78, mov ea x, 7801aaad system()的内存地址
0xFF,0xD0 call eax调用system()
};
char large-string[128];
void main(){
char buffer[96];
int i;
long*long-ptr=(long*)large-string;
for(i=0;i<32;i++)
*(long-ptr+i)=(int)buffer;
for(i=0;i large-string[i]=shellcode[i]; memcpy(buffer,large-string,128); }