zoukankan      html  css  js  c++  java
  • win7环境下一次浅谈栈溢出

    在我们的生活中,存在的许许多多的漏洞,下面像大家介绍的就是平时比较常见的栈溢出漏洞的实践过程。

    下面,我们用一个非常简单的例子来让大家对栈溢出漏洞有个直观的认识。

    这是一个简单的密码验证程序,但因为代码不严密,导致了栈溢出漏洞的产生。

    #include<stdio.h>

    #include<string.h>

    #define PASSWORD "1234567"

    int verify_password (char *password)

    {

             intauthenticated;

             charbuffer[8];//定义一个大小为8字节的数组,控制没溢出的字符串长度;(超出这个长度就发生溢出)

             authenticated=strcmp(password,PASSWORD);

             strcpy(buffer,password);//这个语句就直接导致了溢出的发生

             returnauthenticated;

    }

    main()

    {

             intvalid_flag=0;

             charpassword[1024];

             while(1)

             {

                       printf("请输入密码:");

                       scanf("%s",password);

                       valid_flag=verify_password(password);

                       if(valid_flag)

                       {

                                printf("密码错误! ");

                       }

                       else

                       {

                                printf("恭喜,你通过了验证! ");

                                break;

                       }

             }

    }

    具体的运行情况如下:

    wKioL1ZZlSGA7AodAABF_ZeE4mE042.png图1

    wKiom1ZZlMiyNlloAABCzWZ-3o4139.png

    但是,如果我们输入这样的密码,它也能通过

    那么,出现这种情况的原因是什么呢?

    wKiom1ZZlNmAGlWFAAHjIzoAXFc385.png图3

    这是程序运行时栈的情况。

    学过C语言的人应该知道,我们一个字符串的结尾是以字符串截断符null作为字符串结束标志。在这个程序中,我们开始定义的char型buffer数组长度为8,如果你输入的密码长度不等于8的话,那么这个密码验证程序的功能还是完善的,但是如果你的密码长度为8的话,这个栈溢出漏洞的危害就显现出来了。密码长度为8,buffer字符串数组的’结束标志就会溢出至int authenticated的内存空间内,并将原来的数据覆盖。

             观察源代码我们不难发现,authenticated变量的值来源于strcmp函数的返回值,之后会返回给main函数作为密码验证成功与否的标志变量:当authenticated为0时,表示验证成功,反之,验证不成功。

    光说不管用,下面我们用ollydbg来验证一下到底是不是这样。

    wKioL1ZZlUTDtv_jAAB_-5wmLCU101.png

    图4

    这里,我们输入8个q。

    wKioL1ZZlU6Q8KpnAAFwbTBhfRY473.png

    图5

    wKiom1ZZlPaAFpqsAAAhVf7DRSQ320.png

    图6

    在ASCII中71代表q。

    在图6中,我们可以清楚地看到,8个q将buffer数组全部占满,字符串截断符溢出至0018FB4C(即原authenticated的位置)。

    栈的具体变化情况如下表:

    wKioL1ZZlWGy2uv9AAAqmyoSVOA498.png

    通过上面的解释,我想大家对栈溢出有了个初步的认识。在这里介绍的栈溢出漏洞看起来很简单,但实际上栈溢出是最常见的内存错误之一,也是攻击者入侵系统时所用到的最强大、最经典的一类漏洞利用方式。

    注意:

    1、  在观察内存的时候应当注意内存数据与数值数据的区别,电脑在存储数据的时候并不是按照我们平时记忆的方式存储。在调试环境中,内存有低到高分布,但在数值应用的时候确实由高位字节向低位字节进行解释。

    2、  在输入密码时,如果你输入的字符串小于原来定义的密码,是不能冲破验证程序的。

    3、  这个实验是在win7 64位环境下完成的,在其他环境下栈溢出的原理相同,但内存地址不同。

  • 相关阅读:
    LeetCode 242. Valid Anagram (验证变位词)
    LeetCode 205. Isomorphic Strings (同构字符串)
    LeetCode 204. Count Primes (质数的个数)
    LeetCode 202. Happy Number (快乐数字)
    LeetCode 170. Two Sum III
    LeetCode 136. Single Number (落单的数)
    LeetCode 697. Degree of an Array (数组的度)
    LeetCode 695. Max Area of Island (岛的最大区域)
    Spark中的键值对操作
    各种排序算法总结
  • 原文地址:https://www.cnblogs.com/wh4am1/p/6611035.html
Copyright © 2011-2022 走看看