前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >规避检测(共五章):第三章

规避检测(共五章):第三章

作者头像
Creaper
发布2023-11-20 12:44:51
2030
发布2023-11-20 12:44:51
举报
文章被收录于专栏:锦鲤安全锦鲤安全

一、进程和库检测方法

虚拟环境启动一些特定的程序进程,这些进程在通常的主机操作系统中未执行。还有一些特定的模块被加载到进程地址空间中。

1. 检查特定正在运行的进程和加载的库

1.1 检查特定进程是否正在运行

代码语言:javascript
复制
check_process_is_running("vmtoolsd.exe");

bool check_process_is_running(const std::string& proc_name) {
    HANDLE hSnapshot;
    PROCESSENTRY32 pe = {};

    pe.dwSize = sizeof(pe);
    bool present = false;
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hSnapshot == INVALID_HANDLE_VALUE)
        return false;

    if (Process32First(hSnapshot, &pe)) {
        do {
            if (!StrCmpI(pe.szExeFile, proc_name.c_str())) {
                present = true;
                break;
            }
        } while (Process32Next(hSnapshot, &pe));
    }
    CloseHandle(hSnapshot);

    return present;
}

1.2 检查进程地址空间中是否加载了特定的库

代码语言:javascript
复制
VOID loaded_dlls()
{
    /* Some vars */
    HMODULE hDll;

    /* Array of strings of blacklisted dlls */
    TCHAR* szDlls[] = {
        _T("sbiedll.dll"),
        _T("dbghelp.dll"),
        _T("api_log.dll"),
        _T("dir_watch.dll"),
        _T("pstorec.dll"),
        _T("vmcheck.dll"),
        _T("wpespy.dll"),
    };

    WORD dwlength = sizeof(szDlls) / sizeof(szDlls[0]);
    for (int i = 0; i < dwlength; i++)
    {
        TCHAR msg[256] = _T("");
        _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process loaded modules contains: %s "),
            szDlls[i]);

        /* Check if process loaded modules contains the blacklisted dll */
        hDll = GetModuleHandle(szDlls[i]);
        if (hDll == NULL)
            print_results(FALSE, msg);
        else
            print_results(TRUE, msg);
    }
}

1.3 检查特定库中是否存在特定函数

代码语言:javascript
复制
BOOL wine_exports()
{
    /* Some vars */
    HMODULE hKernel32;

    /* Get kernel32 module handle */
    hKernel32 = GetModuleHandle(_T("kernel32.dll"));
    if (hKernel32 == NULL) {
        print_last_error(_T("GetModuleHandle"));
        return FALSE;
    }

    /* Check if wine_get_unix_file_name is exported by this dll */
    if (GetProcAddress(hKernel32, "wine_get_unix_file_name") == NULL)
        return FALSE;
    else
        return TRUE;
}

1.4 检查某些库是否可以加载,其他库是否可以加载

这种技术依赖于这样的假设,即在通常的系统中有一些可以加载的通用系统库 - 也有一些假的,它们不应该真正存在于通常的系统中。但是,在沙盒中,当尝试加载某些假库时,它们可能会被报告为已加载 - 这与普通主机上的情况不同。

换句话说,如果未加载通常在物理机存在(但未广泛使用)的系统库,则应用程序可能位于沙箱中。如果报告加载了假 DLL,那么它很可能是一个沙箱,因为这样的 DLL 不会加载到正常物理机器中。

代码语言:javascript
复制
bool Generic::CheckLoadedDLLs() const {
    std::vector<std::string> real_dlls = {
        "kernel32.dll",
        "networkexplorer.dll",
        "NlsData0000.dll"
    };
    std::vector<std::string> false_dlls = {
        "NetProjW.dll",
        "Ghofr.dll",
        "fg122.dll"
    };
    HMODULE lib_inst;

    for (auto& dll : real_dlls) {
        lib_inst = LoadLibraryA(dll.c_str());
        if (lib_inst == nullptr) {
            return true;
        }
        FreeLibrary(lib_inst);
    }

    for (auto& dll : false_dlls) {
        lib_inst = LoadLibraryA(dll.c_str());
        if (lib_inst != nullptr) {
            return true;
        }
    }

    return false;
}

