zoukankan      html  css  js  c++  java
  • 我也要学C语言第二十二章:给自己的代码找漏洞,然后自己攻击自己

    万能密码

      前两天的时候,我一直在思考写电话薄的事情,很多程序,都是需要登录,而且需要密码才才能进入程序。所以我也写了个验证密码的小程序,我们来看看这个小程序:

    #include "stdio.h"
    #include
    <string.h>

    void main()
    {
    char szPawd[16] ="dodolook";
    char szIn[16];
    int i =3;

    while(i--)
    {
    scanf(
    "%s", szIn);

    if (strcmp(szIn, szPawd) ==0)
    {
    printf(
    "登录成功!你是合法用户\r\n");
    break;
    }
    else
    {
    printf(
    "登录失败!请再尝试\r\n");
    }
    }

    }

    这个本意是检查用户输入的密码和设定的密码,一致的话就登录成功,不一致的话呢就登录失败!但是这个程序纯在万能密码,如果你输入1111111111111111任意密码 然后再输入你刚才输入的任意密码,就可以成功登录!我们来看看登录成功的图:

    这个原因其实因为先定义的变量在前面,后定义的变量在后面,而且是挨着的,然后用户输入密码撑爆了szIn变量,一般来说,撑爆了程序崩溃,但是如果通过静心构造后不但可以避免崩溃,而且还能影响到程序的执行流程,甚至可以让程序执行缓冲区里的代码,这样的话,就太危险了!

      我们来看看内存:

    那么该如何避免这样的情况发生了!我们可以这样做:

    我们可以针对scanf做1个限制。不能让它撑破了变量。我们把scanf那行代码用下面的替换:

    for(int n =0; n <sizeof(szPwd)/sizeof(char) -1; n++)
    {
    szIn[n]
    = getchar();
      if(szIn[n] == '\n')
      {
    break;
    }
    }
    szIn
    = \0";

    这样的话就会自动切断啦!不会撑破啦!

    但是仔细一想,也不行的啊,因为虽然不会撑爆,但是当程序一运行,原始密码肯定也在内存里的啊。是不是这样的呢,我们打开可执行文件看看。

      我们首先运行我们的程序,然后用WinHex打开运行的程序,然后你随便输入1个密码,然后再在WinHex中查找你刚才输入的密码,如下图:

    我晕啊!就在我们随便输入的密码下面就是真正的密码,差不多就在隔壁呢!这样的话,我们很轻松就得到了真正的密码,而且还可以把真正的密码给改啦!

      看来啊!写这样的密码验证根本没有任何意义,但是我通过学习这个更加清楚的知道了内存的排列,和数组越界访问的弊端和其利用价值。我相信随便以后的学习,我会知道如何去写程序,不会这么轻松让人给攻破密码。同时以后也会学习如何利用一些漏洞在别人的程序里跑自己的代码!加油O!!!

      关于通过漏洞控制程序的流程,以及在别人的程序里跑自己的代码,我会在自己学习了以后再写笔记!这个问题暂时就到这里啦!哈哈!真有意思!

  • 相关阅读:
    HTML基础 整理
    今天课堂总结
    课后习题
    JAVA的文件创建
    JAVA_输入输出流 异常处理
    12.23流水账号
    12.22 repeater 删除
    12.22 repeater 修改
    12.22 repeater 添加
    12.22 repeater 主页
  • 原文地址:https://www.cnblogs.com/dodolook/p/2096650.html
Copyright © 2011-2022 走看看