基于Registry的虚拟机检测

简介

通常在编写的恶意软件会被蓝队捕捉,那么如何让蓝队花去更长时间去反编译我们的恶意软件这也成为了一种必选项,注意不是防止破解,理论上任何软件都会被破解,我们需要做的其实只是增加蓝队的破解成本。

通常蓝队会把捕捉到的恶意软件放在一个虚拟环境里如vmware,virtualbox等知名虚拟机软件,也有可能是自研的沙箱,那么如何识别软件是否运行在虚拟环境里会是防止破解重要的一环,本文将叙述一部分常见的虚拟机软件会注册的Registry,检测虚拟机防止破解以便让蓝队成员增加破解成本。

检测原理

通常在虚拟内,虚拟机软件会注册一些在物理机上不存在的注册表项,如果在注册表内出现了这样的选项,基本可以判定为运行在虚拟机环境,当然这种判断也有误报的可能,一些虚拟机软件会在物理界也注册一些相同的选项,但是对于虚拟机内,这样的表项算是比较少。

通常注册表项会使用windows提供的api进行查询,会使用让如下函数:

ntdll.dll导出:

  • NtOpenKey

  • NtEnumerateKey

  • NtQueryValueKey

  • NtClose

以及在其之上封装出的kernel32.dll的导出函数:

  • RegOpenKey

  • RegOpenKeyEx

  • RegQueryValue

  • RegQueryValueEx

  • RegCloseKey

  • RegEnumKeyEx

检查注册表路径

代码来自:https://github.com/a0rtega/pafish

/* sample of usage: see detection of VirtualBox in the table below to check registry path */
int vbox_reg_key7() {
    return pafish_exists_regkey(HKEY_LOCAL_MACHINE, "HARDWARE\\ACPI\\FADT\\VBOX__");
}

/* code is taken from "pafish" project, see references on the parent page */
int pafish_exists_regkey(HKEY hKey, char * regkey_s) {
    HKEY regkey;
    LONG ret;

    /* regkey_s == "HARDWARE\\ACPI\\FADT\\VBOX__"; */
    if (pafish_iswow64()) {
        ret = RegOpenKeyEx(hKey, regkey_s, 0, KEY_READ | KEY_WOW64_64KEY, &regkey);
    }
    else {
        ret = RegOpenKeyEx(hKey, regkey_s, 0, KEY_READ, &regkey);
    }

    if (ret == ERROR_SUCCESS) {
        RegCloseKey(regkey);
        return TRUE;
    }
    else
        return FALSE;
}

对于蓝队,如果注册表查询中出现了如下表项,那么该软件可能就在使用逃避技术。

检查特定的表项内的字符串

/* sample of usage: see detection of VirtualBox in the table below to check registry path and key values */
int vbox_reg_key2() {
    return pafish_exists_regkey_value_str(HKEY_LOCAL_MACHINE, "HARDWARE\\Description\\System", "SystemBiosVersion", "VBOX");
}

/* code is taken from "pafish" project, see references on the parent page */
int pafish_exists_regkey_value_str(HKEY hKey, char * regkey_s, char * value_s, char * lookup) {
    /*
        regkey_s == "HARDWARE\\Description\\System";
        value_s == "SystemBiosVersion";
        lookup == "VBOX";
    */

    HKEY regkey;
    LONG ret;
    DWORD size;
    char value[1024], * lookup_str;
    size_t lookup_size;

    lookup_size = strlen(lookup);
    lookup_str = malloc(lookup_size+sizeof(char));
    strncpy(lookup_str, lookup, lookup_size+sizeof(char));
    size = sizeof(value);

    /* regkey_s == "HARDWARE\\Description\\System"; */
    if (pafish_iswow64()) {
        ret = RegOpenKeyEx(hKey, regkey_s, 0, KEY_READ | KEY_WOW64_64KEY, &regkey);
    }
    else {
        ret = RegOpenKeyEx(hKey, regkey_s, 0, KEY_READ, &regkey);
    }

    if (ret == ERROR_SUCCESS) {
        /* value_s == "SystemBiosVersion"; */
        ret = RegQueryValueEx(regkey, value_s, NULL, NULL, (BYTE*)value, &size);
        RegCloseKey(regkey);

        if (ret == ERROR_SUCCESS) {
            size_t i;
            for (i = 0; i < strlen(value); i++) { /* case-insensitive */
                value[i] = toupper(value[i]);
            }
            for (i = 0; i < lookup_size; i++) { /* case-insensitive */
                lookup_str[i] = toupper(lookup_str[i]);
            }
            if (strstr(value, lookup_str) != NULL) {
                free(lookup_str);
                return TRUE;
            }
        }
    }

    free(lookup_str);
    return FALSE;
}

最后更新于