You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROP中jmp esp用法疑问:picoCTF栈溢出shellcode执行失败求助

栈溢出问题分析与可行方案原理拆解

基础环境与初始信息

  • 目标程序:无PIE保护、未开启NX的32位ELF文件
  • 漏洞函数调试结论:执行ret指令时,EAX寄存器存储栈上缓冲区的起始地址;缓冲区起始到saved EIP的偏移量为28字节

初始思路与失败情况

初始方案构造的溢出 payload 为:NOP sled + shellcode,用jmp eax gadget覆盖saved EIP,意图跳转到缓冲区起始执行shellcode,但触发SIGSEGV,崩溃地址为0xff854a00。
使用pwntools asm生成的shellcode如下:

int 0x3   ; 调试用断点指令
xor eax, eax
push eax
push 0x0068732f
push 0x6e69622f
xor ebx, ebx
push eax
push ebx
mov ecx, esp
mov al, 0xb
int 0x80

可行payload构造方案

网上找到的有效payload结构(按写入顺序):

  • 6条NOP指令
  • 汇编后的jmp esp指令(机器码为0xffe4)
  • 20条NOP指令
  • jmp eax gadget的地址(用于覆盖saved EIP)
  • shellcode

核心原理拆解

1. 初始方案失败的可能原因

直接用jmp eax跳转到缓冲区起始执行shellcode时,存在两个关键问题:

  • 若shellcode位于缓冲区的高地址区域(靠近saved EIP),执行shellcode中的push等栈操作时,栈指针ESP会向低地址方向移动(x86栈向下增长),可能覆盖shellcode的前半部分,导致执行非法指令崩溃。
  • 函数返回后,原栈帧的缓冲区区域可能被后续栈操作(如调用其他函数)覆盖,导致shellcode被破坏。

2. 可行方案的执行流程

当漏洞函数执行到ret指令时:

  1. ret弹出栈顶的jmp eax地址到EIP,ESP自动+4(指向shellcode的起始地址)。
  2. 执行jmp eax,跳转到EAX指向的缓冲区起始地址(即6条NOP的开头)。
  3. 依次执行NOP指令,直到遇到jmp esp指令。
  4. 执行jmp esp,直接跳转到当前ESP指向的地址——也就是shellcode的起始位置,开始执行shellcode。

3. 为什么jmp esp能解决问题

  • jmp esp将执行流直接引导到当前栈顶位置,而栈顶恰好是我们放置shellcode的区域,完全避开了原缓冲区可能被覆盖的问题。
  • 即使原缓冲区的NOP sled或jmp esp指令被轻微破坏,前面的NOP sled也能保证执行流顺利到达jmp esp,确保跳转的可靠性。

内容的提问来源于stack exchange,提问作者Jacopo Bracaloni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:13:15