万能密码
前两天的时候,我一直在思考写电话薄的事情,很多程序,都是需要登录,而且需要密码才才能进入程序。所以我也写了个验证密码的小程序,我们来看看这个小程序:
#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那行代码用下面的替换:
{
szIn[n] = getchar();
}
szIn = \0";
这样的话就会自动切断啦!不会撑破啦!
但是仔细一想,也不行的啊,因为虽然不会撑爆,但是当程序一运行,原始密码肯定也在内存里的啊。是不是这样的呢,我们打开可执行文件看看。
我们首先运行我们的程序,然后用WinHex打开运行的程序,然后你随便输入1个密码,然后再在WinHex中查找你刚才输入的密码,如下图:
我晕啊!就在我们随便输入的密码下面就是真正的密码,差不多就在隔壁呢!这样的话,我们很轻松就得到了真正的密码,而且还可以把真正的密码给改啦!
看来啊!写这样的密码验证根本没有任何意义,但是我通过学习这个更加清楚的知道了内存的排列,和数组越界访问的弊端和其利用价值。我相信随便以后的学习,我会知道如何去写程序,不会这么轻松让人给攻破密码。同时以后也会学习如何利用一些漏洞在别人的程序里跑自己的代码!加油O!!!
关于通过漏洞控制程序的流程,以及在别人的程序里跑自己的代码,我会在自己学习了以后再写笔记!这个问题暂时就到这里啦!哈哈!真有意思!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述