Malware identities / source figures

Samples and source figures

Hashes for the analyzed files, followed by the screenshots used throughout the article.

Sample hashes

Sample or objectSHA-256
Campaign ZIP 248,759 bytes7108FF29916D064216AA2ECE7FB395F1E3A73D12D19895BFFC0BD46806CBF85A
Staged IMG 641,024 bytes38EC1F5E23F65B10AE3027BEABFA0BF7F9FB686355A9E33C7E7E44E6A998E04C
Tax_Notice_23665.exe 120,984 bytes93DD8B7B393289F88493596FAA4AE70054D9EB4FE47F2DD334F0C6BB5262F2A8
nvdaHelperRemote.dll 455,527 bytes7295090C2CB63EBC43F932451971C41F9D015D2741E97AE3D9855F5AE87CFF94
Decoded carrier record 415,071 bytes0419AE7381CAA97172C40F5AEA601B8A22F1F58D27F3930509AF5808E043F65E
Protected package allocation 417,792 bytesE49581067CC2AA5ABD09C8DF42D6FBD87CB064A9363FE8B52D8369FD1C51FFE5
Reconstructed image A 397,312-byte PE32 mapper28B8EB812E0F0AB724475BD51E3DC1F618BCB08B05998C414D4193009BF8D598
Reconstructed image B PE32 launcher46B34789196733FAB62193F0AAEDB198B09F1362F9B10CA1DD70CF81D68B01AD
PLK1 compressed derivative 669,717 bytes502A7D2D72BEFA9114417936A1B3C2DD8EC84FCD4AE9EF9A09FFF3604FC05CCE
Reconstructed PackClientCore.dll 985,088 bytes4DE6EF8647FB4B599966A233740CB0514D1E71B8019A1A1792ED7E1E514EDF1C
Reconstructed Core .text 753,664 bytesF06FF7AB6D62B761344CAECBCC6857912F7543F43C0E5FF462D2174BADB0CA3F
Filtered positive-flow PCAPNG 762,668 bytesAB437D0EAE5E3C93764B89A3ECC5F6940D3CBEE0C2BE8D80D34CD7CB4CA38875
PID 5812 dump 42,481,455 bytesB67AA7F4176AF9793C0D2C53C12B757C95C213BF827108697ED5B60D2C1ED663
PID 3696 dump 38,687,630 bytesE635CC1F72112E10FEA9B9B9574FD7D2F7A5D101EDBF3C33B61FDD12071FA49E

Full provenance and methods

Source figures

The signed host calls the carrier initializer.

Figure 01 / static reconstruction

The signed host calls the carrier initializer.

At host RVA 0x1004, the signed Tax Notice executable calls the imported nvdaHelperRemote.dll!injection_initialize entry.

Source: Ghidra disassembly and decompilation of Tax_Notice_23665.exe.

Technical note ↗ · View in article ↗

The installed pair uses a signed host and a separate companion DLL.

Figure 02 / runtime observation

The installed pair uses a signed host and a separate companion DLL.

Explorer shows Tax_Notice_23665.exe beside nvdaHelperRemote.dll under C:\ProgramData\NVIDIA Corporation\NvSvc. A separate properties view lists an embedded NV Access Limited signature for the host. The signature belongs to the host; this view does not authenticate the companion DLL.

Source: Explorer directory listing and host Digital Signatures properties, captured separately.

Technical note ↗ · View in article ↗

Launcher B retains its PackClientLauncher build identity.

Figure 04 / static reconstruction

Launcher B retains its PackClientLauncher build identity.

The image summary identifies the imported PE and its PackClientLauncher PDB name; the recorded SHA-256 identifies the reconstructed image.

Source: Ghidra program information for recovered image B.

Technical note ↗ · View in article ↗

The worker opens an existing endpoint.

Figure 05 / static reconstruction

The worker opens an existing endpoint.

1. CreateFileW receives the supplied endpoint, read/write access and disposition 3 (OPEN_EXISTING). 2. The READY header uses magic 0x50435231 and type 1. The endpoint namespace and external peer are not recovered.

Source: Ghidra decompilation of the worker endpoint-open and READY path.

Technical note ↗ · View in article ↗

The recapture branch constructs a type-2 response.

Figure 08 / static reconstruction

The recapture branch constructs a type-2 response.

The literal type 2 and the send-helper call are visible in the recapture path. The surrounding dataflow establishes the field semantics and BGRX payload layout.

Source: Ghidra disassembly of the recapture response in image B.

Technical note ↗ · View in article ↗

Authentication gates decryption.

Figure 10 / static reconstruction

Authentication gates decryption.

A failed tag comparison exits the receive path before ciphertext reaches the AES-CBC helper.

Source: Ghidra decompilation of the authenticated receive path in image B.

Technical note ↗ · View in article ↗

A historical Triage Launcher flow reaches PLK1.

Figure 11 / runtime observation

A historical Triage Launcher flow reaches PLK1.

Wireshark displays PLH1, PLC1, PLA1 and PLK1 on the filtered historical flow. The selected PLK1 header declares wire version 2, LZ4, 669,717 transferred bytes, 985,088 original bytes and the expected Core plaintext SHA-256.

Source: Filtered PCAPNG derived from Triage 260715-wd77daas7l/behavioral1 and opened with the PackClient Wireshark dissector.

Technical note ↗ · View in article ↗

The plaintext must pass digest verification, cache save and cache reload.

