软件漏洞
- 造成软件漏洞原因:
- 如何预防?
- 软件漏洞常见名词
- ```栈溢出漏洞```
- 复现前准备
造成软件漏洞原因:
本质原因是因为人类目前还没办法在原点上区分数据与代码,说白了就是目前人们还没理解编写安全代码的真正方法。
如何预防?
通过修改自身代码、公共库函数的安全性降低漏洞出现频率,并且通过操作系统干预,使得漏洞攻击变得难以实现。
软件漏洞常见名词
vulnerability:漏洞、计算机安全隐患。Exploit[ik 'splbrt] :漏洞利用。
Shellcode:壳代码
Payload:有效荷载,payload是 shellcode 的一部分, shellcode_的执行往往就是为了给 payload代码开辟道路,说白了就是真正干坏事的代码。
栈溢出漏洞
复现前准备
栈溢出漏洞是一个很经典且非常危险的漏洞,我们来写一个简单的代码复现并了解一下它的原理。
在我们项目属性中将选项设置如下。使用Release版本x86进行调试。
#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include<iostream>
int checkPassword(const char* password)
{
int result = 1;
char buff[7]{};
result = strcmp(password, "51hook");
strcpy(buff, password);
return result;
}
int main()
{
int flag = 0;
char password[0x500];
while (1)
{
printf("请输入密码\n");
int result = scanf("%s", password);
flag = checkPassword(password);
if (flag)
{
MessageBoxA(0, "密码错误!", "提示", MB_OK);
}
else
{
MessageBoxA(0, "密码正确!", "提示", MB_OK);
break;
}
}
return 0;
}
可以看到我们正常执行输入错误密码会弹窗错误,接下来我们要通过栈溢出漏洞来绕过密码检测,让他提示正确。
我们拿出release版的32位exe文件进行调试。
找到我们的main函数位置
我们在过程中会调用scanf函数,来输入wwwwww
步进到我们的checkpassword时停止,我们进入函数查看。
前面先提升堆栈并初始化栈空间
然后把输入的和要检测的都压入堆栈。
到目前为止一切正常
当我们执行完strcpy函数时我们就能够发现在值钱开辟的堆栈空间中,***我们之前输入的字符串放进去了,放到了我们的buff缓冲区中,***但是这个时候问题就出现了,我们之前定义缓冲区大小为0x500而我们在checkPassword函数中定义时buff缓冲区大小只有7
.我们验证的密码51hook加上\0正好为7,但是传进来的password大小要远比这个缓冲区大小要大,我们这时只输入了6个w,也就是并没有超出缓冲区的界限,可以看到我们的buff缓冲区也成功存储了wwwwww,我们再往下看。
下一条指令我们将mov eax,[ebp-4],ebp-4存的是什么?从正向代码我们可以知道这是我们的result局部变量
,通过将其置1 来判断我们输入的密码输入正确还是错误,通过上面分析我们可以得知password大小远超出buff缓冲区大小,而从上图我们可以得知这 关键的返回值result=0x00000001中重要的01紧紧挨着我们的buff缓冲区
,那我们是不是可以通过控制这个关键的01给他改为00,让result=0x00000000从而绕过密码的检测直接达成密码正确的目的呢?我们来试一下
重新运行我们的exe文件,这回我们在输入时,输入wwwwwwww八个w,因为上文我们知道buff缓冲区大小只有7个,因为对齐才成为8个,在我们输入完后字符串他会看到\0才会停止,我们输入8个w,所以他在原本01的位置就会自动补为0,而我们要修改01为00,的目的也就达到了。
我们可以看到以前的01部分已经被我们的输入覆盖掉了成了00,让我们把他执行完。
可以确实的看到虽然我们并没有输入正确的密码,我们也绕过了验证,达到了我们想要的效果,这就是栈溢出漏洞。