2.检查进程地址空间中是否存在特定工件(仅限沙盒)

代码语言:javascript
复制
BOOL AmISandboxied(LPVOID lpMinimumApplicationAddress, LPVOID lpMaximumApplicationAddress)
{
    BOOL IsSB = FALSE;
    MEMORY_BASIC_INFORMATION RegionInfo;
    ULONG_PTR i, k;
    SIZE_T Length = 0L;

    i = (ULONG_PTR)lpMinimumApplicationAddress;
    do {

        NTSTATUS Status = NtQueryVirtualMemory(GetCurrentProcess(),
            (PVOID)i,
            MemoryBasicInformation,
            &RegionInfo,
            sizeof(MEMORY_BASIC_INFORMATION),
            &Length);
        if (NT_SUCCESS(Status)) {

            if (((RegionInfo.AllocationProtect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) &&
                ((RegionInfo.State & MEM_COMMIT) == MEM_COMMIT)) {

                for (k = i; k < i + RegionInfo.RegionSize; k += sizeof(DWORD)) {
                    if (
                        (*(PDWORD)k == 'kuzt') ||
                        (*(PDWORD)k == 'xobs')
                        )
                    {
                        IsSB = TRUE;
                        break;
                    }
                }
            }
            i += RegionInfo.RegionSize;
        }
        else {
            i += 0x1000;
        }
    } while (i < (ULONG_PTR)lpMaximumApplicationAddress);

    return IsSB;
}

二、网络检测方法

这个群体中的逃避技术在这个或那个意义上与网络有关。要么使用与网络相关的功能,要么检查网络参数 — 如果它们与通常的主机操作系统不同,则可能会检测到虚拟环境。

1.特定网络属性

不同虚拟环境的供应商为其产品硬编码一些值(MAC 地址)和名称(网络适配器)——因此,例如 可以通过检查相应对象的属性来检测环境。

1.1 检查 MAC 地址是否特定

代码语言:javascript
复制
int pafish_check_mac_vendor(char* mac_vendor) {
    unsigned long alist_size = 0, ret;
    ret = GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &alist_size);

    if (ret == ERROR_BUFFER_OVERFLOW) {
        IP_ADAPTER_ADDRESSES* palist = (IP_ADAPTER_ADDRESSES*)LocalAlloc(LMEM_ZEROINIT, alist_size);
        void* palist_free = palist;

        if (palist) {
            GetAdaptersAddresses(AF_UNSPEC, 0, 0, palist, &alist_size);
            char mac[6] = { 0 };
            while (palist) {
                if (palist->PhysicalAddressLength == 0x6) {
                    memcpy(mac, palist->PhysicalAddress, 0x6);
                    if (!memcmp(mac_vendor, mac, 3)) {
                        LocalFree(palist_free);
                        return TRUE;
                    }
                }
                palist = palist->Next;
            }
            LocalFree(palist_free);
        }
    }

    return FALSE;
}
代码语言:javascript
复制
BOOL check_mac_addr(TCHAR* szMac)
{
    BOOL bResult = FALSE;
    PIP_ADAPTER_INFO pAdapterInfo;
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO));

    if (pAdapterInfo == NULL)
    {
        _tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n"));
        return -1;
    }

    //对 GetAdaptersInfo 进行初始调用,以便在 ulOutBufLen 变量中获取必要的大小
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
    {
        FREE(pAdapterInfo);
        pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen);
        if (pAdapterInfo == NULL) {
            printf("Error allocating memory needed to call GetAdaptersinfo\n");
            return 1;
        }
    }


    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_SUCCESS)
    {
        // 将给定的 mac 地址转换为多字节字符数组
        CHAR szMacMultiBytes[4];
        for (int i = 0; i < 4; i++) {
            szMacMultiBytes[i] = (CHAR)szMac[i];
        }
        while (pAdapterInfo)
        {
            if (pAdapterInfo->AddressLength == 6 && !memcmp(szMacMultiBytes, pAdapterInfo->Address, 3))
            {
                bResult = TRUE;
                break;
            }
            pAdapterInfo = pAdapterInfo->Next;
        }
    }

    return bResult;
}

