freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

通过ACPI检测沙箱
2023-06-19 21:50:26
所属地 海外

前言

最近 @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我们能很轻易的看到:
image.png

虚拟机 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;
}

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

POC

这个POC检测什么:

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

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

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

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

vmware:
image.png
Cuckoo:
image.png

扩展: WEATH是什么

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

# 沙箱 # 沙箱绕过
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录