关于 [栈溢出后jmp esp执行shellcode] 原理分析

Posted Yuri800

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于 [栈溢出后jmp esp执行shellcode] 原理分析相关的知识,希望对你有一定的参考价值。

    网上关于栈溢出后用jmp esp执行shellcode的文章有很多,感觉分析的都没有戳到点,所以想结合自己调试的经历写下自己的想法。

正常情况下,函数栈分布图如下:

---->栈内存由低向高方向----->
|------------栈变量----------|----ebp----|------返回地址------|函数形参|
发生溢出后,以上栈空间的内容被覆盖,可能从上面的布局变成这样:

---->栈内存由低向高方向----->
|------------x90x90x90x90x90|x90x90x90..|shellcode缓存区的地址|x90x90.|
即,返回地址被改为一段缓存区的地址。当函数执行结束,从栈中取返回地址准备执行时,取到的是shellcode的地址,最终跳进shellcode执行。这段shellcode的地址一般被硬编码为某个地址,这个地址可以存在于程序空间的任何地方,只要有执行权限。

就像写代码时用绝对路径读取配置文件的内容,偶尔会出错一样,为了解决这种错误,可能会用相对程序运行时的路径去获取配置文件的内容。硬编码shellcode的地址也会出错,于是先人提出一种相对定位shellcode地址的方法,这就是jmp esp。

这用到了栈指针esp的一个特性:当函数执行ret指令后,Eip寄存器发生了跳转,但Esp还指向函数形参在栈中的地址。如示意图:

ret返回前 esp的位置:

---->栈内存由低向高方向----->
|------------栈变量----------|----ebp----|------返回地址------|函数形参|
                                        ^
                                        |
                                       esp指向这个位置
ret返回后 esp的位置

---->栈内存由低向高方向----->
|------------栈变量----------|----ebp----|------返回地址------|函数形参|
                                                            ^
                                                            |
                                                           esp指向这个位置
相对于Eip的跳跃性----ret以后Eip指向天南地北了,Esp具有相对比较稳定的连续性----至少在刚才栈内存的附近。于是,当Eip在后续执行过程中,遇到了jmp esp指令,仍会回到上图中esp指向的函数形参位置执行,执行shellcode的剩余部分。

跳转后,执行的位置确定了,剩下的问题就是寻找用户可访问空间中,哪段内存地址包含了jmp esp这样的指令。于是OD可能提供了这样的插件,用于寻找这样的地址,比如找到0x00ABCDEF这个地址上包含了jmp esp指令。于是,栈溢出后,在返回地址处填入0x00ABCDEF。当被溢出的函数执行ret指令时,首先会跳转到0x00ABCDEF处取指执行。取到的结果是jmp esp,于是Eip被设置成Esp的值---即上图中本是存放函数形参,现在被shellcode覆盖的栈内存处继续执行


以上是关于关于 [栈溢出后jmp esp执行shellcode] 原理分析的主要内容,如果未能解决你的问题,请参考以下文章

避免 shellcode NASM 的 JMP CALL POP 技术中的 JMP?

PwnNotes-0x01 栈溢出(shellcode & ret2libc & ROP)

PwnNotes-0x01 栈溢出(shellcode & ret2libc & ROP)

堆栈认知——栈溢出实例(ret2shellcode)

堆栈认知——栈溢出实例(ret2shellcode)

软件安全实验——lab6(缓冲区溢出2:使用jmp esp或者call esp方法和修改函数指针)