1.2 检查适配器名称是否特定

代码语言:javascript
复制
int pafish_check_adapter_name(char* name) {
    unsigned long alist_size = 0, ret;
    wchar_t aux[1024];

    mbstowcs(aux, name, sizeof(aux) - sizeof(aux[0]));
    ret = GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &alist_size);

    if (ret == ERROR_BUFFER_OVERFLOW) {
        IP_ADAPTER_ADDRESSES* palist = (IP_ADAPTER_ADDRESSES*)LocalAlloc(LMEM_ZEROINIT, alist_size);
        void* palist_free = palist;
        if (palist) {
            if (GetAdaptersAddresses(AF_UNSPEC, 0, 0, palist, &alist_size) == ERROR_SUCCESS) {
                while (palist) {
                    if (wcsstr(palist->Description, aux)) {
                        LocalFree(palist_free);
                        return TRUE;
                    }
                    palist = palist->Next;
                }
            }
            LocalFree(palist_free);
        }
    }

    return FALSE;
}
代码语言:javascript
复制
BOOL check_adapter_name(TCHAR* szName)
{
    BOOL bResult = FALSE;
    PIP_ADAPTER_INFO pAdapterInfo;
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO));

    if (pAdapterInfo == NULL)
    {
        _tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n"));
        return -1;
    }

    // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
    {
        FREE(pAdapterInfo);
        pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen);
        if (pAdapterInfo == NULL) {
            printf("Error allocating memory needed to call GetAdaptersinfo\n");
            return 1;
        }
    }

    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_SUCCESS)
    {
        while (pAdapterInfo)
        {
            if (StrCmpI(ascii_to_wide_str(pAdapterInfo->Description), szName) == 0)
            {
                bResult = TRUE;
                break;
            }
            pAdapterInfo = pAdapterInfo->Next;
        }
    }

    return bResult;
}

1.3 检查提供商的网络共享名称是否特定

代码语言:javascript
复制
int vbox_network_share() {
    unsigned long pnsize = 0x1000;
    char provider[pnsize];

    int retv = WNetGetProviderName(WNNC_NET_RDR2SAMPLE, provider, &pnsize);
    if (retv == NO_ERROR) {
        if (lstrcmpi(provider, "VirtualBox Shared Folders") == 0)
            return TRUE;
        else
            return FALSE;
    }

    return FALSE;
}

2.检查网络是否属于安全边界

恶意软件向 https[:]//www.maxmind.com/geoip/v2.1/city/me 发出请求,通常需要某种身份验证或 API 密钥。为了满足这一要求,恶意软件通过将 HTTP 引用程序设置为 https[:]//www.maxmind.com/en/locate-my-ip-address 并将 User-Agent 设置为Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)此技巧允许示例检索有关运行它的计算机的 IP 地址的信息。

响应以 JSON 格式返回,包含有关国家/地区、城市以及与 IP 地址关联的组织的信息。如果在响应中发现一些“坏”字符串,恶意软件就会知道它是在某种安全边界/组织内启动的。

代码语言:javascript
复制
Amazon
anonymous
BitDefender
BlackOakComputers
Blue Coat
BlueCoat
Cisco
cloud
Data Center
DataCenter
DataCentre
dedicated
ESET, Spol
FireEye
ForcePoint
Fortinet
Hetzner
hispeed.ch
hosted
Hosting
Iron Port
IronPort
LeaseWeb
MessageLabs
Microsoft
MimeCast
NForce
Ovh Sas
Palo Alto
ProofPoint
Rackspace
security
Server
Strong Technologies
Trend Micro
TrendMicro
TrustWave
VMVault
Zscaler

3.基于网络验证名称结果的反仿真技术

最初,这种技术是为绕过AV检测而设计的。它本身不是一种逃避技术——相反,它在调用函数后滥用有趣的副作用。

