溢出漏洞原理及利用
本文是作者学习过程的笔记整理而来的,如有错误,还请见谅!
实验环境
- Windows 10
- Visual Sutdio 2015
- x32dbg(x64dbg)
- *010Editor
实验目的
- 学习溢出漏洞的原理
- 学会手工查看程序崩溃日志
- 利用程序的溢出漏洞执行自己的代码
编写一个简单的有溢出漏洞的程序
代码:
// ConsoleApplication_shellcode.cpp : 定义控制台应用程序的入口点。
//即与ConsoleApplication_shellcode.exe是一个程序
#include "stdafx.h"
#include<windows.h>
int VerifyPassword(char* pszPassword,int nSize)
{
char szBuffer[50]={0};
memcpy(szBuffer, pszPassword, nSize);
return strcmp("Hades", szBuffer);
}
int main()
{
int nFlag = 0;
char szPassword[0x200] = {0};
FILE* fp;
LoadLibraryA("user32.dll");
if (NULL == (fp = fopen("password.txt", "rb")))
{
MessageBoxA(NULL, "Open File Fail", "error", NULL);
exit(0);
}
fread(szPassword, sizeof(szPassword), 1, fp);
nFlag = VerifyPassword(szPassword, sizeof(szPassword));
if (nFlag)
{
printf("password err\n");
}
else
{
printf("password ok\n");
}
fclose(fp);
system("pause");
return 0;
}
项目设置:
为了程序忽视警告正常生成,也为了之后测试方便,需要配置一下项目环境
编译运行:
代码完成,项目设置完成,直接编译成exe
运行前新建一个password.txt,打开其输入一些字符,双击测试exe
程序崩溃(自己故意写的崩溃代码,这效果是当然正常.其实崩溃在函数返回),一个有溢出漏洞的测试程序完成.
查看程序崩溃日志,找到崩溃点
查看日志
打开 控制面板-管理工具-事件查看器-Windows日志-应用程序
找到崩溃程序的日志,查看信息如图
异常代码:0xC0000005—————表示内存访问异常
异常错误偏移量:0x38383838—–即输入的8888的ASCII码
定位错误
为了定位错误,把文本改为如下图字符串
(中途VS程序出现问题,重新又写了一次源程序,所以程序名称有点不一样,实际
ConsoleApplication_bug.exe==ConsoleApplication_shellcode.exe):
再次运行程序,查看崩溃日志
找到password.txt中的0xE3E4处,改成1111测试
错误偏移量正好是1111的ASCII码,所以正确定位到了错误地址处.
调试验证
使用x32dbg调试器打开程序验证刚才测试的溢出地址
执行过memcpy函数
栈中的地址数据为0x31313131.
所以验证正确.memcpy函数拷贝字节过多,淹没了VerifyPassword函数栈中的返回地址.所以返回时找不到错误数据地址中的代码.(如果地址为系统领空,系统拒绝访问,自然报异常0xC0000005)
这就是一个简单的例子,也是溢出漏洞的产生原理
PS:
本来是个很长的文章,后边会简单说利用这个溢出地址执行一些简单代码.但是今天很晚了,明天写在下一篇文章里吧
第一次写博客文章.跟笔记不一样,总是改改改.大家见谅.