freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

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

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

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

常见的反沙箱反虚拟机思路
渗透测试安全攻防 2024-03-24 17:53:26 276769

反调试

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 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
恶意软件技术
相关推荐
渗透测试安全攻防 LV.5
公众号《渗透测试安全攻防》,欢迎来找我玩
  • 38 文章数
  • 36 关注者
flaskpython代码审计思路及实战记录
2025-02-03
flask安全指南
2025-01-11
windows栈溢出教程
2024-11-25
文章目录