首页
社区
课程
招聘
[原创][翻译]规避技术:硬件
2021-5-31 14:35 7941

[原创][翻译]规避技术:硬件

2021-5-31 14:35
7941

备注
原文地址:https://evasions.checkpoint.com/techniques/hardware.html
原文标题:Evasions: Hardware
更新日期:2021年5月31日
此文后期:根据自身所学进行内容扩充
因自身技术有限,只能尽自身所能翻译国外技术文章,供大家学习,若有不当或可完善的地方,希望可以指出,用于共同完善这篇文章。


目录

  • 硬件信息检测方法

  • 1. 检查硬盘是否有特定的名称

  • 2. 检查HDD Vendor ID是否有特定值

  • 3. 检查是否没有音频设备

  • 4. 检查CPU温度信息是否可用

  • 5. 检查物理显示适配器的IDirect3D9接口

  • 识别标志

  • 反制措施

硬件信息检测方法
虚拟环境模拟硬件设备,并在其描述中留下具体的痕迹--这些痕迹可以被查询,并对非主机操作系统做出结论。
1. 检查硬盘是否有特定的名称
使用的函数:

  • SetupDiGetClassDevs

  • SetupDiEnumDeviceInfo

  • SetupDiGetDeviceRegistryProperty

代码样本:

hDevs = SetupDiGetClassDevs(
    &guid,  // GUID_DEVCLASS(DEVINTERFACE)_DISKDRIVE
    NULL,
    NULL,
    DIGCF_PRESENT);

SetupDiEnumDeviceInfo(
    hDevsInfo,
    0,
    &devinfo);  // PSP_DEVINFO_DATA

SetupDiGetDeviceRegistryProperty(
    hDevs,
    &devinfo,
    SPDRP_FRIENDLYNAME,
    &dword_1,
    szFriendlyName,  // HDD name will be here
    dFriendlyNameSize,
    &dword_2);


检测表:

检查硬盘驱动器是否有以下名称之一:

检测

名称

QEMU

QEMU

VirtualBox

VBOX

VirtualPC

VIRTUAL HD

VMware

VMware


2. 检查HDD Vendor ID是否有特定值
使用了以下函数:

  • DeviceIoControl(..., IOCTL_STORAGE_QUERY_PROPERTY, ...)

代码样本:

bool GetHDDVendorId(std::string& outVendorId) {
    HANDLE hDevice = CreateFileA(_T("\\\\.\\PhysicalDrive0"), 
                                 0, 
                                 FILE_SHARE_READ | FILE_SHARE_WRITE, 
                                 0, 
                                 OPEN_EXISTING, 
                                 0, 
                                 0);
    if (hDevice == INVALID_HANDLE_VALUE)
        return false;
    
    STORAGE_PROPERTY_QUERY storage_property_query = {};
    storage_property_query.PropertyId = StorageDeviceProperty;
    storage_property_query.QueryType = PropertyStandardQuery;
    STORAGE_DESCRIPTOR_HEADER storage_descriptor_header = {};
    DWORD BytesReturned = 0;
  
    if (!DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, 
                         &storage_property_query, sizeof(storage_property_query), 
                         &storage_descriptor_header, sizeof(storage_descriptor_header), 
                         &BytesReturned, )) {
        printf("DeviceIoControl() for size query failed\n");
        CloseHandle(hDevice);
        return false;
    }
    if (!BytesReturned) {
        CloseHandle(hDevice);
        return false;
    }
  
    std::vector<char> buff(storage_descriptor_header.Size); //_STORAGE_DEVICE_DESCRIPTOR
    if (!DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, 
                         &storage_property_query, sizeof(storage_property_query), 
                         buff.data(), buff.size(), 0)) {
        CloseHandle(hDevice);
        return false;
    }
  
    CloseHandle(hDevice);
  
    if (BytesReturned) {
        STORAGE_DEVICE_DESCRIPTOR* device_descriptor = (STORAGE_DEVICE_DESCRIPTOR*)buff.data();
        if (device_descriptor->VendorIdOffset)
            outVendorId = &buff[device_descriptor->VendorIdOffset];
  
        return true;
    }
    
    return false;
}

检测表:

检查硬盘供应商ID是否为以下之一:

检测

名称

VirtualBox

VBOX

VMware

vmware


3. 检查是否没有音频设备
这项技术是从TeslaCrypt恶意软件样本中提取的,并在Joe Security的这篇博文中进行了描述。
代码样本:

