Anti VM专题

7、通过社会工程学检测虚拟机

一、课程目标

本节课主要学习如何通过社会工程学方法来检测虚拟机环境。社会工程学检测不是通过技术手段直接检测虚拟机特征,而是通过观察用户行为和环境特征来间接判断是否处于虚拟化环境。通过本课的学习,你将能够:

  1. 理解社会工程学在虚拟机检测中的应用
  2. 掌握通过用户交互行为检测虚拟机的方法
  3. 学会设计欺骗性测试来识别虚拟机环境
  4. 实现基于社会工程学的虚拟机检测代码
  5. 了解该技术的特点和局限性

二、名词解释表

名词解释
社会工程学通过心理操纵和欺骗手段获取信息的技术
用户行为分析通过观察用户操作模式来判断环境特征
交互检测通过与用户的交互来获取环境信息
欺骗性测试设计看似正常的测试来暴露虚拟机环境
环境感知通过多种线索判断运行环境的特征
反虚拟机心理学利用虚拟机用户行为特征进行检测

三、技术原理

3.1 社会工程学检测概述

社会工程学检测是通过设计特定的用户交互场景,观察用户的反应和行为模式来判断是否处于虚拟机环境。

3.2 虚拟机用户行为特征

虚拟机环境中的用户通常表现出以下特征:

  1. 操作谨慎性

    • 对未知程序更加警惕
    • 频繁查看任务管理器
    • 快速关闭可疑窗口
  2. 环境设置

    • 使用默认的虚拟机配置
    • 桌面背景和主题较为简单
    • 缺少个性化设置
  3. 交互模式

    • 鼠标移动轨迹较为规律
    • 键盘输入模式相对简单
    • 对提示信息反应迅速

3.3 检测原理

通过设计特定的交互场景和测试,观察用户的反应时间和行为模式,与正常用户的行为模式进行对比,从而判断是否处于虚拟机环境。

四、代码实现

4.1 基础交互检测

#include <windows.h>
#include <stdio.h>
#include <time.h>

// 用户行为记录结构
typedef struct _USER_BEHAVIOR {
    DWORD mouseMovementCount;
    DWORD keyPressCount;
    DWORD windowFocusChanges;
    DWORD responseTime;
    BOOL suspiciousBehavior;
} USER_BEHAVIOR, *PUSER_BEHAVIOR;

// 全局行为记录
static USER_BEHAVIOR g_userBehavior = {0};

// 钩子过程 - 监控鼠标移动
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0) {
        g_userBehavior.mouseMovementCount++;
    }
    
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

// 钩子过程 - 监控键盘输入
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0) {
        g_userBehavior.keyPressCount++;
    }
    
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

// 监控窗口焦点变化
LRESULT CALLBACK WindowHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0) {
        g_userBehavior.windowFocusChanges++;
    }
    
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

// 基础交互检测
BOOL DetectVMViaUserInteraction() {
    printf("=== 基础交互检测 ===\n");
    
    // 安装钩子
    HHOOK hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, GetModuleHandle(NULL), 0);
    HHOOK hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, GetModuleHandle(NULL), 0);
    
    if (!hMouseHook || !hKeyboardHook) {
        printf("安装钩子失败。\n");
        return FALSE;
    }
    
    // 显示一个看似正常的对话框
    printf("请在接下来的对话框中点击'确定'按钮。\n");
    
    DWORD startTime = GetTickCount();
    
    int result = MessageBoxW(NULL, 
                           L"请点击'确定'继续程序运行。", 
                           L"用户验证", 
                           MB_OKCANCEL | MB_ICONINFORMATION);
    
    DWORD endTime = GetTickCount();
    g_userBehavior.responseTime = endTime - startTime;
    
    // 卸载钩子
    UnhookWindowsHookEx(hMouseHook);
    UnhookWindowsHookEx(hKeyboardHook);
    
    printf("用户响应时间: %lu ms\n", g_userBehavior.responseTime);
    printf("鼠标移动次数: %lu\n", g_userBehavior.mouseMovementCount);
    printf("键盘按键次数: %lu\n", g_userBehavior.keyPressCount);
    printf("窗口焦点变化: %lu\n", g_userBehavior.windowFocusChanges);
    
    // 分析用户行为
    if (g_userBehavior.responseTime < 500) {
        printf("响应时间过短,可能是自动化操作。\n");
        g_userBehavior.suspiciousBehavior = TRUE;
        return TRUE;
    }
    
    if (g_userBehavior.mouseMovementCount < 5) {
        printf("鼠标移动次数过少,行为不够自然。\n");
        g_userBehavior.suspiciousBehavior = TRUE;
        return TRUE;
    }
    
    return FALSE;
}

