bypass 2-绕沙箱

admin 2024年3月18日17:06:06评论9 views字数 4249阅读14分9秒阅读模式
bypass 2-绕沙箱
image-20240318151112522

bypass 2-绕沙箱

绕沙盒或者说绕沙箱,是Bypass中一项不可缺少的步骤,每个杀软都有自己的沙箱检测机制,有的在本地有的在云端,不过沙箱和我们正常使用的系统相比存在一些差异,所以我们可以通过一些方式达到绕过的目的,我下面分为4点来总结。

1 基于系统检查

  1. 检测CPU核心数

判断CPU核心是否小于4

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

int main() {
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo); // 获取系统信息

    int numCPU = sysinfo.dwNumberOfProcessors; // 获取CPU核心数
    if (numCPU < 4) {
        printf("疑似沙盒环境n");
    }

}
  1. 检测内存大小

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

int main() {

    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(memInfo);
    GlobalMemoryStatusEx(&memInfo);

    DWORDLONG totalPhysicalMem = memInfo.ullTotalPhys; // 获取总的物理内存大小

    double totalPhysicalMemGB = (double)totalPhysicalMem / (1024 * 1024 * 1024);

    if (totalPhysicalMemGB < 4.0) {
        printf("内存小于4GB可能为沙箱环境n");
    }
    else {
        printf("内存: %.2f GBn", totalPhysicalMemGB);
    }
}
  1. 检测硬盘大小

int main()
{
    HANDLE hDevice = CreateFileW(L"\\.\PhysicalDrive0"0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0NULL);

    DISK_GEOMETRY pDiskGeometry;
    DWORD bytesReturned;
    DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL0, &pDiskGeometry, sizeof(pDiskGeometry), &bytesReturned, (LPOVERLAPPED)NULL);

    DWORD diskSizeGB;
    diskSizeGB = pDiskGeometry.Cylinders.QuadPart * (ULONG)pDiskGeometry.TracksPerCylinder * (ULONG)pDiskGeometry.SectorsPerTrack * (ULONG)pDiskGeometry.BytesPerSector / 1024 / 1024 / 1024;

    if (diskSizeGB < 50){
        printf("C盘小于50GB可能为沙箱环境n");
    }
    else {
        printf("C盘大小为%dn",diskSizeGB);
    }
}
  1. 遍历进程,查询是否存在指定进程

int main()
{
    PROCESSENTRY32W processEntry = { 0 };
    processEntry.dwSize = sizeof(PROCESSENTRY32W);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    WCHAR processName[MAX_PATH + 1];
    if (Process32FirstW(hSnapshot, &processEntry))
    {
        do
        {
            StringCchCopyW(processName, MAX_PATH, processEntry.szExeFile);
            //这里我们为了判断时大小写不敏感,就将processName全都转换成大写
            CharUpperW(processName);
            if (wcsstr(processName, L"WECHAT.EXE")) {
                printf("存在对应进程n");
            };
        } while (Process32NextW(hSnapshot, &processEntry));
    }
}
  1. 某些沙箱会修改文件名,所以我们可以通过检测当前文件名的方式

int main()
{

   char buffer[100];
    int len = GetModuleFileNameA(NULL, buffer, 100);
    if (len == 0) {
        printf("Failed to get the module file namen");
    } else {
        char *programName = strrchr(buffer, '\');
        if (programName != NULL) {
            programName++;
            if (strcmp(programName, "ConsoleApplication1.exe") == 0) {
                printf("名字未被修改n");
            }
        }
    }
    return 0;
}

2 基于用户活动的检查

不常用:

  1. 检测鼠标点击次数

  2. 检测鼠标移动速度

3 基于时间

  1. 基于时间的原理就是,在沙箱中时间流速很快,我们让我们的程序睡眠一段时间什么都不干,睡眠时间 > 程序在沙箱中的执行总时间,就可以绕过沙箱,说到睡眠,最简单的就是windows.h的sleep函数

int main()
{   
    Sleep(10000); // 10 秒(10000 毫秒)
}

但是现在这种方法基本上所有沙箱都会进行对抗,直接绕过睡眠函数的执行,

  1. 同类型函数替代

  • WaitForMultipleObjects

  • WaitForSingleObjectEx

  • MsgWaitForMultipleObjects

  • WaitForInputIdle

  • MsgWaitForMultipleObjectsEx

  • NtDelayExecution

  1. 通过对比睡眠前后的时间

// 获取进入睡眠前的系统启动时间到现在的毫秒数
ULONGLONG uptimeBeforeSleep = GetTickCount64();
// 定义一个函数指针类型 PNtDelayExecution
typedef NTSTATUS(WINAPI *PNtDelayExecution)(IN BOOLEAN, IN PLARGE_INTEGER);
// 获取 ntdll.dll 动态链接库中的 NtDelayExecution 函数的地址,并将其赋值给函数指针 pNtDelayExecution
PNtDelayExecution pNtDelayExecution = (PNtDelayExecution)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtDelayExecution");
// 定义一个 LARGE_INTEGER 结构体 delay 用于设置延迟的时间
LARGE_INTEGER delay;
delay.QuadPart = -10000 * 100000// 100 seconds
// 调用 NtDelayExecution 函数,让当前线程进入睡眠状态,睡眠时间为100秒
pNtDelayExecution(FALSE, &delay);

// 获取唤醒后的系统启动时间到现在的毫秒数
ULONGLONG uptimeAfterSleep = GetTickCount64();

// 判断经过的时间是否超过了100000毫秒(即100秒),如果不超过则返回false
if ((uptimeAfterSleep - uptimeBeforeSleep) < 100000)
    return false;

4 其他

  1. 用户交互

//在执行shellcode前放一个交互代码
int main()
{   
    int response = MessageBoxW(NULLL"检测到存在新版本,是否升级?"L"提示", MB_YESNOCANCEL);
    if (response == IDYES) return false;
}
  1. 检测进程数是否大于50

int main()
{   
    DWORD runningProcessesIDs[1024];
    DWORD runningProcessesCountBytes;
    DWORD runningProcessesCount;
    EnumProcesses(runningProcessesIDs, sizeof(runningProcessesIDs), &runningProcessesCountBytes);
    runningProcessesCount = runningProcessesCountBytes / sizeof(DWORD);
    if (runningProcessesCount < 50return false;
    printf("正常系统n");
}

原文始发于微信公众号(小惜渗透):bypass 2-绕沙箱

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月18日17:06:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   bypass 2-绕沙箱http://cn-sec.com/archives/2585352.html

发表评论

匿名网友 填写信息