实验三+缓冲区溢出

合集下载

缓冲区溢出攻击实验

缓冲区溢出攻击实验

HUNAN UNIVERSITY课程实验报告题目: Buflab-handout学生姓名学生学号专业班级计科1403(一)实验环境联想ThinkPadE540 VM虚拟机ubuntu32位操作系统(二)实验准备1.使用tar xvf命令解压文件后,会有3个可执行的二进制文件bufbomb,hex2raw,makecookie。

bufbomb运行时会进入getbuf函数,其中通过调用Gets函数读取字符串。

要求在已知缓冲区大小的情况下对输入的字符串进行定制完成特定溢出操作。

从给的PDF文件中我们得知getbuf函数为:/ /Buffer size for getbuf#define NORMAL_BUFFER_SIZE 32int getbuf(){char buf[NORMAL_BUFFER_SIZE];Gets(buf);return 1;}这个函数的漏洞在于宏定义的缓冲区的大小为32,若输入的字符串长于31(字符串末尾结束符)则会导致数据的覆盖,从而导致一系列损失;在此实验中,我们正是利用这个漏洞来完成实验。

2. hex2raw可执行文件就是将给定的16进制的数转成二进制字节数据。

Makecookie是产生一个userid。

输入的相应的用户名产生相应的cookie值。

**我产生的cookie值为0x5eb52e1c,如下图所示:Level0:实验要求:从英文的PDF文件中的“Your task is to get BUFBOMB to execute the code for smoke when getbuf executes its return statement,rather than returning to test. Note that your exploit string may also corrupt parts of the stack not directlyrelated to this stage, but this will not cause a problem, since smoke causes the program to exit directly.”这句话看出实验让我们在test运行完后,不直接退出,而是跳到smoke函数处执行然后退出,这点很重要!(本人之前一直没有成功就是错在这儿)Test源码:void test(){int val;// Put canary on stack to detect possible corruptionvolatile int local = uniqueval();val = getbuf();// Check for corrupted stackif (local != uniqueval()) {printf("Sabotaged!: the stack has been corrupted\n");}else if (val == cookie) {printf("Boom!: getbuf returned 0x%x\n", val);validate(3);} else {printf("Dud: getbuf returned 0x%x\n", val);}}smoke源码:void smoke(){printf("Smoke!: You called smoke()\n");validate(0);exit(0);}对bufbomb函数进行反汇编并获取getbuf函数的反汇编代码:从上面的汇编代码中我们可以得知,lea指令把buf的指针地址(-0x28(%ebp))传给了Gets()。

03缓冲区溢出漏洞原理

03缓冲区溢出漏洞原理

程序进程内存布局
Windows进程内存空间
程序进程内存布局
Windows进程内存空间
缓冲区溢出攻击原理
缓冲区溢出攻击原理
栈帧 栈帧是一个函数执行的环境,每个函数都有自己的栈帧空间,系统栈
顶为正运行函数的栈帧。
低地址
栈帧寄存器: – ESP:栈指针寄存器,存放系统栈最上面 栈帧的栈顶的指针。 – EBP:基址指针寄存器,存放栈最上面栈
缓冲区溢出攻击原理
函数调用过程
高地址(栈底)
main ebp esp esp esp esp func ebp esp esp
低地址(栈顶)
… 2 1 Ret(EIP) ebp retVal
缓冲区溢出攻击原理
函数返回过程
保存返回值:通常将函数的返回值保存在Eax;
弹出当前栈帧,恢复上一个栈帧。 – ESP加上栈帧大小,回收栈帧空间 – 将栈帧底部保存的前栈EBP值弹入EBP寄存器 – 将函数返回地址弹给EIP寄存器
跳转:按照函数返回地址跳回母函数中继续执行。
缓冲区溢出攻击原理
函数调用过程示意图
缓冲区溢出攻击原理
缓冲区溢出攻击
向缓冲区中填入过多的数据,超出边界导致数据外溢,覆盖了相邻
的内存空间 利用缓冲区溢出覆盖改写关键数据 最终改变程序执行流程,干扰系统运行,破坏系统完全性以及执行 任意恶意代码
缓冲区溢出防御
操作系统防御机制
DEP
– 使堆和栈的数据不可执行,这样就无法运行堆或栈中的 shellcode ASLR – 加载的可执行模块内存地址随机化,模块地址不再固定,
无法使用事先固定地址跳转到shellcode,因为存放shellcode
的地址变成随机的了

缓冲区溢出攻击与防范实验报告

缓冲区溢出攻击与防范实验报告

缓冲区溢出攻击与防范实验报告——计算机网络(2)班——V200748045黄香娥1·缓冲区溢出的概念:缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间想匹配,这就为缓冲区溢出埋下隐患.操作系统所使用的缓冲区又被称为"堆栈". 在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。

2·缓冲区溢出的危害:在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。

而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。

3·缓冲区溢出原理:由一个小程序来看://test.c#include "stdio.h"#include "stdlib.h"#include "string.h"void overflow(void){char buf[10];strcpy(buf,"0123456789123456789");}//end overflowint main(void){overflow();return 0;}//end main按F11进入"Step into"调试模式,如下:按F11跟踪进入overflow,让程序停在6,现在再看一下几个主要参数:esp=0x0012ff30,eip发生了变化,其它未变。

缓冲区溢出攻击实验报告_林凯杰_30601340

缓冲区溢出攻击实验报告_林凯杰_30601340

缓冲区溢出攻击实验【实验要求】1)基本要求:编写一个能实现缓冲区溢出(整数溢出或堆栈溢出)的程序。

