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 eaxgadget的地址(用于覆盖saved EIP)- shellcode
核心原理拆解
1. 初始方案失败的可能原因
直接用jmp eax跳转到缓冲区起始执行shellcode时,存在两个关键问题:
- 若shellcode位于缓冲区的高地址区域(靠近saved EIP),执行shellcode中的
push等栈操作时,栈指针ESP会向低地址方向移动(x86栈向下增长),可能覆盖shellcode的前半部分,导致执行非法指令崩溃。 - 函数返回后,原栈帧的缓冲区区域可能被后续栈操作(如调用其他函数)覆盖,导致shellcode被破坏。
2. 可行方案的执行流程
当漏洞函数执行到ret指令时:
ret弹出栈顶的jmp eax地址到EIP,ESP自动+4(指向shellcode的起始地址)。- 执行
jmp eax,跳转到EAX指向的缓冲区起始地址(即6条NOP的开头)。 - 依次执行NOP指令,直到遇到
jmp esp指令。 - 执行
jmp esp,直接跳转到当前ESP指向的地址——也就是shellcode的起始位置,开始执行shellcode。
3. 为什么jmp esp能解决问题
jmp esp将执行流直接引导到当前栈顶位置,而栈顶恰好是我们放置shellcode的区域,完全避开了原缓冲区可能被覆盖的问题。- 即使原缓冲区的NOP sled或
jmp esp指令被轻微破坏,前面的NOP sled也能保证执行流顺利到达jmp esp,确保跳转的可靠性。
内容的提问来源于stack exchange,提问作者Jacopo Bracaloni
相关产品推荐
相关产品推荐