void AudioEvasion() {
  PCWSTR wszfilterName = L"audio_device_random_name";

  if (FAILED(CoInitialize(NULL)))
    return;

  IGraphBuilder *pGraph = nullptr;
  if (FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph)))
    return;

  if (E_POINTER != pGraph->AddFilter(NULL, wszfilterName))
    ExitProcess(-1);

  IBaseFilter *pBaseFilter = nullptr;
  CoCreateInstance(CLSID_AudioRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pBaseFilter);
  
  pGraph->AddFilter(pBaseFilter, wszfilterName);

  IBaseFilter *pBaseFilter2 = nullptr;
  pGraph->FindFilterByName(wszfilterName, &pBaseFilter2);
  if (nullptr == pBaseFilter2)
    ExitProcess(1);

  FILTER_INFO info = { 0 };
  pBaseFilter2->QueryFilterInfo(&info);
  if (0 != wcscmp(info.achName, wszfilterName))
    return;

  IReferenceClock *pClock = nullptr;
  if (0 != pBaseFilter2->GetSyncSource(&pClock))
    return;
  if (0 != pClock)
    return;

  CLSID clsID = { 0 };
  pBaseFilter2->GetClassID(&clsID);
  if (clsID.Data1 == 0)
    ExitProcess(1);

  if (nullptr == pBaseFilter2)
    ExitProcess(-1);

  IEnumPins *pEnum = nullptr;
  if (0 != pBaseFilter2->EnumPins(&pEnum))
    ExitProcess(-1);

  if (0 == pBaseFilter2->AddRef())
    ExitProcess(-1);
}


4. 检查CPU温度信息是否可用
这项技术是从GravityRAT恶意软件中提取的,并通过这个链接进行了描述。

代码样本(Windows cmd命令):

wmic /namespace:\\root\WMI path MSAcpi_ThermalZoneTemperature get CurrentTemperature

5. 检查物理显示适配器的IDirect3D9接口
该方法检查IDirect3D9接口实例化时系统中存在的物理显示适配器。它适用于从Windows XP开始的所有Windows版本。
使用的函数:

  • Direct3DCreate9 - called from `d3d9.dll` library

  • GetAdapterIdentifier - called via IDirect3D9 interface

代码样本:

#include <d3d9.h>

// https://github.com/qt/qtbase/blob/dev/src/plugins/platforms/windows/qwindowsopengltester.cpp#L124

void detect() {
    typedef IDirect3D9* (WINAPI* PtrDirect3DCreate9)(UINT);

    HMODULE d3d9lib = ::LoadLibraryA("d3d9");
    if (!d3d9lib)
        return;

    PtrDirect3DCreate9 direct3DCreate9 = (PtrDirect3DCreate9)GetProcAddress(d3d9lib, "Direct3DCreate9");
    if (!direct3DCreate9)
        return;

    IDirect3D9* direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
    if (!direct3D9)
        return;

    D3DADAPTER_IDENTIFIER9 adapterIdentifier;
    const HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier);
    direct3D9->Release();

    if (SUCCEEDED(hr)) {
        printf("VendorId:    0x%x\n", adapterIdentifier.VendorId);
        printf("DeviceId:    0x%x\n", adapterIdentifier.DeviceId);
        printf("Driver:      %s\n", adapterIdentifier.Driver);
        printf("Description: %s\n", adapterIdentifier.Description);
    }
}

这个代码样本归功于指出它的elsamuko
常规主机上的输出示例如下:

VendorId:    0x10de
DeviceId:    0x103c
Driver:      nvldumdx.dll
Description: NVIDIA Quadro K5200

而这里是一个在虚拟机(VMware)上输出的例子:

VendorId:    0x15ad
DeviceId:    0x405
Driver:      vm3dum64_loader.dll
Description: VMware SVGA 3D

检查的字段以D3DADAPTER_IDENTIFIER9结构的相应字段命名。恶意软件可以将这些字段中的值与已知存在于虚拟机中的值进行比较,如果发现匹配,则得出结论,它是在虚拟机下运行。
检测表:

检查D3DADAPTER_IDENTIFIER9结构的字段中是否存在以下值:

检测

结构字段

注释

VMware

VendorId0x15AD
DeviceId0x405Only when used in combination with VendorId related to VMware (0x15AD)
Drivervm3dum.dll
Drivervm3dum64_loader.dll
DescriptionVMware SVGA 3D


识别标志
识别标志对每种技术都是通用的:拦截使用的函数,并跟踪它是否被调用。例如,很难说出为什么应用程序要获取硬盘名称。这并不一定意味着应用了规避技术。所以在这种情况下,最好的办法就是拦截目标函数并跟踪其调用。
反制措施

  • 对比硬盘检查:重命名硬盘,使其不会被特定字符串检测到;

  • 对照音频设备检查:添加音频设备;

  • 对比CPU温度检查:将存根添加到虚拟机管理程序(hyperviso)以输出一些有意义的信息;

  • 与物理显示适配器检查相比:在d3d9.dll中的函数GetAdapterIdentifier上设置挂钩,检查查询的适配器是否与DirectX相关,并替换返回值。



[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2021-5-31 14:40 被梦幻的彼岸编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (2)
雪    币: 1243
活跃值: (1815)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
库尔 2021-5-31 17:44
2
0
我觉得,这种单纯判断玩意会误杀.....规避技术最好还是,重新修改特征编译vbox,这个是vbox论坛看到的。
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
luskyc 2021-5-31 23:09
3
0
这些应该都是最基本的了,那几个大的游戏公司,检测得更底层了,包括很多个维度
游客
登录 | 注册 方可回帖
返回