漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

漏洞挖掘前言

题目

Lab

Buffer Overflow Vulnerability Lab

Pre

1、阅读Basic Integer Overflows 这篇文章,大概描述整数溢出的原因和危害。
http://www.phrack.org/issues.htmlssue=60&id=10#article

上面这段代码如何才能执行到system(“/bin/sh”)处/p>

2、阅读堆溢出的文章Once upon a free()… 
http://www.phrack.org/issues.htmlssue=57&id=9#article。比较堆溢出和栈溢出的异同。

3、(一定要做)上网搜索利用jmp esp或者call esp来进行栈溢出的文章并且仔细阅读,解释这种技术的优点。

 

 

解答

Lab

Buffer Overflow Vulnerability Lab

Task1: Exploiting the Vulnerability

Step1:编译漏洞代码并赋权

编译stack.c文件,关闭栈保护并设置栈可执行。赋予程序SUID权限,关闭地址随机化。

$ su root

Password (enter root password)

# gcc -o stack -z execstack -fno-stack-protector stack.c

# chmod 4755 stack

# exit

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

 

Step2:通过调试获取返回地址位置

调试程序stack,对main函数进行反汇编。

disas main含义为显示main函数对应的汇编代码

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

可以看出,bof函数的调用地址为0x080484fa,bof函数正常返回地址为0x080448ff。所以接下来我们要在bof函数中找到程序结束时的地址。

反汇编bof函数:

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

可以看出bof函数在地址0x0804849c处结束,我们应该将此处地址的内容改为我们shellcode的地址,使得程序结束时直接跳转到我们精心编辑的恶意代码上。这里我们就要使用缓冲区溢出来修改返回地址。

 

Step3:改写exploit代码,为寻找buffer初始地址做准备

在exploit.c函数中添加我们自己的代码,目的是找到栈中b0uffer一开始的写入位置,做个标记。

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

编译并执行:

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

 

Step4:查找返回地址和buffer的距离

既然我们已经知道bof函数在地址0x0804849c处结束,那我们可以在该处设置断点,然后查看此时栈中的内容。

gdb中我们可以使用examine命令(简写是x)来查看内存地址中的值。所以x/16xw $esp的含义是从内存地址$esp读取内容,w表示以4字节为一个单位,16表示输出16个单位,x表示按十六进制格式显示变量。

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

由图中可以看出,返回地址和badfile里我们写入的AAAA相差36个字节,这意味着在badfile里,我们只要在shellcode地址前,加上36个任意字符,即可将原返回地址改变为恶意代码地址,引导程序跳转。

 

Step5:编写溢出攻击代码,实施攻击

这时我们已经知道了返回地址的储存位置和改写方法,接下来我们就要知道shellcode的地址。在本次实验中shellcode在stack程序执行时,是被放入栈中的(这也是我们为什么编译时选择栈可执行的原因),所以从原理上来说,我们只要把shellcode放在buffer的恶意代码返回地址之后,即buffer[40]以后就行,而且是可以精确计算的。

但是值得注意的是,gdb下堆栈位置和我们真实执行程序时的位置会有偏差,所以我们要多次修改我们的shellcode地址才能成功。这里我们借助nop来提高命中率。在提供的代码中,已经使用nop对整个buffer进行了初始化,所以我们并不需要额外添加写入nop的语句。

这里我们选择在离buffer[0]300个字节处再开始存放我们的shellcode,为的是留出充分的nop作为对偏差的缓冲。由于buffer是会前移还是后移我们并不清楚,所以我们取300-40的一半(40是指前面36个字符+4个字节的返回地址,确保指针落在nop中间),也就是将shellcode的地址视为:buffer[170],即0xbffff118+170=0xbfff1c2。

综上,在exploit.c添加我们的代码如下:

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

重新编译exploit.c并执行,执行有漏洞的程序stack,发现攻击成功:

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

 

 

Task 2: Address Randomization

执行命令# /sbin/sysctl -w kernel.randomize_va_space=2,打开地址随机化。

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

由于地址每次都在变换,所以攻击难度大大增强。

使用while语句循环攻击,执行了半个小时,但是仍然没有成功,随机性可能是太强了。

 

Task 3: Stack Guard

编译stack.c文件时,打开栈保护机制,执行task1操作。即使用以下语句编译:

$ su root

Password (enter root password)

# gcc -o stack -z execstack stack.c

# chmod 4755 stack

# exit

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

可以看出由于栈保护机制,攻击失败。

 

Task 4: Non-executable Stack

编译stack.c文件时,关闭栈可执行,执行task1操作。即使用以下语句编译:

$ su root

Password (enter root password)

# gcc -o stack -z noexecstack -fno-stack-protector stack.c

# chmod 4755 stack

# exit

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

可以看出由于栈不可执行,攻击同样失败。

 

 

Pre

1、阅读Basic Integer Overflows 这篇文章,大概描述整数溢出的原因和危害。http://www.phrack.org/issues.htmlssue=60&id=10#article

上面这段代码如何才能执行到system(“/bin/sh”)处/p>

 

整数溢出:由于计算机中整数都有一个宽度,因此它就有一个可以表示的最大值。当我们试图保存一个比它可以表示的最大值还大的数时,就会发生整数溢出。整数溢出的危害:在整数溢出确实发生之前我们是无法得知它会溢出的,因此程序是没有办法区分先前计算出的值是否正确。如果计算结果作为一个缓冲区的大小或数组的下标时将会非常危险。

对于上述这段漏洞代码,是一个典型的整数溢出。我们知道一个单位所能表示的最大正整数总是比能表示的最小负整数的绝对值小1,所以如果我们能把最小负整数除以负一,那么将得到比最大正整数大一的数,从而导致整数溢出。

而如果代码出现了错误,查询signal函数作用可知sig是传递给它的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。所以当发生整数溢出时将会立即执行catcher函数,从而达到我们的目的。

漏洞挖掘——实验6 Buffer Overflow Vulnerability Lab

 

2、阅读堆溢出的文章Once upon a free()…

http://www.phrack.org/issues.htmlssue=57&id=9#article。比较堆溢出和栈溢出的异同。

 

栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围。简单来说栈溢出就是数据被写到了不应该写的地方,从而导致种种隐患。

堆溢出的产生是由于过多的函数调用,导致调用堆栈无法容纳这些调用的返回地址,一般在递归中产生。堆溢出很可能由无限递归产生,但也可能仅仅是过多的堆栈层级。

 

3、(一定要做)上网搜索利用jmp esp或者call esp来进行栈溢出的文章并且仔细阅读,解释这种技术的优点。

shellcode在内存中的起始地址往往不固定,导致漏洞利用不一定成功,通过jmp esp的方式可以解决这个问题。

ESP寄存器总是指向返回地址的下一地址。如果用jmp esp覆盖返回地址,那么在函数返回后会执行jmp esp,跳到esp,也就是返回地址的下一地址开始执行。因此,将shellcode放于返回地址之后,并将返回地址覆盖为jmp esp,就可以避免shellcode在内存中产生的移位问题。

 

 

 

来源:一半西瓜

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年3月14日
下一篇 2019年3月14日

相关推荐