文章总结: 本文探讨了Windows平台下的沙箱对抗技术,旨在区分真实环境与沙箱以规避分析。作者提供了多种检测思路与C++实现代码,包括扫描桌面快捷方式以识别IDA等逆向工具、检测VMware目录判断虚拟机环境、监测鼠标移动及调用蜂鸣器模拟用户交互。文章最后整合了完整代码模板,强调了组合多种技巧对抗沙箱的重要性。 综合评分: 85 文章分类: 免杀,恶意软件,逆向分析,二进制安全
记一次另类的沙箱对抗
原创
zyxa
众亦信安
2026年1月14日 10:55 湖南
声明:文中涉及到的技术和工具,仅供学习使用,禁止从事任何非法活动,如因此造成的直接或间接损失,均由使用者自行承担责任。
众亦信安,中意你啊!
温馨提示:当前公众号推送机制调整,仅常读及星标账号可展示大图推送。建议各位将众亦信安团队设为“星标“,以便及时接收我们的最新内容与技术分享。
从上次的云沙箱对抗方法中我门针对微步在线沙箱的运行截图这个特征来进行沙箱绕过
那么我们也可以从这个点入手从特定特征来进行对抗
从逆向人员角度
逆向人员一般有ida dbbug等相关逆向工具,所以我们只需要检测桌面上是否有相关名称等
bool HasDebuggerDesktopShortcut(){ static const std::vector<std::wstring> targets = { L"ida64.exe", L"ollydbg.exe", L"x32dbg.exe", L"x64dbg.exe" };
static const int desktopTypes[] = { CSIDL_DESKTOPDIRECTORY, CSIDL_COMMON_DESKTOPDIRECTORY };
auto CheckDesktop = [&](const std::wstring& desktopPath) -> bool { std::wstring search = desktopPath + L"\\*.lnk";
WIN32_FIND_DATAW fd; HANDLE hFind = FindFirstFileW(search.c_str(), &fd); if (hFind == INVALID_HANDLE_VALUE) return false;
do { std::wstring lnkPath = desktopPath + L"\\" + fd.cFileName;
IShellLinkW* pShellLink = nullptr; if (FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void**)&pShellLink))) continue;
IPersistFile* pPersistFile = nullptr; pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile); if (!pPersistFile) { pShellLink->Release(); continue; }
if (FAILED(pPersistFile->Load(lnkPath.c_str(), STGM_READ))) { pPersistFile->Release(); pShellLink->Release(); continue; }
wchar_t targetPath[MAX_PATH] = { 0 }; WIN32_FIND_DATAW wfd; pShellLink->GetPath(targetPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY);
std::wstring exePath = targetPath; for (const auto& exe : targets) { if (!exePath.empty() && exePath.find(exe) != std::wstring::npos) { pPersistFile->Release(); pShellLink->Release(); FindClose(hFind); return true; } }
pPersistFile->Release(); pShellLink->Release();
} while (FindNextFileW(hFind, &fd));
FindClose(hFind); return false; };
if (FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) return false;
for (int csidl : desktopTypes) { wchar_t path[MAX_PATH]; if (SUCCEEDED(SHGetFolderPathW(nullptr, csidl, nullptr, 0, path))) { if (CheckDesktop(path)) { CoUninitialize(); return true; } } }
CoUninitialize(); return false;}
同时一般是在虚拟机中运行所以我们可以检测运行时是否是虚拟机环境,这里可以参考上一篇文章的检测是否有相关目录
bool isVMwareInstalled() { WIN32_FIND_DATAW findFileData; HANDLE hFind;
// 构建搜索路径 wchar_t path[MAX_PATH]; swprintf(path, MAX_PATH, L"C:\\Program Files\\VMware");
// 搜索目录 hFind = FindFirstFileW(path, &findFileData); if (hFind != INVALID_HANDLE_VALUE) { // 如果找到目录,则关闭搜索句柄并返回 true FindClose(hFind); return true; } else { // 如果未找到目录,则返回 false return false; }}
#
从云沙箱角度
从云沙箱角度来对抗更加简单,参考上一篇文章,这里提供别的思路,云沙箱没有没有cpu温度,鼠标移动活动,键盘活动等之类的情形,所以我们可以从这些方面入手
检测鼠标情况
bool HasRealMouseMove( int maxMove = 5, DWORD intervalMs = 1000, DWORD timeoutMs = 3000 // 3 秒){ POINT oldPoint{}, currentPoint{}; int moveCount = 0;
GetCursorPos(&oldPoint);
DWORD start = GetTickCount();
while (GetTickCount() - start < timeoutMs) { Sleep(intervalMs);
GetCursorPos(¤tPoint);
if (currentPoint.x != oldPoint.x || currentPoint.y != oldPoint.y) { oldPoint = currentPoint; ++moveCount; }
if (moveCount >= maxMove) return true; }
return false; // 超时仍未检测到真实鼠标}
检测是否存在蜂鸣器
#include <Windows.h>#include <stdio.h>// 调用Beep 实现延迟执行int time_Beep(){// 设置延迟 30000毫秒 int wh_compter = 0;int wh_total = 30000;
while(wh_compter < wh_total){Beep(2, 1); // 2hertz, 1ms 设置低频和短暂的间隔时间实现听不见蜂鸣声wh_compter++;}
if(wh_compter > wh_total - 1)return 1;
return 0;}
int main(){if(time_Beep())printf("调用Beep 延迟执行成功 \n");elseprintf("调用Beep 延迟执行失败 \n!");return 0;}
沙箱对抗需要多种技巧组合才能发挥更好的作用,反沙箱的意义是为了区分真实环境和沙箱环境以确保我们的马子在沙箱环境中不被执行
这里提供一个完整模板
#include <windows.h>#include <shlobj.h>#include <shobjidl.h>#include <string>#include <vector>#include <iostream>
//判断是否是逆向人员bool HasDebuggerDesktopShortcut(){ static const std::vector<std::wstring> targets = { L"ida64.exe", L"ollydbg.exe", L"x32dbg.exe", L"x64dbg.exe" };
static const int desktopTypes[] = { CSIDL_DESKTOPDIRECTORY, CSIDL_COMMON_DESKTOPDIRECTORY };
auto CheckDesktop = [&](const std::wstring& desktopPath) -> bool { std::wstring search = desktopPath + L"\\*.lnk";
WIN32_FIND_DATAW fd; HANDLE hFind = FindFirstFileW(search.c_str(), &fd); if (hFind == INVALID_HANDLE_VALUE) return false;
do { std::wstring lnkPath = desktopPath + L"\\" + fd.cFileName;
IShellLinkW* pShellLink = nullptr; if (FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void**)&pShellLink))) continue;
IPersistFile* pPersistFile = nullptr; pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile); if (!pPersistFile) { pShellLink->Release(); continue; }
if (FAILED(pPersistFile->Load(lnkPath.c_str(), STGM_READ))) { pPersistFile->Release(); pShellLink->Release(); continue; }
wchar_t targetPath[MAX_PATH] = { 0 }; WIN32_FIND_DATAW wfd; pShellLink->GetPath(targetPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY);
std::wstring exePath = targetPath; for (const auto& exe : targets) { if (!exePath.empty() && exePath.find(exe) != std::wstring::npos) { pPersistFile->Release(); pShellLink->Release(); FindClose(hFind); return true; } }
pPersistFile->Release(); pShellLink->Release();
} while (FindNextFileW(hFind, &fd));
FindClose(hFind); return false; };
if (FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) return false;
for (int csidl : desktopTypes) { wchar_t path[MAX_PATH]; if (SUCCEEDED(SHGetFolderPathW(nullptr, csidl, nullptr, 0, path))) { if (CheckDesktop(path)) { CoUninitialize(); return true; } } }
CoUninitialize(); return false;}//判断是否北京时间bool IsBeijingTimeZone() { TIME_ZONE_INFORMATION tzinfo; GetTimeZoneInformation(&tzinfo); // 计算时区偏移量(以分钟为单位) int tz_offset = tzinfo.Bias; // 将分钟转换为小时 int tz_offset_hours = tz_offset / 60; if (tz_offset_hours == -8) { return false; }}
//判断是否有鼠标活动bool HasRealMouseMove( int maxMove = 5, DWORD intervalMs = 1000, DWORD timeoutMs = 3000 // 3 秒){ POINT oldPoint{}, currentPoint{}; int moveCount = 0;
GetCursorPos(&oldPoint);
DWORD start = GetTickCount();
while (GetTickCount() - start < timeoutMs) { Sleep(intervalMs);
GetCursorPos(¤tPoint);
if (currentPoint.x != oldPoint.x || currentPoint.y != oldPoint.y) { oldPoint = currentPoint; ++moveCount; }
if (moveCount >= maxMove) return true; }
return false; // 超时仍未检测到真实鼠标}
//判断是否为虚拟机bool isVMwareInstalled() { WIN32_FIND_DATAW findFileData; HANDLE hFind;
// 构建搜索路径 wchar_t path[MAX_PATH]; swprintf(path, MAX_PATH, L"C:\\Program Files\\VMware");
// 搜索目录 hFind = FindFirstFileW(path, &findFileData); if (hFind != INVALID_HANDLE_VALUE) { // 如果找到目录,则关闭搜索句柄并返回 true FindClose(hFind); return true; } else { // 如果未找到目录,则返回 false return false; }}
int main(){
}
加入圈子获取更多反沙箱思路
圈子介绍
后续更新suo5二开、自研webshell管理工具、cs远控等,目前定价129/年,前30名的师傅享受85折优惠。
往这里看
点点关注不迷路,不定时持续分享各种干货。可关注公众号回复”进群”,也可添加管理微信拉你入群。
项目交流,src/众测挖掘,重大节日保障,攻防均可联系海哥微信。
入了小圈的朋友联系海哥进内部交流群。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:众亦信安 zyxa《记一次另类的沙箱对抗》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论