4.2 改进的交互检测

// 欺骗性测试 - 假装系统更新
BOOL DeceptiveSystemUpdateTest() {
    printf("=== 欺骗性系统更新测试 ===\n");
    
    // 显示一个仿真的系统更新对话框
    printf("显示仿真系统更新对话框...\n");
    
    DWORD startTime = GetTickCount();
    
    // 创建一个仿真的更新对话框
    int result = MessageBoxW(NULL, 
                           L"系统检测到重要更新,是否立即安装?\n\n注意:安装过程中请勿关闭计算机。", 
                           L"Windows Update", 
                           MB_YESNO | MB_ICONWARNING);
    
    DWORD endTime = GetTickCount();
    DWORD responseTime = endTime - startTime;
    
    printf("用户对系统更新的响应时间: %lu ms\n", responseTime);
    
    // 分析用户反应
    if (result == IDYES) {
        printf("用户选择安装更新。\n");
        
        // 如果响应时间过短,可能是虚拟机环境
        if (responseTime < 1000) {
            printf("响应时间过短,可能是虚拟机环境。\n");
            return TRUE;
        }
    } else {
        printf("用户拒绝安装更新。\n");
        
        // 在虚拟机环境中,用户可能更倾向于拒绝未知更新
        return TRUE;
    }
    
    return FALSE;
}

// 欺骗性安全警告测试
BOOL DeceptiveSecurityWarningTest() {
    printf("=== 欺骗性安全警告测试 ===\n");
    
    DWORD startTime = GetTickCount();
    
    // 显示一个仿真的安全警告
    int result = MessageBoxW(NULL, 
                           L"安全警告:检测到潜在的安全威胁!\n\n建议立即运行杀毒软件进行全面扫描。", 
                           L"Windows Defender", 
                           MB_OKCANCEL | MB_ICONERROR);
    
    DWORD endTime = GetTickCount();
    DWORD responseTime = endTime - startTime;
    
    printf("用户对安全警告的响应时间: %lu ms\n", responseTime);
    
    // 分析用户反应
    if (responseTime < 800) {
        printf("用户对安全警告反应过快,可能是虚拟机环境。\n");
        return TRUE;
    }
    
    if (result == IDCANCEL) {
        printf("用户取消了安全警告操作。\n");
        // 虚拟机用户可能更倾向于取消未知的安全操作
        return TRUE;
    }
    
    return FALSE;
}

// 用户注意力测试
BOOL UserAttentionTest() {
    printf("=== 用户注意力测试 ===\n");
    
    // 显示一个需要用户仔细阅读的对话框
    int result = MessageBoxW(NULL, 
                           L"请仔细阅读以下条款:\n\n"
                           L"1. 本软件仅供学习研究使用\n"
                           L"2. 请勿用于非法用途\n"
                           L"3. 使用本软件即表示您同意以上条款\n\n"
                           L"请点击'我同意'继续。", 
                           L"软件许可协议", 
                           MB_OKCANCEL | MB_ICONINFORMATION);
    
    if (result != IDOK) {
        printf("用户未同意许可协议,行为可疑。\n");
        return TRUE;
    }
    
    return FALSE;
}

4.3 高级社会工程学检测技术

// 环境感知检测
BOOL EnvironmentalAwarenessTest() {
    printf("=== 环境感知检测 ===\n");
    
    // 检查桌面背景
    WCHAR wallpaperPath[MAX_PATH];
    if (SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, wallpaperPath, 0)) {
        printf("桌面背景: %ws\n", wallpaperPath);
        
        // 检查是否为默认壁纸
        if (wcsstr(wallpaperPath, L"Windows\\web\\wallpaper") != NULL) {
            printf("使用默认壁纸,可能是虚拟机环境。\n");
            return TRUE;
        }
    }
    
    // 检查屏幕分辨率
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    printf("屏幕分辨率: %dx%d\n", screenWidth, screenHeight);
    
    // 常见的虚拟机分辨率
    if ((screenWidth == 1024 && screenHeight == 768) ||
        (screenWidth == 800 && screenHeight == 600) ||
        (screenWidth == 1280 && screenHeight == 1024)) {
        printf("使用常见虚拟机分辨率。\n");
        return TRUE;
    }
    
    // 检查颜色深度
    HDC hdc = GetDC(NULL);
    int colorDepth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
    ReleaseDC(NULL, hdc);
    printf("颜色深度: %d\n", colorDepth);
    
    if (colorDepth < 32) {
        printf("颜色深度较低,可能是虚拟机环境。\n");
        return TRUE;
    }
    
    return FALSE;
}

