zoukankan      html  css  js  c++  java
  • 栈溢出漏洞利用原理

    栈溢出漏洞利用原理

    2013-12-26 21:21 3686

    下面的代码引自《shellcoder's handbook》英文版,中文版中没有这一节,可能是漏译,也可能是有意为之。下面的过程是经过本人调试并测试通过的,请不要套用,因为不同的平台,其结果可能也是不同的,至少我调试得到的字节数跟书中作者调试得到的字节数是有出入的,但是思路是相同的。
    用例代码
    overflow.c
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #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! Exiting ");
      exit(1);
    }
    int do_valid_stuff()
    {
      printf("The serial number is valid! ");
      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.因此,因此我们构造的字符串如下:
    AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDx29x86x04x08
    当我们执行如下命令时,它就会跳到我们指定的调用地址处,这样我们就可以如愿以偿地改变了程序的执行流程.
    printf  “AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDx29x86x04x08”|./overflow
    如图所示:

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

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

    《0day安全 软件漏洞分析技术(第二版)》第三次再版印刷预售开始!

  • 相关阅读:
    iOS 关于使用xib创建cell的两种初始化方式
    KVO的初级使用
    通知的初级使用
    C语言的变量 常量
    C语言的编译 链接
    1 hello word
    java 中 == 与 equals引出的字符串比较
    02PSP0级及登陆界面开发
    00软工课程引言
    06动手动脑
  • 原文地址:https://www.cnblogs.com/bonelee/p/13759593.html
Copyright © 2011-2022 走看看