语言不限(c,c++,c#,java等均可),环境也不限(linux或windows等)。

并在调试状态下(如linux的gdb或其他集成开发环境的调试命令)查看寄存器和相应存储单元内容的变化情况。

分析并解释缓冲区溢出的原因。

提交:分析文档(要给出调试过程和运行过程中的一些必要的截图),源代码等。

2)提高要求:在上述溢出的情况下,改写ret地址,增加shellcode代码,实现本地或远程管理员权限的非授权访问。

例:一个简单的shellcode程序:/* linux下的一个程序*/#include <stdio.h>void main() {char *name[2];name[0]="/bin/sh";name[1]=NULL;execve(name[0],name,NULL);}也可用gdb对其反汇编(主要分析execve和exit函数调用的机器指令),获得相关的汇编代码,进一步处理为16进制机器代码,形如char shellcode[]="\xeb\xlf.......\bin\sh";然后利用strcpy等脆弱性函数植入shellcode.【实验原理】实验主要是利用strcpy等脆弱性函数在执行时没有检查缓冲区长度的特性,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。

1、局部变量与堆栈的关系在一个程序中,会声明各种变量。

静态全局变量是位于数据段并且在程序开始运行的时候被初始化,而局部变量则在堆栈中分配,只在该函数内部有效。

如果局部变量使用不当,会造成缓冲区溢出漏洞。

例如,以下程序将命令行的第1个参数拷贝到buffer局部变量中。

void main(int argc,char **argv){char buf[80];strcpy(buf,argv[1]);}在一次函数调用中,堆栈中将被依次压入:参数、返回地址。

缓冲区溢出攻击与防范实验报告

缓冲区溢出攻击与防范实验报告

实验六报告如图2所示的Windows 2000系统(虚拟机环境下)的计算机。

显然这2台计算机处于同一个网段中,可以相互通讯,win10系统用作攻击机,下面将在此系统上运行Metasploit进行渗透测试,而Windows 2000系统都是本次任务中需要进行渗透入侵的靶机,保持安装后的默认状态,没有打额外的系统安全补丁。

图1 win10攻击机图2 Windows 2000 靶机2、扫描靶机在正式开始渗透之前,应该对靶机进行扫描探测工作,搞清楚渗透目标的系统类型、开放的端口服务、可能存在的安全漏洞等。

在win10攻击机上运行metasploit console,即可进入Metasploit环境。

现在可以利用MSF框架中集成的Nmap扫描器对渗透测试目标进行扫描,如图3所示,获取了靶机的开放服务和操作系统类型等信息。

图3 windows 2000扫描结果利用扫描器的脚步插件,还有可能直接探测出目标系统的安全漏洞,例如如图4所示,Nmap 利用smb-check-vulns插件扫描探测出了Windows 2000靶机存在MS08_067漏洞,命令执行如下:nmap -script= 。

namap扫描的结果里报告发现MS08-067:DISABLED。

这是在暗示我们或许能够对这台主机进行渗透攻击,然后我们在Metasloit里面找到此漏洞的攻击模块,并尝试攻击目标机器。