Figure 13 / static reconstruction

The plaintext must pass digest verification, cache save and cache reload.

The transfer body checks the plaintext digest, requires Save to succeed, and immediately requires TryLoad to return a nonempty vector. The visible failure branches are SHA256 mismatch, disk_cache_save_failed and disk_cache_reload_failed.

Source: Ghidra decompilation of image B’s PLK1 acceptance and cache-return path.

Technical note ↗ · View in article ↗

Traffic recovery and memory identity agree.

Figure 14 / recovery verification

Traffic recovery and memory identity agree.

PLK1 supplies the complete PE hash; the mapped .text hash independently links that build to all 352 memory images.

Source: PowerShell verification output for the historical PLK1 transfers and retained Core memory mappings.

Technical note ↗ · View in article ↗

The recovered Core is a 32-bit x86 PE DLL.

Figure 15 / static reconstruction

The recovered Core is a 32-bit x86 PE DLL.

Ghidra identifies the reconstructed payload as little-endian 32-bit x86 and a Portable Executable, with the same SHA-256 recovered from PLK1 traffic.

Source: Ghidra import summary for the reconstructed PackClientCore.dll.

Technical note ↗ · View in article ↗

Core resolves and validates the modern plugin ABI.

Figure 16 / static reconstruction

Core resolves and validates the modern plugin ABI.

The recovered Core resolves PackPlugin_GetAbiVersion and PackPlugin_GetFeatureId before accepting feature-specific host bindings. A separate legacy path resolves Main.

Source: Ghidra decompilation of reconstructed PackClientCore.dll function 0x10016231.

Technical note ↗ · View in article ↗

Core serializes its built-in preview as PV10.

Figure 17 / static reconstruction

Core serializes its built-in preview as PV10.

The Core serializer emits the PV10 marker in the built-in screenshot-preview path. Packet reconstruction finds 15 matching type-18 JPEG frames; no bridge from the separate Launcher 1RCP endpoint is established.

Source: Ghidra disassembly and decompilation of reconstructed PackClientCore.dll RVA 0x236D0.

Technical note ↗ · View in article ↗

The active-session path retries a token-based launch.

Figure 18 / static reconstruction

The active-session path retries a token-based launch.

The call uses CreateProcessAsUserW with flags 0x09000400. The loop sleeps for 1,000 ms after each failure and stops after at most 0x1E attempts. This helper handles session handoff; the original elevation path remains unresolved.

Source: Ghidra decompilation of the active-session spawn loop in image B.

Technical note ↗ · View in article ↗

Private executable allocation in svchost.exe, PID 5812.

Figure 19 / runtime observation

Private executable allocation in svchost.exe, PID 5812.

VMMap shows a 408 KiB Execute/Read allocation at 0x002E0000. Corresponding dump analysis identifies its contents as the transformed A/B package.

Source: VMMap allocation views from the PID 5812 capture.

Technical note ↗ · View in article ↗

One parent creates two siblings.

Figure 21 / runtime observation

One parent creates two siblings.

Process Monitor records parent PID 2116 creating svchost PID 3696 and schtasks PID 4600; schtasks then creates conhost PID 8248. SUCCESS is the Process Create result, not the child's exit code.

Source: Process Monitor process-creation rows from the PID 3696 capture.

Technical note ↗ · View in article ↗

NvSvc combines an at-logon trigger with a ProgramData action.

Figure 22 / runtime observation

NvSvc combines an at-logon trigger with a ProgramData action.

Task Scheduler shows NvSvc's enabled at-logon trigger, ProgramData action and configured principal. Highest available privileges for this user do not establish SYSTEM execution.

Source: Task Scheduler action, trigger and principal settings for NvSvc.

Technical note ↗ · View in article ↗

Full-EXE execution persists the Tax Notice host.

Figure 23 / runtime observation

Full-EXE execution persists the Tax Notice host.

The process view records NvSvc task creation with the ProgramData Tax_Notice_23665.exe action, matching the intended signed-host/carrier chain.

Source: Triage 260908-zwr5naybjb behavioral1 process report.

Technical note ↗ · View in article ↗

Direct-DLL execution persists a copied rundll32 host.

Figure 24 / runtime observation

Direct-DLL execution persists a copied rundll32 host.

The direct rundll32 invocation causes NvSvc to target a copied rundll32.exe without the DLL argument. That action cannot replay the original entry point and is treated as a sandbox-context artifact, not a second variant.

Source: Triage 260908-zwr5naybjb behavioral2 process report.

Technical note ↗ · View in article ↗

The surviving surrogate has a bare command line.

Figure 25 / runtime observation

The surviving surrogate has a bare command line.

1. Bare SysWOW64 svchost command line. 2. Parent 2116 has exited. 3. The process is x86. The Downloads\PackClient current directory supplies additional context. These properties support an anomalous surrogate, without identifying an injection subtype.

Source: Process Explorer properties for PID 3696.

Technical note ↗ · View in article ↗

Connection attempts from svchost.exe, PID 3696.

Figure 26 / runtime observation

Connection attempts from svchost.exe, PID 3696.

Process Explorer shows two SYN_SENT attempts to 154.36.188.201:443, from local ports 54581 and 50275.

Source: Process Explorer TCP/IP views associated with PID 3696.

Technical note ↗ · View in article ↗

Figure

Enlarged figure

Open figure at full resolution ↗