// 用户习惯分析
BOOL UserHabitAnalysis() {
    printf("=== 用户习惯分析 ===\n");
    
    // 检查最近使用的程序
    DWORD processes[1024];
    DWORD bytesReturned;
    DWORD processCount;
    
    if (EnumProcesses(processes, sizeof(processes), &bytesReturned)) {
        processCount = bytesReturned / sizeof(DWORD);
        printf("当前运行进程数: %lu\n", processCount);
        
        // 虚拟机环境中进程数通常较少
        if (processCount < 30) {
            printf("运行进程数较少,可能是虚拟机环境。\n");
            return TRUE;
        }
    }
    
    // 检查系统运行时间
    DWORD uptime = GetTickCount() / 1000;  // 转换为秒
    printf("系统运行时间: %lu 秒 (%.2f 小时)\n", uptime, (float)uptime / 3600);
    
    // 如果系统运行时间很短,可能是虚拟机
    if (uptime < 300) {  // 少于5分钟
        printf("系统运行时间过短,可能是虚拟机环境。\n");
        return TRUE;
    }
    
    return FALSE;
}

// 心理压力测试
BOOL PsychologicalStressTest() {
    printf("=== 心理压力测试 ===\n");
    
    // 显示一个带有倒计时的警告对话框
    DWORD startTime = GetTickCount();
    
    int result = MessageBoxW(NULL, 
                           L"警告:程序将在10秒后自动关闭!\n\n"
                           L"如果您是正常用户,请立即点击'取消'。\n"
                           L"如果您是自动化程序,将无法及时响应。", 
                           L"紧急警告", 
                           MB_OKCANCEL | MB_ICONSTOP);
    
    DWORD endTime = GetTickCount();
    DWORD responseTime = endTime - startTime;
    
    printf("用户响应时间: %lu ms\n", responseTime);
    
    // 正常用户应该能够及时响应
    if (responseTime > 8000) {  // 超过8秒
        printf("响应时间过长,可能是虚拟机环境。\n");
        return TRUE;
    }
    
    if (result == IDOK) {
        printf("用户点击了'确定',行为可疑。\n");
        return TRUE;
    }
    
    return FALSE;
}

// 综合社会工程学检测
BOOL ComprehensiveSocialEngineeringDetection() {
    printf("=== 综合社会工程学检测 ===\n");
    
    BOOL result1 = DetectVMViaUserInteraction();
    BOOL result2 = DeceptiveSystemUpdateTest();
    BOOL result3 = DeceptiveSecurityWarningTest();
    BOOL result4 = UserAttentionTest();
    BOOL result5 = EnvironmentalAwarenessTest();
    BOOL result6 = UserHabitAnalysis();
    BOOL result7 = PsychologicalStressTest();
    
    return result1 || result2 || result3 || result4 || result5 || result6 || result7;
}

4.4 反虚拟机实现

// 简单的社会工程学反虚拟机检测
VOID SimpleSocialEngineeringAntiVM() {
    if (ComprehensiveSocialEngineeringDetection()) {
        printf("通过社会工程学检测到虚拟机环境!程序即将退出。\n");
        ExitProcess(1);
    }
}

// 多层次社会工程学检测
BOOL MultiLayerSocialEngineeringDetection() {
    // 第一层:基础交互检测
    if (DetectVMViaUserInteraction()) {
        return TRUE;
    }
    
    // 第二层:欺骗性测试
    if (DeceptiveSystemUpdateTest()) {
        return TRUE;
    }
    
    // 第三层:安全警告测试
    if (DeceptiveSecurityWarningTest()) {
        return TRUE;
    }
    
    // 第四层:用户注意力测试
    if (UserAttentionTest()) {
        return TRUE;
    }
    
    // 第五层:环境感知检测
    if (EnvironmentalAwarenessTest()) {
        return TRUE;
    }
    
    // 第六层:用户习惯分析
    if (UserHabitAnalysis()) {
        return TRUE;
    }
    
    // 第七层:心理压力测试
    if (PsychologicalStressTest()) {
        return TRUE;
    }
    
    return FALSE;
}

