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. 扩展阅读

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