Laeteth/advanced-anti-sandbox-Virtual-Machine
GitHub: Laeteth/advanced-anti-sandbox-Virtual-Machine
一个专注于Windows平台反沙箱技术的代码示例集合,提供多种检测虚拟化和分析环境的方法。
Stars: 7 | Forks: 1
# 反沙箱随想
# 介绍
在学习反检测技术时,我遇到了一个无法回避的挑战:反沙箱技术。当我们的样本被上传到在线分析网站时,它们会在虚拟化环境中经历动态和静态分析。该过程会记录敏感操作,以判定样本是否为恶意软件。我们可能都遇到过这种情况:CS 连接到许多具有不同用户名和操作系统的国外机器,但心跳包却异常短。此时,我们可以确信样本已落入沙箱环境。我们该怎么办?让我们通过探讨作者对反沙箱技术的思考来进一步探索。
# 沙箱
在讨论反沙箱之前,我们先明确一下什么是沙箱。[美国国家标准与技术研究院 (NIST)](https://csrc.nist.gov/glossary/term/sandbox) 将沙箱定义为“一个允许不受信任的应用程序在高度受控的环境中运行的系统,其中应用程序的权限被限制为一组基本的计算机权限。”
沙箱实际上可以分为三种类型:软件、硬件和云端。
常见的软件包括:[sandboxie](https://sandboxie-plus.com/downloads/) 用于在沙箱环境中启动程序;VMware 和 Docker 也被视为软件沙箱的实现。
硬件解决方案通常作为企业解决方案出售,例如华为的 [FireHunter6000](https://e.huawei.com/cn/products/security/firehunter6000)。
云端的则是我们常用的沙箱网站,例如:
* https://s.threatbook.com/ 微步在线沙箱
* https://www.virustotal.com/ VT
* https://any.run/ 交互式沙箱
* https://www.joesandbox.com/#windows Joe Sandbox
* https://www.hybrid-analysis.com/ 混合分析系统
* https://sandbox.dbappsecurity.com.cn/ 安恒云沙箱
* https://sandbox.ti.qianxin.com/sandbox/page 奇安信沙箱
* https://sandbox.freebuf.com/ Freebuf 沙箱
* https://ata.360.net/ 360 云沙箱
* https://habo.qq.com/ 哈勃沙箱
# 前置条件
如果你想为你的木马样本构建反沙箱能力,请确保满足以下前置条件:
* 能够静态免杀
* 确保静态资源中不存在敏感信息;尽量避免混淆。
* 如果以 shellcode 形式加载,请预先加密 shellcode(避免使用短密钥的对称加密)。
* 无其他前置条件
* 例如,在加载逻辑之前执行反调试检查
* 确保程序执行时首先调用反沙箱逻辑
作者使用 Visual Studio 2019,以 C++ 作为编程语言。有其他偏好的读者可自由切换到不同的 IDE 或编程语言。
# 思路
## 开胃菜
如何对抗微步沙箱?
首先,我们来看看微步的释放功能。它会在 C 盘下生成一个随机字符串名称的文件夹来运行。

此时,我们可以编写代码,利用简单的正则表达式匹配来绕过沙箱。
```
std::string workingdir()
{
char buf[256];
GetCurrentDirectoryA(256, buf);
return std::string(buf);
}
bool check_run_path() {
std::string test(workingdir());
std::regex pattern("^C:\\\\[A-Za-z0-9_]+");
if (std::regex_match(test, pattern)) {
return false;
}
else {
return true;
}
}
```
成果展示
 微步多年以来都是这样释放样本的,理论上不会失效。接下来会以三个反向介绍反沙箱的思路
## 基于时间的检测
用于延时。由于沙箱可能会加速进程或通过 hooking 技术绕过时间延迟,因此最好结合差分检测。
延迟时间应足够长,因为某些虚拟机可能需要较长时间才能完成分析。
常规
* NtDelayExecution
* WaitForSingleObject
* SetTimer
* SetWaitableTimer
* CreateTimerQueueTimer
进阶
* 使用 API 泛洪
* GetSystemTimeAdjustment
* 实现自定义计时器
* 实现计时器功能
* 使用求算法引入延迟
* 从其他进程检索时间 例如,计划任务
* select (Windows sockets)
协同
* 在线时间戳查询以确定时间差
* NTP
* 第三方 API
我使用的
* 时间延迟和差分检测
```
bool check_time() {
auto url = ("http://api.pinduoduo.com");
httplib::Client cli(url);
auto res = cli.Get("/api/server/_stm");
std::string time_str1;
if (res->status == 200) {
for (char c : res->body) {
if (c >= '0' && c <= '9') {
time_str1 += c;
}
}
}
else {
return false;
}
long long api_time1 = std::stoll(time_str1);
time_t currentTime1 = time(0);
//开始休眠300秒
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
WaitForSingleObject(hEvent, 300000);//300s
CloseHandle(hEvent);
res = cli.Get("/api/server/_stm");
std::string time_str2;
if (res->status == 200) {
for (char c : res->body) {
if (c >= '0' && c <= '9') {
time_str2 += c;
}
}
}
else {
return false;
}
long long api_time2 = std::stoll(time_str2);
//判断差值
if (api_time2 - api_time1 > 290000) {
return true;
}
else {
exit(0);
return false;
}
}
```
为了确定系统启动时间,虚拟机通常会持续运行很长时间。我们可以使用 WINAPI GetTickCount() 函数来实现此目的。
但是,如果我们的样本目标是测试服务器,则确定系统启动时间会变得无效。
## 因素评估
标准
+ 确定CPU核心数 dwNumberOfProcessors
+ 确定RAM大小 GlobalMemoryStatus
+ 确定硬盘大小 PhysicalDrive0
+ 确定系统用户名
+ 以前有一个用于确定用户名的字典,但现在通常是随机数,如 DESKTOP-XXX。
+ 确定工作组
进阶:本节包含一个专业术语:**Pocket Litter**(口袋垃圾/残留物)
+ 确定桌面文件数量
+ 大多数沙箱桌面上的文件很少,虽然有各种 Office 软件,但缺少微信或 QQ 等应用
+ 我们可以判断文件是否低于某个阈值来识别沙箱
+ 检查是否存在微信、QQ、企业微信以及其他符合中国用户习惯的软件
+ 确定临时文件数量
+ 相反,与普通用户相比,过多的临时文件可能表明是沙箱
+ 检测系统中 doc、xls、ppt 文件的数量
+ 数量过少可能表明是沙箱环境
+ 检测可执行文件名是否已被修改
+ 检测进程是否在特定时间窗口内运行(常见于 APT 攻击,HVV 中经常使用)
+ 通过 GetSystemDefaultLangID 检测系统语言
+ 俄罗斯 APT 组织常用的策略;如果检测到俄语,进程则退出
+ 检测附加的 DLL 是否在黑名单中
+ 确定 IP 地址
+ 根据目标标准进行评估
+ 例如,如果针对中国大陆,检查非国内 IP 以对抗国外沙箱
+ 或者,将范围缩小到地级市
+ 验证扬声器功能和可访问性
+ 确认麦克风响应
+ 统计活动前台窗口数量
+ 虚拟机中通常较少
+ 检测鼠标移动
+ 以前流行的技术:GetCursorPos
+ 获取坐标后,延迟两次并计算向量。如果结果形成三角形,则可能不是沙箱
+ 自从在 ATT&CK 框架中被标记以来,已被列为敏感行为
+ 检查显卡显存大小
+ 家用电脑通常超过 2GB,而沙箱分配的较少
+ 检查系统变量
+ 主要查找与虚拟机文件相关的环境变量
+ 检查 CPU 温度
请注意:建议使用 GetSystemFirmwareTable API 从 SMBIOS 检索硬件信息。
使用 WMI API 将被视为敏感操作。
我使用的
+ IP 检测
```
bool check_ip() {
auto url = "http://ip-api.com";
httplib::Client cli(url);
auto res = cli.Get("/csv");
std::string ip_str;
if (res->status == 200) {
for (char c : res->body) {
ip_str += c;
}
}
else {
exit(0);
return false;
}
if (ip_str.find("China") != std::string::npos) {
//std::cout << "The string contains 'China'." << std::endl;
return true;
}
else {
//std::cout << "The string does not contain 'China'." << std::endl;
exit(0);
return false;
}
}
```
+ 鼠标检测
```
double distance(POINT p1, POINT p2) {
double dx = p2.x - p1.x;
double dy = p2.y - p1.y;
return sqrt(dx * dx + dy * dy);
}
bool check_mouse() {
POINT p1, p2, p3;
GetCursorPos(&p1);
Sleep(3000);
GetCursorPos(&p2);
Sleep(3000);
GetCursorPos(&p3);
double d1 = distance(p1, p2);
double d2 = distance(p2, p3);
double d3 = distance(p3, p1);
// 检查是否能构成一个类三角形
if ((d1 + d2 > d3) && (d2 + d3 > d1) && (d1 + d3 > d2)) {
return true;
}
else {
return false;
}
}
```
## 非常规手段
还存在其他奇特的反沙箱技术:
* 体积膨胀
* 许多在线反沙箱系统都有大小限制。如果你的样本超过 300MB,将不会被接受。
* 反向收集
* 编写一个旨在收集沙箱指纹的样本,总结沙箱的特征以便日后识别。
* 压缩炸弹
* 部署压缩包炸弹以消耗服务器资源。
# 疑问
本文不会涵盖反调试或反虚拟化技术。反调试方法非常敏感,而反虚拟化通常是不必要的,因为许多服务器运行在模拟的集群虚拟机上。此外,敏感的沙箱检测方法也不会被讨论,因为网上已经存在许多常规方法。在实践中,有效沙箱检测的关键不在于使用方法的数量,而在于其在实际应用中的简单性和实用性。
# 总结
随着沙箱技术的进步,反沙箱技术也在不断演变。目前,我们对沙箱的应用仍主要停留在机械层面,但许多安全公司已经开始开发集成 AI 的沙箱系统。因此,作为安全研究人员,我们必须不断提高我们的技术能力,以跟上技术的进步。
该项目已在 GitHub 上开源。欢迎提交 issue。
https://github.com/yj94/Anti-Sandbox
# 参考
* https://en.wikipedia.org/wiki/Sandbox_(computer_security)
* https://csrc.nist.gov/glossary/term/sandbox
* https://github.com/Hz-36/Anti-Sandbox
* https://github.com/ZanderChang/anti-sandbox
* https://github.com/LordNoteworthy/al-khaser
* https://attack.mitre.org/techniques/T1497
* https://evasions.checkpoint.com
# 声明
本项目首次发布于先知社区。转载请注明出处! https://xz.aliyun.com/t/14381
标签:Anti-Debug, Anti-Sandboxie, Anti-VM, Cobalt Strike, DAST, DNS 反向解析, DOM解析, evasion, 云资产清单, 动态分析防御, 反沙箱, 反虚拟化, 反调试, 威胁情报, 安全技术, 开发者工具, 恶意软件分析, 攻击诱捕, 数据展示, 样本保护, 沙箱检测, 环境感知, 私有化部署, 端点可见性, 红队, 虚拟机检测, 逃逸技术, 逆向工程, 防御规避