万能密码

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

#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!!!

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