MS08-067是一个对操作系统版本依赖非常高的漏洞,所以在这里,我们只自动payload指定一下目标就可以确保触发正确的溢出代码。

图4漏洞扫描结果3利用MS08_067漏洞渗透入侵MS08-067漏洞的全称为“Windows Server服务RPC请求缓冲区溢出漏洞”,如果用户在受影响的系统上收到特制的RPC 请求,则该漏洞可能允许远程执行代码。

在Microsoft Windows 2000Windows XP 和Windows Server 2003 系统上,攻击者可能未经身份验证即可利用此漏洞运行任意代码,此漏洞可用于进行蠕虫攻击,目前已经有利用该漏洞的蠕虫病毒。

信息安全实验-缓冲区溢出-蒋智超

信息安全实验-缓冲区溢出-蒋智超

缓冲区溢出一、实验目的掌握缓冲区溢出攻击的现象掌握使用缓冲区溢出工具的方法二、实验步骤一.利用ms06035漏洞进行攻击1.进入“ms06035漏洞利用工具”目录主机A单击工具栏中“ms06035工具”按钮,进入“ms06035漏洞利用工具”工作目录。

2.查看当前目录内容主机A用dir命令查看当前目录中的内容,如下图所示:图4-1-1 工具目录中的内容上图中标注的“ms06035.exe”即为ms06035漏洞利用工具。

3.使用“ms06035工具”进行攻击主机A执行“ms06035.exe 主机B的ip 445”命令,发起对主机B的攻击。

4.主机B观察被攻击现象主机B被攻击后出现蓝屏死机的现象(实验结束,主机B用虚拟机“快照X”恢复实验环境)。

二.利用ms08025漏洞进行攻击以下步骤两主机互相攻击对方,操作相同,故以主机A为例说明实验步骤。

「注」主机B单击“ms08025工具”按钮,进入实验目录。

将ms08025.exe复制到D盘的根目录下,以便实验下一步进行。

1.telnet登录系统(1)主机A在命令行下使用telnet登录同组主机,当出现“您将要把您的密码信息送到Internet区内的一台远程计算机上,这可能不安全,您还要发送吗(y/n)”当出现此提示时,选择n,输入登录账号“student”,密码“123456”。

登录成功如下图所示。

图4-1-2 telnet登录(2)主机A依次输入“d:”|“dir”查看同组主机D盘根目录,“ms08025.exe”即为实验工具。

图4-1-3 实验工具2.使用系统命令添加用户主机A使用“net user student1 /add”命令来试添加一个用户“student1”,执行该命令,出现“发生系统错误5,拒绝访问”的提示,如下图所示:图4-1-4 使用系统命令添加用户请解释出现上述现象的原因:。

3.查看ms08025工具使用方法主机A在telnet命令行中输入“ms08025.exe”,查看工具的使用方法,如下图所示:图4-1-5 ms08025工具使用方法4.使用ms08025工具添加用户主机A执行“ms08025.exe "net user student1 /add"”命令,提示命令成功完成,证明用户student1成功添加,如下图所示:图4-1-6 使用ms08025工具添加用户5.查看用户信息主机A用命令“net user student1”查看用户student1的信息,发现用户student1创建成功,隶属于Users组。

缓冲区溢出攻击与防范实验报告

缓冲区溢出攻击与防范实验报告

缓冲区溢出攻击与防范实验报告——计算机网络(2)班——V200748045黄香娥1·缓冲区溢出的概念:缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间想匹配,这就为缓冲区溢出埋下隐患.操作系统所使用的缓冲区又被称为"堆栈". 在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。

2·缓冲区溢出的危害:在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。

而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。

3·缓冲区溢出原理:由一个小程序来看://test.c#include "stdio.h"#include "stdlib.h"#include "string.h"void overflow(void){char buf[10];strcpy(buf,"0123456789123456789");}//end overflowint main(void){overflow();return 0;}//end main按F11进入"Step into"调试模式,如下:按F11跟踪进入overflow,让程序停在6,现在再看一下几个主要参数:esp=0x0012ff30,eip发生了变化,其它未变。

缓冲区溢出实验

缓冲区溢出实验

缓冲区溢出实验实验环境:实验准备:因为缓冲区溢出攻击是一个比较老的攻击方法,因此在现在的操作系统中都加入了防护机制。

在实验开始之前,为了能成功的看到结果,我们需要把这些防护机制关掉。

