书接上回,我们再来进一步做一下动态免杀中的反沙箱对抗手段,在面对沙箱等检测环境时也能够从容应对
鄙人技术浅陋,经网上四处观看浏览总结得此文,如有不足希望师傅们多包容⊙﹏⊙
下面开始正文喵
补丁
在正式开始之前,先做一个先前文章的补丁:
在之前刚刚做出 loader 的那一集里面,字符数组写作:
const char shellcode[] = " ";
正确的写法应该是:
const unsigned shellcode[] = { };
另外再补充一下,在运行上线时候会出现 cmd 黑窗口,如果想让他不出现,在编译的时候加上这个参数
-mwindows
就可以安静的运行
对抗沙箱的思路
沙箱大概是什么的定义上上集说过了,这里主要讲一下思路,随后再做一下具体的实现
这里主要记录的都是通用的思路,无针对特定厂商的特定 av/edr 的对抗思路
对比检出率效果均有控制变量,如无特别说明,除比较条件外的操作均为去调试信息+自签名,无其他对抗手段叠加使用
前言
相关的反沙箱的手段不仅仅是为了躲避检测,在实际的上线操作前执行的目的同样是为了隐藏我们的关联信息,防止将我们的远控服务端被沙箱标记(相关论述在上上上集聊过)
隐匿远控服务端的技术本系列不做讨论
时间
系统时间的检测主要针对国外的云沙箱,国外沙箱是免杀的坟场,上了国外沙箱之后用不了多久就会寄掉(上一集已经可以看出来)
但其实对于国外沙箱的对抗思路很简单,他们的模拟环境的时间都不是北京时间,基于这个点,可以检测系统时间(也可以顺便查一下时间流速)就可以防止国外云沙箱的检测
但是诸如微步等沙箱的行为检测已经把检测系统时间标记为高危行为了(
如图:

给出一个具体的实现:
BOOL CheckBeijingTimeZone() {
TIME_ZONE_INFORMATION tzinfo;
GetTimeZoneInformation(&tzinfo);
int tz_offset = tzinfo.Bias;
int tz_offset_hours = tz_offset / 60;
return(tz_offset_hours == -8);
}
然后在主函数中调用
if(timecheck != 1){
return 0;
}
检测到不是北京时间就立即结束进程,不执行后续的上线操作
但是实话实说,直接上图,可以猜猜哪个是做了时区查询的:

答案是左边,做了时区的检测,规避海外沙箱,反倒会让检出率上升好几个

技术进步太快了,查时区已经被标记为 bypass 的明显特征了hh,检测手段搞的越来越厉害了
查时间的样本就不上微步看了(绝对不是因为我懒),检测硬件配置手段的样本会上微步
硬件配置
沙箱都是基于虚拟化技术的纯软件实现,就如图虚拟机一样,为了减小性能开销,优化运行效率,虚拟化的硬件资源都不会太多(就比如虚拟机的经典配置是4核8g内存50g硬盘)
但是现在已经是 2025 年了,还在用这种配置的电脑的人几乎没有了,几百块钱预算的配置都能配到至少 256g 的硬盘了
因此可以检测当前环境的 cpu 、内存、磁盘大小的水平来判断
理论上有误判的可能性,但是几乎不会出现
下面给出一个实现:
bool CheckSystemHardware()
{
//CPU
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors;
if (numberOfProcessors < 2) return false;
//RAM
MEMORYSTATUSEX memoryStatus;
memoryStatus.dwLength = sizeof(memoryStatus);
GlobalMemoryStatusEx(&memoryStatus);
DWORD RAMMB = memoryStatus.ullTotalPhys / 1024 / 1024;
if (RAMMB < 2048) return false;
//硬盘
HANDLE hDevice = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
DISK_GEOMETRY pDiskGeometry;
DWORD bytesReturned;
DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &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 < 100) return false;
return true;
}
调用的时候
hardcheck = CheckSystemHardware();
if(hardcheck != 1){
return 0;
}
记得先声明变量
试试:

然后上国内的微步看看(因为一些原因,报告地址就不贴出来了)
总览:

多引擎检测:

可以看到微软的MSE、ESET、卡巴斯基和 OneStatic(微步自己的)检出了恶意文件,微步的检出了 c2 家族是 vshell(确实有实力啊)
其他的为啥没检测出呢????其实我也不知道,我看见过了 360 之后我还自己装了 360 杀毒(肯定不可能过啊),瞬间就杀到了,静态都过不去,但是在微步上面的没过,不是特别懂,仅作参考
看一下动态检测部分:


可见虽然没有做到全部 bypass 的免杀,但是对于动态沙箱的检测是可以做到成功检测的(虽然反沙箱的手段肯定会被沙箱怀疑,但是可以防止被进一步分析,还能保护后续上线的行为特征信息)
另外针对微步沙箱的话,还可以利用桌面上的固定 npc 的 adobe 的快捷方式,如果有这个快捷方式就 stop,也是个方法
这个手法在几年前是能 vt 全绿的,免杀易如反掌啊(哭了
技术在进步,不能停止学习啊
睡大觉
从这一节开始不再给出具体实现和沙箱检测了(意义不大)
就是运行后先挂起,或者执行一些不相干的功能,在一段时间(几十秒到几分钟)后再执行 shellcode 上线沙箱通常
虚拟机特定的特征
比如网卡名称,注册表中的信息等(这里不过多赘述)
实际意义不大,现有的沙箱平台多数都是自身开发的虚拟化技术,使用 vmware,virtualbox 之类现成轮子的可能性不大,除非是人工分析的情况下被拖入虚拟机上工具分析
运行时间
样本上传,然后沙箱启动,也就是说沙箱的系统运行时间不会太长
可以获取当前系统运行的时长,进行一个判断
还有很多别的可以检测的不再一一列举了喵
本来计划着没有下面的内容,但是学着写着,觉得这个还是可以提一句:

可以在微步上看到这个技术检测的矩阵,但是点击标题跳转超链接是 404 的(右侧有进度条可以拖动,不止图中这些
记录着的都是沙箱可能会对样本进行侦测的行为喵
反沙箱的主要目的是对抗沙箱的检测,阻止样本被进一步动态分析,可能并不会对免杀效果有所提升
下一集说一点针对杀软检测的规避手段,比如我们样本中的 VirtualAlloc 函数就是导致被检出的原因之一喵
