6. Hands-on-Keyboard: The Second Stage
Chapter 5 ended at the funnel: up to roughly 18,000 potentially affected customers, the DNS control plane observed in passive DNS, and a much smaller publicly documented set receiving hands-on follow-on activity. SUNBURST was only ever the door. For selected targets, the operators came through it by hand, and that is where a supply-chain infection became a real intrusion.
This chapter has two layers, and the line between them matters:
- The loaders, as artifacts. TEARDROP and RAINDROP were examined as binaries; their job—to map Cobalt Strike BEACON into memory—is read line by line from the decompilation.
- What the operators did once inside. The hands-on tradecraft (credential theft, Golden SAML, mailbox export) is not established by those binaries; it is documented by vendor incident response (Mandiant, Microsoft, Volexity) and is included here, clearly marked as cited, not derived, because it is the layer where the espionage objective was actually met.
6.1 The kill chain, and where each piece lives
SUNBURST has no in-memory loader of its own. Its command set (Chapter 4) is all disk-based:
WriteFile (stage bytes), SetRegistryValue (config/persistence), RunTask → Process.Start
(launch). So the chain hands off in stages:
SUNBURST ── stages loader DLL (+ payload) to disk, installs a service ──▶
TEARDROP / RAINDROP ── map & execute BEACON in memory ──▶
Cobalt Strike BEACON (in memory) ── operator C2, lateral movement, theft
Each link is a different tool with a different on-disk footprint. SUNBURST writes files and starts a service; the loader is the thing on disk that turns a blob into running BEACON; BEACON itself is the hands-on implant. The two loaders examined here solve the same problem, get BEACON running without dropping a recognizable BEACON PE, in two different ways.
6.2 TEARDROP: a service loader that reads a “JPEG”
TEARDROP (1817a5bf…, on-disk name NETSETUPSVC.DLL) is a Windows-service
loader. It is not self-contained: it reads its payload from an external file masqueraded as a
JPEG, and maps the recognizable BEACON PE entirely into memory so it never touches disk. It
decompiles to a compact 79 functions (IDA) / 201 (Binary Ninja). The call order:
NetSetupServiceMain() // ServiceMain export, runs as the NETSETUPSVC service
└ CreateThread(StartAddress)
└ StartAddress(): AddVectoredExceptionHandler(Handler) → sub_21514B2960() // the loader
Running as a service ServiceMain is the persistence and the privilege: a service runs at boot,
unattended, with high privilege. The real work is in the loader, sub_21514B2960:
// TEARDROP, IDA Hex-Rays
FileA = CreateFileA("festive_computer.jpg", 0x80000000, 3u, 0, 3u, 0x80u, 0); // (1) open the "JPEG"
ReadFile(FileA, &hdr, 0x40u, …); // (2) read 0x40-byte header
if ( hdr[0] == 0xFF && hdr[1] == 0xD8 ) { strcpy(Buf2,"JFIF"); memcmp(&hdr[6],"JFIF",4); } // (3) looks like a JPEG
…
v7 = v4 ^ 0x7FFFFFFF; // (4) XOR-decode the body → the real BEACON shellcode
// __write_memory_part_0(): VirtualProtect(…, 0x40 /*PAGE_EXECUTE_READWRITE*/) + memcpy // (5)
v9(…); // (6) call the decoded shellcode IN MEMORY
Line by line:
CreateFileA("festive_computer.jpg", …): open a file that, on disk, looks like an image. The payload is staged separately (by SUNBURST); the loader just consumes it. (Vendor reporting documents a sibling variant readinggracious_truth.jpg; the file name is per-intrusion, the technique is constant.)ReadFile(… &hdr, 0x40u …): read the first 64 bytes.hdr[0]==0xFF && hdr[1]==0xD8…"JFIF": check the JPEG magic (FF D8) and theJFIFtag. The file is a structurally valid-looking JPEG header, so a cursory look, or a file type check, sees an image. The real payload sits past the header.v4 ^ 0x7FFFFFFF: XOR-decode the body. Until this runs, the BEACON shellcode is just obfuscated bytes inside an “image”; there is no executable BEACON on disk to scan for.VirtualProtect(…, PAGE_EXECUTE_READWRITE)+memcpy: copy the decoded bytes into memory and make that memory executable (0x40=PAGE_EXECUTE_READWRITE). This is the moment the data becomes code.v9(…): call into the now-executable region: Cobalt Strike BEACON runs, in memory.
A disk scanner therefore sees a service DLL and a harmless .jpg: nothing that resembles BEACON.
The payload only becomes code after the VirtualProtect(PAGE_EXECUTE_READWRITE) flip. (The loader
also references a SOFTWARE\Microsoft\CTF registry path, an alternate payload/config source
across variants.) This exact decode-and-map routine is what FireEye’s APT_Dropper_*_TEARDROP
YARA matches, keying on the byte runs 4A 46 49 46 ("JFIF") and 53 4F 46 54 57 41 52 45
("SOFTWARE") plus the decode opcodes.
6.3 RAINDROP: the same goal, fully self-contained
RAINDROP (be9dbbec…, on-disk name 7z.dll) is a second BEACON loader, built
from a modified 7-Zip so it can ride a legitimate executable as a side-loaded DLL. It was used
for lateral movement, spreading BEACON to additional hosts. The key difference from TEARDROP:
RAINDROP carries the BEACON payload embedded inside itself; there is no external “JPEG,” no
separate payload file. It is the larger of the two (797 functions IDA / 848 BN). Entry is via
DllMain:
// RAINDROP, IDA Hex-Rays: DllMain
CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)post_pgo_initialization, nullptr, 0, nullptr);
Loading the DLL (via the legitimate host binary it side-loads into) is enough to kick off a worker
thread. That thread then assembles and decrypts the embedded payload (a telltale 31× memmove
to reconstruct it in pieces), maps it executable, and runs it in the classic loader sequence:
VirtualAlloc ×5 → copy/decrypt payload → VirtualProtect ×2 (PAGE_EXECUTE_READ) → CreateThread
Same destination as TEARDROP, BEACON executing in memory, reached without an external payload file at all. RAINDROP is thus the more “fileless” of the pair: only the loader DLL is on disk.
6.4 What “memory-only” does and does not mean
“Memory-only” is widely misread as “nothing on disk.” That is wrong, and the distinction is a detection point:
| Stage | On disk? | In memory only? |
|---|---|---|
| SUNBURST DLL | Yes (it is a signed Orion file) | No |
Loader (TEARDROP NETSETUPSVC.DLL / RAINDROP 7z.dll) |
Yes, always | No |
TEARDROP payload (festive_computer.jpg) |
Yes, as a disguised file | No |
| Cobalt Strike BEACON PE | No, never dropped | Yes |
“Memory-only” means the recognizable BEACON PE is never written to disk; it exists only after
the loader decodes and maps it. It does not mean the attack leaves no disk artifacts: the
loader DLL is always present, and TEARDROP additionally leaves the disguised payload. For a
defender, that is the opening: you will not find BEACON on disk, but you can find an anomalous
service DLL (NETSETUPSVC.DLL), a side-loaded 7z.dll, a stray *.jpg that isn’t an image or,
at runtime, a private memory region freshly flipped to PAGE_EXECUTE_READWRITE inside a service
process.
6.5 What the operators did once inside (cited, not derived from the loaders)
Provenance boundary. Everything in §6.2–6.4 is read from the loader binaries. Everything in this section is vendor-documented incident response reporting from Mandiant, Microsoft, and Volexity. It is not a capability of the loaders here, and it was not derived from any artifact. It is included because it is where the campaign’s espionage objective was actually achieved.
BEACON in memory was a means, not an end. Once the operators had hands-on access in an escalated victim, the reporting describes a deliberately low-malware, credential-centric style: “living off the land,” using legitimate credentials and rotating per-victim infrastructure (often hosted in the US to dodge geolocation heuristics) so the activity blended with normal admin work.
The signature technique was an attack on identity infrastructure, not endpoints:
- Golden SAML. After obtaining administrative access on-premises, the actor stole the organization’s AD FS token signing certificate and used it to forge SAML authentication tokens. With a forged token, they could authenticate to federated cloud services (Microsoft 365, Azure AD) as any user, including administrators, bypassing both passwords and MFA, because a forged token removes the identity provider from the flow entirely and produces no authentication event at AD FS to alert on. The technique was first described by CyberArk in 2017; SolarWinds is the first known in-the-wild use. (Tellingly, CISA found victims showing SAML token abuse with no identified Orion compromise, evidence of additional initial access vectors beyond the supply chain, and a reminder from Chapter 2 that “SolarWinds victim” and “Orion victim” are not synonyms.)
- Targeted mailbox theft. Volexity’s casework (its “Dark Halo” cluster) documents the
objective concretely: Exchange-focused reconnaissance, scheduled tasks for remote execution,
selective mailbox export through Exchange, staging password-protected archives under OWA
paths (e.g.
owa\auth\Redir.png), manipulating ActiveSync device IDs (Set-CASMailbox) to pull mail, and then cleaning up the export artifacts. The targets were the emails of specific executives, policy experts, and, pointedly, IT and incident response staff. - MFA bypass by stolen secret. Separately, Volexity observed the actor steal a Duo
integration secret from an OWA server and forge a valid
duo-sidcookie to bypass MFA for webmail, a second, independent identity bypass theme. - Later persistence in the identity plane. Microsoft’s subsequent reporting describes FoggyWeb (a passive backdoor that exfiltrates the AD FS configuration database and decrypted token signing/decryption certificates) and MagicWeb (an AD FS backdoor allowing authentication as any user), the same identity-first philosophy, made persistent.
Hunting pivots that follow from this (for retrospective log review, per the same reporting):
historic DNS for avsvmcloud[.]com, treating CNAME responses as a far stronger targeting
signal than A records (Chapter 5); unexplained outbound web traffic from Orion servers;
New-MailboxExportRequest / Get-MailboxExportRequest and archives under OWA paths; anomalous
SAML token issuance with no corresponding AD FS event; and suspicious process ancestry such as
rundll32.exe or cmd.exe spawned by wmiprvse.exe or solarwinds.businesslayerhost.exe,
the very process SUNBURST lived in (Chapter 4).
6.6 Why this layer is the real damage
The loaders are the interesting reverse engineering; the identity tradecraft is the actual harm. Stacking the chain: a poisoned update gave the actor a foothold in the Orion service process, which SolarWinds documented as running under LocalSystem by default (the Epilogue); SUNBURST could use that inherited context to drop a loader; the loader ran BEACON in memory; and BEACON’s operators pivoted into the cloud by forging identity itself, reading the email of exactly the people whose email an intelligence service wants. That is the espionage objective from Chapter 2, completed.
It also explains why, for the escalated victims, patching was never enough. If the actor forged your federation trust, rebuilding the Orion box does nothing; remediation meant rotating the AD FS token signing certificate, reissuing secrets, and re-establishing trust. The policy response in Chapter 10 had to grapple with that burden. The product’s documented privilege model increased the potential reach of that foothold, but the artifacts examined here do not prove the exact path or success of every hands-on intrusion; that distinction is the Epilogue’s subject.
Sources & evidence
- Book reference: See the Appendix: Timeline, IOCs, and Artifact Map for loader hashes, indicators, and evidence provenance.
- Loaders (locally decompiled, grounded): TEARDROP (
1817a5bf…) supplies thefestive_computer.jpg→JFIFcheck →^ 0x7FFFFFFF→VirtualProtect(RWX)sequence insub_21514B2960; RAINDROP (be9dbbec…) supplies theDllMain→post_pgo_initializationandVirtualAlloc→VirtualProtect→CreateThreadsequence. - Operator tradecraft (public reporting, NOT derived from these samples): Golden SAML, the Volexity mailbox export and Duo bypass casework, FoggyWeb/MagicWeb, the living-off-the-land style, and the hunting pivots, see Mandiant’s Microsoft 365 remediation analysis, Microsoft’s second-stage analysis, and Volexity’s Dark Halo casework.
- Provenance: §6.2–6.4 are read from artifacts; §6.5 is vendor-documented and explicitly not a capability of the samples here.
- Forward references: the privileged foothold → the Epilogue; the remediation/policy fallout → Chapter 10.