【免杀】通过ACPI检测沙箱

admin 2024年4月24日07:43:42评论11 views字数 3051阅读10分10秒阅读模式

点击上方[蓝字],关注我们

免责声明

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任。

文章正文

前言

最近 @Daax 公布了一个关于ACPI检测虚拟机的方法,我对此比较感兴趣,于是研究了一下

ACPI & ACPI table

ACPI表示高级配置和电源管理接口(Advanced Configuration and Power Management Interface)。对于Windows2000,ACPI定义了Windows 2000、BIOS和系统硬件之间的新型工作接口。这些新接口包括允许Windows 2000控制电源管理和设备配置的机制。ACPI table是填写这些配置的地方

很好的是,ACPI可以通过R3的NtQuerySystemInformation拿得到

通过FirmwareTablesView.exe我们能很轻易的看到:

【免杀】通过ACPI检测沙箱

虚拟机 vs 物理机

well..在此声明,在我第一眼看 @Daax 的介绍时候,我第一印象就是这不就是vmp3.x后读 Firmware 拿配置嘛,烂大街了,这项技术很早之前就有了,并不神秘: https://github.com/classic130/VMProtect-Source/blob/a8433f06ee84fa2546e40bef71183827dc230a3b/runtime/core.cc#L329 不不不,今天不会介绍那么古老的技术,而是介绍一些”新”的. 让我们编写代码,获取虚拟机与物理机之间的差异,这是一个简单的快速实现:

static const auto FirmwareTableProviderSignature = 'ACPI';
auto main() -> int {
    printf("acpi sandbox detect by huoji 2023.6.19 n");

    auto firmwareTableBufferSize =
        EnumSystemFirmwareTables(FirmwareTableProviderSignature, 0, 0);
    char* firmwareTableBuffer = nullptr;
    do {
        if (firmwareTableBufferSize == 0) {
            break;
        }
        firmwareTableBuffer =
            reinterpret_cast<char*>(malloc(firmwareTableBufferSize));
        if (firmwareTableBuffer == nullptr) {
            break;
        }
        firmwareTableBufferSize = EnumSystemFirmwareTables(
            FirmwareTableProviderSignature, firmwareTableBuffer,
            firmwareTableBufferSize);
        if (firmwareTableBufferSize == 0) {
            break;
        }
        bool foundHpet = false;
        auto index = 0;
        for (size_t i = 0; i < firmwareTableBufferSize / 4; i++) {
            const auto tableHeader = reinterpret_cast<acpi_table_header*>(
                reinterpret_cast<uint64_t>(firmwareTableBuffer) + i);
            const auto tableID = *firmwareTableBuffer;
            char tid[6] = {0};
            char oemid[7] = {0};
            memcpy(tid, &tableHeader->signature, sizeof(unsigned long));
            memcpy(oemid, reinterpret_cast<char*>(tableHeader->oem_id),
                   sizeof(tableHeader->oem_id));

            printf("tid: %s oemid: %s oem_table_id: %08X n", tid, oemid,
                   tableHeader->oem_table_id);
            index++;
        }
        if (index < 7) {
            printf("[detected] table size n");
        }
        if (foundHpet == false) {
            printf("[detected] HPET not found,Cuckoo detected n");
        }

    } while (false);
    if (firmwareTableBuffer != nullptr) {
        free(firmwareTableBuffer);
    }
    getchar();
    return 0;
}

这是物理机的:

【免杀】通过ACPI检测沙箱

这是在Vmware虚拟机里面的:

【免杀】通过ACPI检测沙箱

这是在布谷鸟沙箱里面的:

【免杀】通过ACPI检测沙箱

看看我们发现了什么: 在windows的虚拟机中,会存在’WAETH’这个OEM_ID 在Vbox/KVM/XEN等非linux hypervisor中,则没有WAETH,只有OEMID(而且OEMID配置不当导致出现问题) 此外这个table的表也存在问题,在虚拟机里面的比在外面的少. 因此我们可以很快的实现一个检测是否在沙箱中的POC

POC

这个POC检测什么:

  1. 1. 检测ACPI表内容,如果小于8那么可能是虚拟机

  2. 2. 检测ACPI是否有windows的WEATH,如果有则说明在windows的虚拟机中

  3. 3. 检测ACPI表中是否没有HPET,如果没有,则说明可能在linux下的沙箱中

here we go: https://github.com/huoji120/ACPI_SANDBOX_DETECT

vmware:

【免杀】通过ACPI检测沙箱
img

Cuckoo:

【免杀】通过ACPI检测沙箱
img

扩展: WEATH是什么

https://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/WAET.docx

https://key08.com/index.php/2023/06/19/1759.html

技术交流

原文始发于微信公众号(Z2O安全攻防):【免杀】通过ACPI检测沙箱

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月24日07:43:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【免杀】通过ACPI检测沙箱http://cn-sec.com/archives/2082327.html

发表评论

匿名网友 填写信息