下面是一个用C语言写出登录程序,
如果输入的密码正确,则输出your password is right
,登录成功,如果不正确,则输出your password is not right
,登录失败。
代码如下:
#include <cstdio>
#include<cstring>
using namespace std;
char realpassword[7]="012345";
int main()
{
char password[7];
bool isright=false;
printf("please enter a 6 words password\n");
scanf("%s",password);
if(strcmp(realpassword,password)==0){
isright=true;
}
if(isright){
printf("your password is right");
}else{
printf("your password is not right");
}
return 0;
}
需要输入一个六位的密码,输入正确则允许进入系统。
常规正确输入:
please enter a 6 words password
012345
your password is right
常规错误输入:
please enter a 6 words password
000000
your password is not right
好了,现在来想一想如果在不知道密码的情况下也可以输出一个正确的结果。
在考虑这个问题之前,先考虑一个问题:
那就是,在内存中char password[7];
和bool isright=false;
是如何排列的?
因为他们都是局部变量,局部变量都在栈区,并且在这个程序中他们在内存里是相邻的,而且,isright在password的上面。
还有更重要的一点,!!!C语言里的数组是可以越界访问的。
好的,知道了这些,我们现在就可以在不知道密码的情况下成功登陆上面的这个系统(当然,我是故意让它可以被这么攻破的),我们只需要在输入的时候,利用password数组覆盖掉isright的值,使其为真。
很简单,只需要输入一个超过限制的字符串,并且保证覆盖后的bool值是true。
好的:知道了这些,就可以输入一个字符串999999999
来看看结果:
please enter a 6 words password
999999999
your password is right
好了,这个系统登录就被攻破了。
不过如果上面的程序把isright 和password 的定义顺序修改
bool isright=false;
char password[7];
就是这样,上面这招就不灵了。
在java里不可以直接操作内存,而且数组不能越界访问,所以不能完成上面的操作(应该是这样,改天试一试)。