// 增强版反虚拟机检测
VOID EnhancedSocialEngineeringAntiVM() {
    // 多次检测
    for (int i = 0; i < 3; i++) {
        if (MultiLayerSocialEngineeringDetection()) {
            printf("第%d次社会工程学检测发现虚拟机环境!\n", i + 1);
            
            // 随机化响应
            int response = rand() % 4;
            switch (response) {
            case 0:
                ExitProcess(0);
            case 1:
                printf("发生未知错误。\n");
                Sleep(5000);
                exit(1);
            case 2:
                // 执行错误指令
                __debugbreak();
            case 3:
                // 进入无限循环
                while (1) {
                    Sleep(1000);
                }
            }
        }
        
        // 随机延迟
        Sleep(rand() % 100 + 50);
    }
    
    printf("社会工程学反虚拟机检测通过。\n");
}

4.5 绕过社会工程学检测的方法

// 社会工程学检测绕过技术
class SocialEngineeringObfuscator {
public:
    // 模拟正常用户行为
    static VOID SimulateNormalUserBehavior() {
        printf("模拟正常用户行为...\n");
        
        // 可以通过自动化脚本模拟正常的鼠标移动和键盘输入
    }
    
    // 延长响应时间
    static VOID ExtendResponseTime() {
        printf("延长响应时间...\n");
        
        // 在自动化测试中故意增加延迟来模拟人类反应时间
    }
    
    // 创建个性化环境
    static VOID CreatePersonalizedEnvironment() {
        printf("创建个性化环境...\n");
        
        // 设置个性化的桌面背景、主题等
    }
};

// 综合绕过方法
VOID ComprehensiveSocialEngineeringBypass() {
    // 模拟正常用户行为
    SocialEngineeringObfuscator::SimulateNormalUserBehavior();
    
    // 延长响应时间
    SocialEngineeringObfuscator::ExtendResponseTime();
    
    // 创建个性化环境
    SocialEngineeringObfuscator::CreatePersonalizedEnvironment();
    
    printf("社会工程学检测绕过完成。\n");
}

4.6 完整测试程序

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <psapi.h>

// 前面实现的函数声明
BOOL DetectVMViaUserInteraction();
BOOL DeceptiveSystemUpdateTest();
BOOL DeceptiveSecurityWarningTest();
BOOL UserAttentionTest();
BOOL EnvironmentalAwarenessTest();
BOOL UserHabitAnalysis();
BOOL PsychologicalStressTest();
BOOL MultiLayerSocialEngineeringDetection();

// 显示系统环境信息
VOID DisplaySystemEnvironmentInfo() {
    printf("=== 系统环境信息 ===\n");
    
    // 显示用户名
    WCHAR username[256];
    DWORD usernameSize = sizeof(username) / sizeof(username[0]);
    if (GetUserNameW(username, &usernameSize)) {
        printf("当前用户: %ws\n", username);
    }
    
    // 显示计算机名
    WCHAR computerName[256];
    DWORD computerNameSize = sizeof(computerName) / sizeof(computerName[0]);
    if (GetComputerNameW(computerName, &computerNameSize)) {
        printf("计算机名: %ws\n", computerName);
    }
    
    // 显示操作系统版本
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osvi);
    printf("操作系统版本: %lu.%lu\n", osvi.dwMajorVersion, osvi.dwMinorVersion);
    
    printf("\n");
}

// 性能测试
VOID PerformanceTest() {
    const int iterations = 2;
    
    printf("=== 性能测试 (%d次调用) ===\n", iterations);
    
    // 测试基础交互检测
    DWORD start = GetTickCount();
    for (int i = 0; i < iterations; i++) {
        // 避免弹出太多对话框,这里只测试逻辑
        printf("模拟第%d次交互检测\n", i + 1);
        Sleep(100);
    }
    DWORD basicTime = GetTickCount() - start;
    
    printf("社会工程学检测模拟耗时: %lu ms\n", basicTime);
    
    printf("\n");
}

