大数跨境
0
0

DiX 研究院:简单的栈溢出原理与实验

DiX 研究院:简单的栈溢出原理与实验 网络安全枢密院
2024-01-09
0
导读:栈溢出是一种缓冲区溢出。


实验环境


  • 操作系统:Windows XP SP2

  • 编译器:Visual C++ 6.0

  • 编译选项:默认编译选项

  • Build版本:debug版本


栈溢出原理


栈溢出是一种缓冲区溢出。函数的局部变量通常保存在栈上,如果这些保存函数局部变量的缓冲区发生溢出,就是栈溢出。最经典的栈溢出利用方式是覆盖函数的返回地址,以达到劫持程序控制流的目的。

 

X86架构中一般使用指令call调用一个函数,并使用指令ret返回。CPU在执行call指令时,会先将当前call指令的下一条指令的地址入栈,再跳转到被调用函数。当被调用函数需要返回时,只需要执行ret指令,CPU会执行出栈操作,将栈顶的地址赋值给EIP寄存器。此时存入的地址叫做返回地址,是用来告诉被调用函数自己应该返回到调用函数什么位置的地址。理想情况下,取出的地址就是之前调用call存入的地址,这样程序就可以返回到父函数继续执行了。编译器会试图保证即便子函数使用了栈并修改了栈顶的位置,也会在子函数返回父函数前将栈顶恢复到刚进入子函数时的状态,从而确保取到的返回地址不会出错。



栈溢出实验


进行实验需要先编写一个存在栈溢出漏洞的程序,其程序源码如下:


运行结果如下:


此程序为一个简单的密码验证的程序,它读取password.txt中的数据传入verify_password(char* password)进行密码验证。此函数存在栈溢出的点为它调用了strcpy(buffer,password),将password复制到buffer数组中,但是没有检查password边界导致buffer数组溢出。


通过OLLYDBG调试到strcpy(buffer,password)返回。观察到的栈如下图


下图为当前函数栈的布局图:


如果我们通过填充buffer[],将函数的返回地址覆盖成buffer[]的首地址,那么当函数返回并调用RETN时,EIP就会被设置为buffer[]的首地址,从而改变程序的执行流程。

Payload内容如下图:


当password.txt文件内的payload被程序执行strcpy()填充进buffer[]后,栈如下图所示:


当执行RETN指令后,CPU会到0012FAF0去执行代码,从而改变了程序的运行流程,转而去执行我们填充的payload。Payload执行完如下图:


此次实验尝试了简单的静态定位返回地址的方法,存在一定的局限性,还有一些可以动态定位payload的方式,例如利用“跳板”——jmp esp去动态的定位payload。

作者

李国浩

华清信安


  精彩回顾  

1

DiX 研究院:jangow-01-1.0.1靶机复现

2

数据安全系列(五)丨数据跨境传输

3

《证券期货业网络和信息安全管理办法》内容解读


【声明】内容源于网络
0
0
网络安全枢密院
北京华清信安科技有限公司是国家高新技术企业和中关村高新技术企业,以智能运营构筑数字安全基石为使命,致力于为客户提供卓越的新一代智能安全运营解决方案和专业安全咨询服务。
内容 123
粉丝 0
网络安全枢密院 北京华清信安科技有限公司是国家高新技术企业和中关村高新技术企业,以智能运营构筑数字安全基石为使命,致力于为客户提供卓越的新一代智能安全运营解决方案和专业安全咨询服务。
总阅读1
粉丝0
内容123