5.2 磁盘CRC32完整性检测
CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测,并以此来判定特定程序内存是否发生了变化,如果发生变化则拒绝执行,通过此种方法来保护内存或磁盘文件不会被非法篡改。总之,内存和磁盘中的校验技术都是用于确保数据和程序的完整性和安全性的重要技术。
磁盘CRC(循环冗余校验)用于检测磁盘数据的完整性,一般而言某些木马专杀工具同样会用到磁盘CRC特征校验技术,该技术的实现原理与内存验证原理完全一致,针对磁盘的验证同样很简单,但此处我们需要将计算到的CRC32
值存储到PE文件自身中,通常我们可以存储到PE文件的前一个DWORD
的位置上,程序运行后对比这个值,来判断程序是否被打过补丁,如果打过直接结束掉。
// 检查磁盘完整性
BOOL CalculateDiskCRC32()
{
char szFileName[MAX_PATH] = { 0 };
char *pBuffer;
DWORD pNumberOfBytesRead;
int FileSize = 0;
// 获取自身文件,并打开文件
GetModuleFileName(0, szFileName, MAX_PATH);
HANDLE hFile = CreateFile(szFileName, GENERIC_READ, 1, 0, 3, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return TRUE;
}
// 取文件长度
FileSize = GetFileSize(hFile, 0);
pBuffer = new char[FileSize];
// 读取文件到内存
ReadFile(hFile, pBuffer, FileSize, &pNumberOfBytesRead, 0);
CloseHandle(hFile);
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS32 pNtHeader = NULL;
pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
// 获取到NT头
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);
// 定位到PE文件头前4字节处
DWORD OriginalCRC32 = *(DWORD *)((DWORD)pNtHeader - 4);
printf("[*] 读出节表值 = %x \n", OriginalCRC32);
// 我们只需要计算PE结构的CRC32值,不需要计算DOS头
FileSize = FileSize - DWORD(pDosHeader->e_lfanew);
DWORD CheckCRC32 = CRC32((BYTE*)(pBuffer + pDosHeader->e_lfanew), FileSize);
printf("[+] 计算CRC32 = %x \n", CheckCRC32);
if (CheckCRC32 == OriginalCRC32)
{
return FALSE;
}
else
{
return TRUE;
}
return TRUE;
}
int main(int argc, char* argv[])
{
BOOL ref = CalculateDiskCRC32();
if (ref == TRUE)
{
printf("[-] 程序已被修改 \n");
}
else
{
printf("[+] 程序正常 \n");
}
system("pause");
return 0;
}
首先读者运行上述程序,则程序会输出当前的CRC32值be63ac8b
我们记下这个HASH值,如下图所示;
并将此值替换到如下图中的黄色位置,当程序运行后会读取该区域内的数据,并与动态计算的CRC32值进行计算,最终判断是否被修改,如下图所示;
通过CRC32数据对比并遍历磁盘文件,我们可以实现一个简单的特征定位查杀程序,用于专门定位某些特殊的程序,如下是修改后的代码片段;
// 计算文件CRC过程
BOOL CalcCRC32(char *FilePath)
{
// 打开文件
HANDLE hFile = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
// 获取文件大小
DWORD dwSize = GetFileSize(hFile, NULL);
if (dwSize == 0xFFFFFFFF)
{
return FALSE;
}
// 分配内存
BYTE *pFile = (BYTE*)malloc(dwSize);
if (pFile == NULL)
{
return FALSE;
}
// 读取内存
DWORD dwNum = 0;
ReadFile(hFile, pFile, dwSize, &dwNum, NULL);
// 计算CRC32
DWORD dwCRC32 = CRC32(pFile, dwSize);
if (pFile != NULL)
{
free(pFile);
pFile = NULL;
}
CloseHandle(hFile);
return dwCRC32;
}
int main(int argc, char* argv[])
{
WIN32_FIND_DATA stFindFile;
HANDLE hFindFile;
char *szFilter = "*.exe"; // 筛选所有的.exe结尾的文件
char szFindFile[MAX_PATH]; // 保存欲检测程序的路径
char szSearch[MAX_PATH]; // 保存完整的筛选路径
int ret = 0; // 搜索状态返回值
lstrcpy(szFindFile, "D:\\"); // 搜索D盘目录下的所有exe结尾的文件
lstrcpy(szSearch, "D:\\");
lstrcat(szSearch, szFilter);
DWORD dwTmpCRC32;
hFindFile = FindFirstFile(szSearch, &stFindFile);
if (hFindFile != INVALID_HANDLE_VALUE)
{
do
{
lstrcat(szFindFile, stFindFile.cFileName);
dwTmpCRC32 = CalcCRC32(szFindFile);
// 比较判断
if (dwTmpCRC32 == 0xbe63ac8b)
{
printf("[*] CRC32 = %x 发现病毒 %s \n", dwTmpCRC32, szFindFile);
}
else
{
printf("[-] CRC32 = %x 正常程序 %s \n", dwTmpCRC32, szFindFile);
}
// 删除程序名称只保留"C:\"
szFindFile[3] = '\0';
ret = FindNextFile(hFindFile, &stFindFile);
} while (ret != 0);
}
FindClose(hFindFile);
system("pause");
return 0;
}
运行程序输出效果如下图所示;
本文作者: 王瑞
本文链接: https://www.lyshark.com/post/7a9a55f0.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
5.2 磁盘CRC32完整性检测的更多相关文章
- 利用SHELL脚本实现文件完整性检测程序(1.2版更新)
一..开发背景 因时势所逼,需要对服务器的文件系统实行监控.虽然linux下有不少入侵检测和防窜改系统,但都比较麻烦,用起来也不是很称手.自己琢磨着也不需要什么多复杂的功能,写个脚本应该就可以满足基本 ...
- Linux AIDE(文件完整性检测)
一.AIDE的概念 AIDE:Advanced Intrusion Detection Environment,是一款入侵检测工具,主要用途是检查文档的完整性.AIDE在本地构造了一个基准的数据库,一 ...
- Linux 磁盘坏道检测和修复
今天在实验室碰到一台机器,根分区和/upgrade分区变成了read-only system.当碰到这个问题的时候,我的第一反应很可能硬件出现了故障,我使用了如下的方法来检测和排除故障: 使用dmes ...
- CRC32是什么?
CRC32:CRC本身是“冗余校验码”的意思,CRC32则表示会产生一个32bit(8位十六进制数)的校验值.由于CRC32产生校验值时源数据块的每一个bit(位)都参与了计算,所以数据块中即使只有一 ...
- 反调试——7——CRC检测
反调试--7--CRC检测 CRC32: CRC的全称是循环冗余校验,作用是为了检测数据的完整性. CRC32的检测原理: 程序被编译后,代码段是固定的,因为已经被写死了. 我们在调试程序的时候,打断 ...
- SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- FME之于规划CAD数据质量检测
最近琢磨规划CAD数据转换入库GIS方面的技术问题,看过一些前辈的文章/文献,对于使用FME WorkBench方面,有了一些了解,往往直接转换数据丢失比较严重,而且GIS对图形属性和空间拓扑比较严格 ...
- Metasploit是一款开源的安全漏洞检测工具,
Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,适合于需要核实漏洞的安全专家,同时也适合于强大进攻能力的 ...
- linux工具类之硬盘检测
软raidmount /dev/md0 /opt [root@localhost root]# cp /usr/share/doc/raidtools-1.00.3/ra ...
- 开源入侵检测系统OSSEC搭建之二:客户端安装
上一篇文章中已经将OSSEC服务端的安装以及客户端的Key导出操作做了解说,接下来在另一台虚拟机中安装客户端,与安装服务端类似同样需要安装ossec,步骤如下. 一.下载ossec-hids-2.8. ...
随机推荐
- C#设计模式19——装饰器模式的写法
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责,而不需要修改这个对象的代码. What(什么) 装饰器模式是一种结构型设计模式,它允许 ...
- RT_Device
以上图片来自网页,非原创
- 洛谷 P7579 「RdOI R2」称重(weigh) 题解
题意: 题目 一道交互题. 有 n 个球,里面有两个假球,假球比普通球的要轻,每次可以询问任意两组球的轻重关系,第一组轻为 < ,第二组轻为 > ,一样重量为 = . 思路: 先考虑在一个 ...
- STL-set(ACM)
1.set只能insert().erase(),没有push()等操作 2.插入的元素自动排序按从小到大的顺序排 3.不会插入相同的元素,已经插入了6,之后就不会再插入了 4.时间复杂度为 O(log ...
- Python实现猜拳小游戏的多种方式
简介 猜拳小游戏是一个经典的小游戏项目,也是初学者学习编程的必要练手题目之一.在 Python 中,我们可以使用多种方式来实现一个简单的猜拳小游戏. 本文将依次介绍六种Python实现猜拳小游戏的方法 ...
- mybatis-plus-generator-ui 可视化代码生成器!
它提供交互式的Web UI用于生成兼容mybatis-plus框架的相关功能代码,包括Entity,Mapper,Mapper.xml,Service,Controller等. 可以自定义模板以及各类 ...
- Atcoder-AGC033C
看到这道题,是个博弈论,没见过树上的,于是想到在数列里的博弈论,又联想到树的特殊形式----链. 于是我们来讨论一下链的情况(对于没有硬币的点,我们就视为它被删掉了): 讨论链的情况 发现若是选择两端 ...
- 【HarmonyOS】一文教你如何在低代码项目中跳转H5页面
[关键字] 元服务.低代码.H5页面跳转.WebView [1.写在前面] 今天我们来实现一个在低代码项目中通过按钮跳转到H5页面的功能,本项目是基于API6的JS工程,我们的实现思路是在页面B中 ...
- GO 集合 map 使用总结
转载请注明出处: Go语言的集合称为映射(map),它是一种无序的键值对(key-value)的集合,集合是通过键(key)来快速检索值(value)的,键(key)类似于索引,它指向值(value) ...
- Django App使用
App - 基本使用 作用主要用于业务功能模块开发 创建App > python manage.py startapp app01 创建成功后默认生成以下文件 默认文件讲解: 1. models ...