Lesson 3 of 9 · 22m
Sandboxes: Useful Liars
What a sandbox verdict really means, when uploading a sample is a leak, how to make samples actually detonate, and the evasion tricks that produce clean reports for dirty files.
A sandbox report is a witness statement, not a verdict. "No malicious activity" means nothing we recognized happened in the 120 seconds we watched, in this VM, with this configuration. I once signed off on a loader that came back clean from two sandboxes. It slept for ten minutes in a loop of short NtDelayExecution calls — too fragmented for the sandbox's sleep-skipping to collapse. EDR caught it on 40 hosts the next morning. Static had shown the VM checks; I trusted the green badge over my own notes.
Public vs private: uploading is publishing
Uploading to VirusTotal or a public sandbox shares the file with every subscriber who can download it — and actors monitor those services for their own hashes. Targeted samples routinely contain the victim's email address, internal hostnames, or even credentials in a phishing kit. The rule:
- Hash lookup first. Already public? You've lost nothing.
- Unknown and targeted? Private sandbox only (self-hosted CAPE, or a commercial sandbox in private mode).
- Public upload only with the IR lead's sign-off, after the client knows.
Getting it to actually run
Half of "clean" reports are samples that never really executed:
- DLLs:
DllMainoften does nothing. List exports first, then call the one that matters. - Scripts:
.js/.vbsrun underwscript.exe;.htaundermshta.exe. - Documents: macros need Office installed and content enabled; the lure tells you which button the victim was asked to press.
- Containers: ISO/IMG/ZIP deliveries hide an
.lnkthat launches the real payload — detonate the shortcut, not the container.
# CAPE: run a DLL's export with a longer timeout
python3 utils/submit.py --package dll --options "function=DllRegisterServer" --timeout 300 9e1c4f.dllC:\> rundll32.exe C:\Users\Public\9e1c4f.dll,DllRegisterServerThe evasion checklist
What commodity loaders check before doing anything interesting:
if (GetTickCount64() < 10 * 60 * 1000) ExitProcess(0); // uptime < 10 min: fresh sandbox VM
if (si.dwNumberOfProcessors < 2) ExitProcess(0); // 1 vCPU: cheap analysis VM
if (ms.ullTotalPhys < (4ULL << 30)) ExitProcess(0); // < 4 GB RAM
if (mac_prefix_is(0x08, 0x00, 0x27)) ExitProcess(0); // VirtualBox OUI
if (recent_docs_count() < 10) ExitProcess(0); // nobody actually uses this machine
if (keyboard_layout_is_cis()) ExitProcess(0); // geofence: don't detonate at homeCountermeasures: realistic VMs (4+ vCPUs, 8 GB, a lived-in user profile with browser history and documents), changed MAC prefixes and hardware strings, human-interaction emulation, longer timeouts, and running the same sample under two or three configurations.
Reading the report in the right order
Process tree → dropped files → network (DNS names, HTTP paths) → memory dumps and extracted configs → then signatures. Signatures are heuristics: "queries computer name" fires on every installer ever built.
Field notes
- Clean sandbox + suspicious static = inconclusive, never "benign". Write it that way.
- Record the environment in your report — OS build, timeout, network mode. IR needs to know whether "no C2 seen" means "no C2" or "INetSim answered".
- With INetSim, every DNS answer is your sinkhole IP. Domains in the report are real; resolved IPs are not. Never paste sandbox-resolved IPs into an IOC list.
- If the sample checks for a debugger or VM, that's a behavior worth reporting by itself.