欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]栈溢出漏洞利用原理

[原创]栈溢出漏洞利用原理

下面的代码引自《shellcoder's handbook》英文版,中文版中没有这一节,可能是漏译,也可能是有意为之。下面的过程是经过本人调试并测试通过的,请不要套用,因为不同的平台,其结果可能也是不同的,至少我调试得到的字节数跟书中作者调试得到的字节数是有出入的,但是思路是相同的。
用例代码
overflow.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int valid_serial(char *psz)
{
  size_t len=strlen(psz);
  unsigned int total=0;
  size_t i;
  if(len<10)
    return 0;
  for(i=0;i<len;i++)
  {
    if((psz[i]<'0')||(psz[i]>'z'))
      return 0;
    total+=psz[i];
  }
  if(total%853==83)
    return 1;
  return 0;
}
int validate_serial()
{
  char serial[24];
  fscanf(stdin,"%s",serial);
  if(valid_serial(serial))
    return 1;
  else
    return 0;
}
int do_invalid_stuff()
{
  printf("Invalid serial number!\nExiting\n");
  exit(1);
}
int do_valid_stuff()
{
  printf("The serial number is valid!\n");
  exit(0);
}
int main(int argc,char *argv[])
{
  if(validate_serial())
    do_valid_stuff();
  else
    do_invalid_stuff();
  return 0;
}

编译:gcc  -g  overflow.c  -o  overflow
首先使用GDB调试overflow,在主函数处设置断点,如图1

图1
运行程序至断点处,反汇编EIP所指地址处的代码,如图2

图2
从上图,可以看到,do_valid_stuff的函数调用地址为0x08048629,记下这个地址,稍后我们会用到这个地址,改变程序的执行流程。同时,记下call指令的下一条指令的地址,也就是0x08048625,这个值将会在后面遇到。此时,查看一下eax,ebx,ecx,edx,ebp,esp寄存器的内容,如图3

图3
从上图中我们可以看到此时寄存器esp的值是0xbffff3d0,因此在调用validate_serial函数之前,我们看看栈中的内容,如图4

图4
从图中可以看到在调用函数之前,寄存器esp所指的值为0x08048650.
现在来看看validate_serial函数的反汇编结果,如图5

图5
当我们进入函数时,反汇编一下,看看我们的程序运行到何处,如图6

图6
从上图中我们可以看出,目前已经进入到validate_serial函数内,但是该函数的第一条指令还没有执行。此时,我们来看看栈中的情况,如图7

图7
注意看0xbffff3cc地址处的值,其值是0x08048625,这个值是不是有点儿眼熟,看看我们的图1,它是不是call指令的下一个指令的地址,我们要覆盖的值就是它。在图中我们还看到了地址为0xbffff3d0的值是0x08048650,这个值是不是也很眼熟。从这条信息中,我们可以得到一个信息,在进行函数调用时,call指令会将该指令的下一条指令的地址放入到栈中,之后给函数分配栈大小。
当我们多执行几条指令时,如图8

图8
此时,从代码中我们可以看到,系统给该函数分配了0x38个字节,分析一下代码你会发现 -0x20(%ebp)的地址其实就是我们的fscanf将获取到的字符串存储到栈中的地址,我们要覆盖的就是从该处到返回地址之间(包括返回地址)的字节数,也就是0x20+0x4+0x4,第一个4是push  %ebp指令占用的4字节,第二个4就是我们要改写的地址字节数,其值我们改写为do_validate_stuff的地址,也就是0x08048629.因此,因此我们构造的字符串如下:
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDD\x29\x86\x04\x08
当我们执行如下命令时,它就会跳到我们指定的调用地址处,这样我们就可以如愿以偿地改变了程序的执行流程.
printf  “AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDD\x29\x86\x04\x08”|./overflow
如图所示:

图9
当我们输入13个H时,其结果也是如此,如图所示:

图10
有不对之处,还请不吝赐教!

上传的附件 overflow-eight.png
overflow-eleven.png
overflow-five.png
overflow-four.png
overflow-nine.png
overflow-one.png
overflow-seven.png
overflow-ten.png
overflow-three.png
overflow-tow.png
1.png
2.png

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功