主要思想是使用具有无效参数的 NetValidateName API 函数调用的确定结果作为服务器名称(例如“123”)来动态计算跳转地址。这种跳跃通常指向某些指令的中间,以绕过AV软件的启发式分析。但这种技术也(至少)有一个副作用。

如果在操作系统中设置了默认的 NetBIOS 设置(启用了基于 TCP/IP 的 NetBIOS),则返回代码始终等于 ERROR_BAD_NETPATH (0x35)。

如果 NetBIOS over TCP/IP 关闭,则返回代码ERROR_NETWORK_UNREACHABLE (0x4CF)。

因此,跳转地址的计算将不正确,并将导致样本崩溃。因此,此技术可用于在沙箱中中断仿真,其中基于 TCP/IP 的 NetBIOS 已关闭,以防止操作系统生成垃圾流量。注意:通过 TCP/IP 的 NetBIOS 已关闭,以便在通过 DNS 解析服务器 IP 时不生成其他网络请求。

代码语言:javascript
复制
void EntryPoint(void)
{
    HANDLE NetApi32 = LoadLibraryW(L"netapi32.dll");
    TD_NetValidateName NetValidateName = (TD_NetValidateName)GetProcAddress(NetApi32, "NetValidateName");
    DWORD Result = NetValidateName(L"123", L"", L"", L"", 1);

    __asm
    {
        call dword ptr ds : [GetLastError]
        add eax, offset TrueEntryPoint
        sub eax, 0xCB  // ERROR_ENVVAR_NOT_FOUND
        call eax
    }
}

三、使用的 CPU 检测方法

该组中的技术使用特定的处理器指令来获取有关CPU的特定信息,或者执行预定义的指令序列,这些指令序列在通常的主机操作系统和虚拟环境中的行为不同。

1.通过 CPUID 指令检查供应商 ID 字符串

CPUID 指令是将处理器标识和功能信息返回给 EBX、ECX、EDX 的指令。接收到这些登记册的信息可用于识别供应商。

代码语言:javascript
复制
__declspec(naked) void get_cpuid_vendor(char* vendor_id) {
    __asm {
        ; save non - volatile register
        push ebx

        ; nullify output registers
        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx

        ; call cpuid with argument in EAX
        mov eax, 0x40000000
        cpuid

        ; store vendor_id ptr to destination
        mov edi, vendor_id

        ; move string parts to destination
        mov eax, ebx; part 1 of 3 from EBX
        stosd
        mov eax, ecx; part 2 of 3 from ECX
        stosd
        mov eax, edx; part 3 of 3 from EDX
        stosd

        ; restore saved non - volatile register
        pop ebx

        ; return from function
        retn
    }
}

2.检查是否通过 CPUID 指令在虚拟机管理程序中运行

检测程序是否在虚拟机监控程序中运行的另一种方法是以另一种方式使用 CPUID 指令。

EAX 不是将 EAX(CPU id 的参数)设置为 0x40000000,而是设置为 1。

当 EAX 设置为 1 时,将设置 ECX 中的第 31 位(CPUID 的返回值),表示程序正在虚拟机监控程序中运行。

代码语言:javascript
复制
__declspec(naked) bool is_run_in_hypervisor() {
    __asm {
        ; nullify output register
        xor ecx, ecx

        ; call cpuid with argument in EAX
        mov eax, 1
        cpuid

        ; set CF equal to 31st bit in ECX
        bt ecx, 31

        ; set AL to the value of CF
        setc al

        ; return from function
        retn
    }
}

3. 检查全局表位置:IDT/GDT/LDT

此技术不适用于最新的 VMware 版本(所有受影响的 Windows 版本)。但是,为了完整起见,此处对其进行了描述。

此技巧涉及查看指向通常在虚拟机上重新定位的关键操作系统表的指针。这就是所谓的“红色药丸”,最初由Joanna Rutkowska引入。

每个 CPU 有一个本地描述符表寄存器 (LDTR)、一个全局描述符表寄存器 (GDTR) 和一个中断描述符表寄存器 (IDTR)。当用户操作系统运行时,必须将它们移动到其他位置,以避免与主机发生冲突。