工程如下:第一步,关掉随机地址机制。

地址随机是一个主要防护机制,在缓冲区溢出攻击过程中需要覆盖并改写程序的返回地址。

使返回地址指向我们的代码,如果开始地址随机的话,我们就不能准确的计算出我们的代码的位置。

所以,我们使用以下命令(在root权限下),关掉该防护机制。

#sysctl -w kernel.randomize_va_space=0第二步,在编译的时候,要关掉栈区保护,并且允许栈区可执行。

这样,我们利用缓冲区溢出注入的代码才可以在栈里面执行。

$ gcc -fno-stack-protector example.c$ gcc -z execstack -o test test.c实验过程:首先分析被攻击的程序#include <stdlib.h>#include <stdio.h>#include <string.h>int bof(char *str){char buffer[24];/* The following statement has a buffer overflow problem */strcpy(buffer, str);return 1;}int main(int argc, char **argv){char str[517];FILE *badfile;badfile = fopen("badfile", "r");fread(str, sizeof(char), 517, badfile);bof(str);printf("Returned Properly\n");return 1;}main()函数读入一个文件,并调用bof(),进行拷贝。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

服务器安全攻防技术实验报告实验名称:缓冲区溢出班级:姓名:学号:实验地点:日期:2020/3/11一、实验目的:1.通过实践掌握缓冲区溢出的原理;掌握常用的缓冲区溢出方法;理解缓冲区溢出的危害性;掌握防范和避免缓冲区溢出攻击的方法。

二、基本技能实验内容、要求和环境:实验环境:1.PC机一台,安装有Windows 2003 server;2.Vmware软件一套;3.Codeblockse软件。

实验内容:1、简单陈述缓冲区溢出的原理。

2、(1)陈述程序如何溢出?(2)为什么执行why_here方法?(3)画出栈结构#include <stdio.h>#include <stdlib.h>void why_here(void) //这个函数没有任何地方调用过{printf("why u here !n\n");printf("you are trapped here\n");system("pause");_exit(0);}int main(int argc,char * argv[]){int buffer[1];buffer[4] = why_here;system("pause");return 0;}三、基本技能实验结果与分析:1、简单陈述缓冲区溢出的原理。

答案:缓冲区溢出是指当前计算机向缓冲区内填充数据位数超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上,破坏程序的堆栈,使程序转而执行其他指令,以达到攻击的目的。

2、(1)陈述程序如何溢出?运行程序,返回结果如下:分析:由代码我们可以看出,在我们的main()函数中并没有调用过why_here()函数,只是定义了一个buffer[1]的数组,但是在我们定义了数组之后,我们同时为buffer[4]赋值为why_here()函数的返回值。

我们知道buffer数组并没有buffer[4]这个位置,此时我们为它赋值就会造成该buffer[4]中原来返回地址被覆盖,转去执行why_here(),就会输出以上的语句了。

进入debug模式,查看Selected frame,从中我们可以获取的信息有:EIP为0x401384,在执行main函数之后被保存为0x4010fd,,编码为C语言,涉及到的实参有argc=1, argv=0x1e2e28,局部变量存放在栈的0x60ff08的位置;而目前的frame指针所指示的位置为0x60ff10;保存的寄存器为EBP存放在0x60ff08,EIP保存在0x60ff0c。

debugging windows的watchs窗口中函数中涉及的参数和变量所对应的值。

(2)为什么执行why_here 方法?答案:我们的EBP 所处的位置为0x60ff08,EIP 所处的位置为0x60ff0c,而我们当前的指针(SP )指向了0x60ff10,刚好是buffer[4]所处的地址,那么它就会转去执行why_here()函数,从而就会输出当前的语句。

(3)画出栈结构 答案:栈空间由操作系统自动分配释放,存放函数的参数值,局部变量,EBP,EIP 的值,栈使用的是一级缓存,只是在被调用的时候处于存储空间中,调用完成立即释放。

注意,全局变量和局部静态变量的存储并不会放到内存中的栈区,而是放到静态区,程序执行结束由系统释放。

在Windows 中,栈是线低地址扩展的数据结构,是一块连续的内存区域。

在大多数的C 编译器中,参数是由右向左入栈,然后就是函数中的局部变量。

当本次函数调用结束后,局部变量先出栈,然后是参数,最后是栈顶指针指向函数的返回地址,就是主函数中下一条指令的地址。