// 主程序
int main() {
    srand((unsigned int)time(NULL));
    
    printf("通过社会工程学检测虚拟机演示程序\n");
    printf("=========================\n\n");
    
    // 显示系统环境信息
    DisplaySystemEnvironmentInfo();
    
    // 基础交互检测
    DetectVMViaUserInteraction();
    
    // 欺骗性系统更新测试
    DeceptiveSystemUpdateTest();
    
    // 欺骗性安全警告测试
    DeceptiveSecurityWarningTest();
    
    // 用户注意力测试
    UserAttentionTest();
    
    // 环境感知检测
    EnvironmentalAwarenessTest();
    
    // 用户习惯分析
    UserHabitAnalysis();
    
    // 心理压力测试
    PsychologicalStressTest();
    
    // 性能测试
    PerformanceTest();
    
    // 实际应用示例
    printf("=== 反虚拟机检测 ===\n");
    if (MultiLayerSocialEngineeringDetection()) {
        printf("检测到虚拟机环境,执行反虚拟机措施。\n");
        
        // 这里可以执行各种反虚拟机措施
        // 为演示目的,我们只是显示信息而不真正退出
        printf("(演示模式:不实际退出程序)\n");
    } else {
        printf("未检测到虚拟机环境,程序正常运行。\n");
        MessageBoxW(NULL, L"社会工程学检测通过,程序正常运行", L"提示", MB_OK);
    }
    
    // 演示绕过方法
    printf("\n=== 绕过演示 ===\n");
    printf("执行社会工程学绕过...\n");
    // ComprehensiveSocialEngineeringBypass();  // 注释掉以避免实际修改
    
    printf("绕过完成后再次检测:\n");
    if (MultiLayerSocialEngineeringDetection()) {
        printf("仍然检测到虚拟机环境。\n");
    } else {
        printf("检测结果显示未发现社会工程学异常。\n");
    }
    
    return 0;
}

4.7 高级技巧和注意事项

// 抗干扰版本(防止简单的Hook)
BOOL AntiTamperSocialEngineeringDetection() {
    // 多次调用并验证
    BOOL results[3];
    
    for (int i = 0; i < 3; i++) {
        results[i] = MultiLayerSocialEngineeringDetection();
        Sleep(10);  // 简短延迟
    }
    
    // 检查结果一致性
    for (int i = 1; i < 3; i++) {
        if (results[i] != results[0]) {
            // 结果不一致,可能是被干扰了
            return TRUE;  // 假设存在虚拟机环境
        }
    }
    
    return results[0];
}

// 综合检测函数
BOOL ComprehensiveSocialEngineeringDetectionEnhanced() {
    // 抗干扰检测
    if (AntiTamperSocialEngineeringDetection()) {
        return TRUE;
    }
    
    // 多层检测
    if (MultiLayerSocialEngineeringDetection()) {
        return TRUE;
    }
    
    return FALSE;
}

// 动态调整检测策略
VOID AdaptDetectionStrategy() {
    printf("=== 动态调整检测策略 ===\n");
    
    // 根据前几次检测结果调整后续检测策略
    static int detectionCount = 0;
    detectionCount++;
    
    if (detectionCount > 3) {
        printf("检测次数过多,调整检测策略。\n");
        // 可以降低检测频率或改变检测方法
    }
}

// 多线程环境下的社会工程学检测
BOOL MultiThreadSocialEngineeringDetection() {
    printf("=== 多线程社会工程学检测 ===\n");
    
    // 在多线程环境中进行检测可以增加检测的可靠性
    
    return FALSE;
}

五、课后作业

  1. 基础练习

    • 设计更多类型的社会工程学测试场景
    • 研究不同用户群体的行为特征差异
    • 实现对用户行为的完整分析
  2. 进阶练习

    • 实现一个完整的行为模式学习系统
    • 研究如何区分正常用户和自动化程序
    • 设计自适应的社会工程学检测机制
  3. 思考题

    • 社会工程学检测方法有哪些明显的局限性?
    • 如何提高社会工程学检测的准确性和隐蔽性?
    • 现代虚拟机用户采用了哪些技术来对抗社会工程学检测?
  4. 扩展阅读

    • 研究人机交互心理学
    • 了解行为分析技术
    • 学习现代反虚拟机技术