代码语言:javascript
复制
idt_vm_detect = ((get_idt_base() >> 24) == 0xff);
ldt_vm_detect = (get_ldt_base() == 0xdead0000);
gdt_vm_detect = ((get_gdt_base >> 24) == 0xff);

// sidt instruction stores the contents of the IDT Register
// (the IDTR which points to the IDT) in a processor register.
ULONG get_idt_base() {
    UCHAR idtr[6];
#if defined (ENV32BIT)
    _asm sidt idtr
#endif
    return *((unsigned long*)&idtr[2]);
}

// sldt instruction stores the contents of the LDT Register
// (the LDTR which points to the LDT) in a processor register.
ULONG get_ldt_base() {
    UCHAR ldtr[5] = "\xef\xbe\xad\xde";
#if defined (ENV32BIT)
    _asm sldt ldtr
#endif
    return *((unsigned long*)&ldtr[0]);
}

// sgdt instruction stores the contents of the GDT Register
// (the GDTR which points to the GDT) in a processor register.
ULONG get_gdt_base() {
    UCHAR gdtr[6];
#if defined (ENV32BIT)
    _asm sgdt gdtr
#endif
    return gdt = *((unsigned long*)&gdtr[2]);
}

4.通过执行非法指令检测环境(仅限虚拟电脑)

恶意软件执行非法指令,这些指令应该在实际CPU上生成异常,但在虚拟环境中正常执行 - 或以某种不同的方式执行。

代码语言:javascript
复制
push ebx
xor ebx, ebx
mov eax, 1
; the following 4 bytes below generate #ud exception
db 0x0F
db 0x3F
db 0x0D
db 0x00
test ebx, ebx
setz al
pop ebx
代码语言:javascript
复制
// Use this code to detect if Windows XP is running inside Virtual PC 2007
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"

#define CONTEXT_ALL 0x1003F

int dummy(int);
unsigned long gf = 0;

int __cdecl Handler(EXCEPTION_RECORD* pRec, void* est, unsigned char* pContext, void* disp)
{
    if (pRec->ExceptionCode == 0xC0000096)  //Privileged instruction
    {
        //---------------------Installing the trick--------------------------------------
        *(unsigned long*)(pContext) = CONTEXT_ALL;/*CONTEXT_DEBUG_REGISTERS|CONTEXT_FULL*/
        *(unsigned long*)(pContext + 0x4) = (unsigned long)(&dummy);
        *(unsigned long*)(pContext + 0x8) = (unsigned long)(&dummy);
        *(unsigned long*)(pContext + 0xC) = (unsigned long)(&dummy);
        *(unsigned long*)(pContext + 0x10) = (unsigned long)(&dummy);
        *(unsigned long*)(pContext + 0x14) = 0;
        *(unsigned long*)(pContext + 0x18) = 0x155; //Enable the four DRx On-Execute
        //---------------------------------------------------------------------------------
        (*(unsigned long*)(pContext + 0xB8))++;
        return ExceptionContinueExecution;
    }
    else if (pRec->ExceptionCode == EXCEPTION_SINGLE_STEP)
    {
        if (gf == 1)
        {
            MessageBox(0, "Expected behavior (XP)", "waliedassar", 0);
            ExitProcess(0);
        }
        gf++;
        (*(unsigned long*)(pContext + 0xC0)) |= 0x00010000; //Set the RF (Resume Flag)
        return ExceptionContinueExecution;
    }
    return ExceptionContinueSearch;
}

int dummy(int x)
{
    x += 0x100;
    return x;
}

int main(int shitArg)
{
    unsigned long ver_ = GetVersion();
    unsigned long major = ver_ & 0xFF;
    unsigned long minor = (ver_ >> 0x8) & 0xFF;
    if (major == 0x05 & minor == 0x01) //Windows XP
    {
        unsigned long x = 0;
        __asm
        {
            push offset Handler
            push dword ptr fs : [0x0]
            mov dword ptr fs : [0x0] , esp
            STI; Triggers an exception(privileged instruction)
        }
        dummy(0xFF);
        __asm
        {
            pop dword ptr fs : [0x0]
            pop ebx
        }
        MessageBox(0, "Virtual PC 2007 detected (XP)", "waliedassar", 0);
    }
    return 0;
}
代码语言:javascript
复制
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"