程序就会从该点继续执行。

了解栈的相关知识之后,就可以画出以以下栈的结构:局部变量存放在低地址端(0x60ff04)EBP 存放位置(0x60ff08)函数返回的地址,下一条指令地址(0x60ff10)EIP 存放位置(0x60ff0c)四、进阶技能的任务与要求:1、(1)陈述程序如何溢出?(2)画出栈结构(3)补充auth方法,如果输入字符超出正常范围下,提示“输入字符超出范围”;否则,无提示。

#include <stdio.h>#include <string.h>int auth(const char* password){int flag = 0;char pwd[16];strcpy(pwd, password);pwd[0] = 't';if(!strcmp(pwd, "test")){flag = 1;}return flag;}int main(){int flag = 0;char password[128];scanf("%s", password);if(auth(password)){printf("right password\n");}else{printf("wrong password\n");}return 0;}2、设计具有溢出的程序,并解释说明五、进阶技能实验结果与分析:1.首先分析代码块,strcpy()函数用于对字符串进行复制,strcpy(char* strDestination, const char* strSource)。

其中,strDestination代表的是目的字符串,strSource,代表的是源字符串,strcpy()函数会把strSource指向字符串复制到strDestination。

必须要保证strDestination足够大,能够容纳下strSource,否者的话,就会造成溢出错误。

返回值为目的字符串,即strDestination。

而我们的程序中的main()函数中的password定义为128位的字符数组,而main()函数中if语句调用的auth()函数中定义的pwd为16位的字符数组,并且在auth()函数中strcpy()函数将password的值赋值给了pwd。

如果我们输入的password大于16位,这就造成了溢出错误。

1)在我们输入和需要比对的字符串test相同时,就会返回正确的密码;2)如果我们输入的密码大于test,但是并不超过16位,此时不会造成溢出错误,但是会返回“wrong password”。

之所以会返回“wrong password”,是因为在auth()函数中使用strcmp()函数进行比较我们输入的password和“test”的值的大小时,strcmp()函数返回的值大于0,又因为if语句对strcmp()函数我的返回值取非,所以if语句判断的值小于0,就会返回flag=0。

之后将返回的结果交于main()函数中的if语句进行判断,此时,就符合else,就会打印输出“wrong password”。

3)如果我们输入的password的位数大于16位,此时就会造成溢出错误,但是同样会输出“wrong password”。

正常情况下,我们应该对输入的密码进行判断,如果输入的密码的位数大于16位,就不允许进行auth()函数中的strcpy()复制操作,这样就不会造成溢出错误了。

(2)画出栈结构局部变量flag、pwd、passowrd存放的位置EBP存放的位置EIP存放的位置auth()函数的返回值(3)补充auth方法,在auth()函数中,对传递进来的参数password进行长度的判断,示例代码如下:int auth(const char* password){int flag = 0;char pwd[16];if(strlen(password)>16){printf("输入字符串超出范围,请重新输入!\n");}else{strcpy(pwd, password);}pwd[0] = 't';if(!strcmp(pwd, "test")){flag = 1;}return flag;}2、设计具有溢出的程序,并解释说明示例代码如下:/*Author: 孤烟逐云Time: 2020/3/11*/#include <stdio.h>#define PASSWORD "root1233"int verify(char *password) // 定义验证用户输入的密码是否正确的函数{int auth;char buffer[8]; // 定义buffer字符数组的长度为8auth = strcmp(password, PASSWORD); // 比较输入的字符串和定义密码是否相同strcpy(buffer, password); // 将用户输入的密码拷贝至bufferreturn auth;}int main(void){int flag = 0;char pass[30]; // 定义pass字符数组长度为30while(1){ // 永远为True,执行该程序就会提示用户输入密码printf("enter the password:\t");scanf("%s", pass); // 提示用户输入密码flag = verify(pass); // 调用验证用户输入的密码是否正确的函数if(flag==0){ // 判断输入的密码如果相同,就跳出验证printf("congratulation!\n");break;}else{ // 如果用户输入的密码不正确,就提示用户再次输入 printf("password incorrect! \n");}}}执行结果如下:(1)输入密码不正确就会提示用户再次输入,输入的密码正确的的话,就会打印出congratulation,并且跳出if语句。

(2)让输入的密码不正确,并且长度超过定义的最大长度,就处于中断状态。

相关文档
最新文档