bool flag = false;

int __cdecl Handler(EXCEPTION_RECORD* pRec, void* est, unsigned char* pContext, void* disp)
{
    if (pRec->ExceptionCode == 0xC000001D || pRec->ExceptionCode == 0xC000001E || pRec->ExceptionCode == 0xC0000005)
    {
        flag = true;
        (*(unsigned long*)(pContext + 0xB8)) += 5;
        return ExceptionContinueExecution;
    }
    return ExceptionContinueSearch;
}

int main(int argc, char* argv[])
{
    __asm
    {
        push offset Handler
        push dword ptr fs : [0x0]
        mov dword ptr fs : [0x0] , esp
    }
    flag = false;
    __asm
    {
        __emit 0x0F
        __emit 0xC7
        __emit 0xC8
        __emit 0x05
        __emit 0x00
    }
    if (flag == false)
    {
        MessageBox(0, "VirtualPC detected", "waliedassar", 0);
    }
    __asm
    {
        pop dword ptr fs : [0x0]
        pop eax
    }
    return 0;
}

6.通过 IN 指令检测环境 - 后门端口(仅限 VMware)

代码语言:javascript
复制
bool VMWare::CheckHypervisorPort() const {
    bool is_vm = false;
    __try {
        __asm {
            push edx
            push ecx
            push ebx
            mov eax, 'VMXh'
            mov ebx, 0
            mov ecx, 10
            mov edx, 'VX'
            in eax, dx      // <- key point is here
            cmp ebx, 'VMXh'
            setz[is_vm]
            pop ebx
            pop ecx
            pop edx
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        is_vm = false;
    }
    return is_vm;
}
代码语言:javascript
复制
bool VMWare::CheckHypervisorPortEnum() const {
    bool is_vm = false;
    short ioports[] = { 'VX' , 'VY' };
    short ioport;
    for (short i = 0; i < _countof(ioports); ++i) {
        ioport = ioports[i];
        for (unsigned char cmd = 0; cmd < 0x2c; ++cmd) {
            __try {
                __asm {
                    push eax
                    push ebx
                    push ecx
                    push edx
                    mov eax, 'VMXh'
                    movzx ecx, cmd
                    mov dx, ioport
                    in eax, dx      // <- key point is here
                    pop edx
                    pop ecx
                    pop ebx
                    pop eax
                }
                is_vm = true;
                break;
            }
            __except (EXCEPTION_EXECUTE_HANDLER) {}
        }
        if (is_vm)
            break;
    }
    return is_vm;
}

锦鲤安全

一个安全技术学习与工具分享平台

点分享

点收藏

点点赞

点在看

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 锦鲤安全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、进程和库检测方法
  • 1. 检查特定正在运行的进程和加载的库
    • 1.2 检查进程地址空间中是否加载了特定的库
      • 1.3 检查特定库中是否存在特定函数
        • 1.4 检查某些库是否可以加载,其他库是否可以加载
        • 2.检查进程地址空间中是否存在特定工件(仅限沙盒)
          • 二、网络检测方法
          • 1.特定网络属性
            • 1.1 检查 MAC 地址是否特定
              • 1.2 检查适配器名称是否特定
                • 1.3 检查提供商的网络共享名称是否特定
                • 2.检查网络是否属于安全边界
                • 3.基于网络验证名称结果的反仿真技术
                  • 三、使用的 CPU 检测方法
                  • 1.通过 CPUID 指令检查供应商 ID 字符串
                  • 2.检查是否通过 CPUID 指令在虚拟机管理程序中运行
                  • 3. 检查全局表位置:IDT/GDT/LDT
                  • 4.通过执行非法指令检测环境(仅限虚拟电脑)
                  • 6.通过 IN 指令检测环境 - 后门端口(仅限 VMware)
                  相关产品与服务
                  多因子身份认证
                  多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档