PackClient detection and hunting guide
Research cut-off: 2026-09-05 (UTC)
Detection strategy
Prefer behavior joins over single strings or filenames. svchost.exe and nvdaHelperRemote.dll are legitimate names in normal contexts; the useful signal is their path, parentage, command line, signer/origin, and nearby persistence activity.
The repository includes the following detection rules under detections/:
- Sigma rules for the observed
NvSvctask, suspicious bare 32-bit service host, screenshot-worker mode, and active-session mode; - a YARA rule for the recovered launcher's distinctive marker constellation;
- Suricata rules for candidate PLH1/PLC1/PLA1 frame prefixes and version bytes.
The included rules are experimental and should be validated against local telemetry and legitimate NVDA deployments.
Correlated observations
| Signal | Evidence relationship |
|---|---|
| Staged signed host and colocated helper | Static sideload evidence; observed in the PID 5812 session |
Bare 32-bit svchost.exe |
Descendant in the PID 5812 process tree |
NvSvc task creation |
In the PID 5812 session, the process tree places task creation beneath that surrogate. In the PID 3696 session, elevated host PID 2116 creates both PID 3696 and schtasks PID 4600; the latter two are siblings. Task XML confirms the configured action. |
/scr_cap_worker and session controls |
Recovered launcher functionality; the worker was exercised separately and was not demonstrated as part of the preserved runtime chain |
Treat individual signals as pivots and correlate them with process ancestry, task creation, file activity, and runtime timing. Scope joins to the VM, time interval, and process creation identity (ProcessGuid where available), not a bare PID. The PID 3696 session shows an earlier unrelated PID 8248 before that number is reused for the later console child. Use lifecycle events or a live process view to confirm process lifetime. See runtime validation.
Host pivots
1. NVDA helper sideload
Hunt for a signed NV Access/NVDA executable loading nvdaHelperRemote.dll from:
- user-writable directories;
- disk-image extraction/staging directories;
ProgramDatapaths unrelated to an approved NVDA installation;- the process current directory when it is not the installed NVDA directory.
Useful telemetry:
- process image path, signer, original filename, hash, parent, and current directory;
- image-load path/hash/signature status;
- adjacent file creation for the host and DLL;
- whether the DLL has the expected organization/signature for the deployed NVDA version.
False-positive control: nvdaHelperRemote.dll is a legitimate NVDA component name. Never alert on the filename alone.
2. NvSvc scheduled task
The observed task was named \\NvSvc, triggered at logon, and launched:
C:\ProgramData\NVIDIA Corporation\NvSvc\Tax_Notice_23665.exe
High-signal conditions include:
- task name exactly
NvSvccombined with a non-NVIDIA-signed target; - a target under the exact
ProgramDatasubdirectory above; - creation by a recently staged executable or its descendant;
/SC ONLOGONplus/RL HIGHESTin the creating command line;- creation within seconds of the host/carrier pair.
Telemetry sources include process creation, Task Scheduler Operational events, Security 4698, and endpoint task inventories. Normalize XML before comparing quoted action paths.
3. Bare 32-bit svchost.exe surrogate
Prioritize a process when several of these hold:
- image is
C:\Windows\SysWOW64\svchost.exe; - command line is only the image path, without ordinary
-k,-s, or COM-server arguments; - parent is not
services.exe/service-control infrastructure; - user is an interactive user rather than the expected service identity;
- current directory points to a staging, download, mounted-image, or sample directory;
- start time aligns with the suspicious host/carrier or task creation;
- thread start addresses or executable mappings fall outside ordinary file-backed images.
Process metadata alone does not identify the injection subtype; memory mappings and thread starts provide the stronger discriminator.
4. Launcher special arguments
The recovered launcher recognizes exact controls including:
/scr_cap_worker <endpoint> [monitor-index]
-acsi
--active-session
/scr_cap_worker is particularly distinctive even after launcher renaming. -acsi and --active-session are less distinctive and should be paired with launcher image or original-filename identity. The Sigma rules keep those behaviors separate so ATT&CK metadata follows the matched execution mode.
5. Cache and filesystem leads
Recovered cache strings describe a current-user protected layout containing:
pluginsdata\x86\blobs\PackClientCore.primary.dll.pblob
pluginsdata\x86\meta\PackClientCore.primary.dll.json
and metadata markers:
PackMonitorClient.PluginStore
PackMonitorClient.PluginStore.v1
dpapi_current_user_v1
The absolute base path was not resolved. Search user-profile and application-data locations, but treat filename/string hits as supporting evidence. The reconstructed active call path does not select the secondary slot.
Memory and local IPC pivots
For a suspicious surrogate, useful collection targets include:
- mapped file list and signature status;
- virtual memory type/protection/size;
- thread start addresses and owning regions;
- process and thread token/session data;
- command line, parent, current directory, environment metadata, and handles;
- local named-pipe handles and peer PIDs where available.
A plausible 1RCP header is 20 bytes:
| Offset | Field | Check |
|---|---|---|
0x00 |
magic | LE32 0x50435231 / ASCII 1RCP |
0x04 |
type | 1, 2, 3, or 5 in this worker |
0x08 |
width | positive for types 1 and 2; impose an analyst size bound |
0x0C |
height | positive for types 1 and 2; impose an analyst size bound |
0x10 |
payload length | zero for READY; exact width * height * 4 for frame |
For requests of type 3 or 5, B ignores DWORDs 2–4. A raw 1RCP string hit is weak; require the full 20-byte structure and field consistency.
Network detection
The initial handshake is plaintext inside the verified outer frame. Exact stream prefixes are:
| Direction | Object | Exact prefix |
|---|---|---|
| client -> server | PLH1 | 24 00 40 5A 15 00 00 00 50 4C 48 31 |
| server -> client | PLC1 | 1C 00 40 5A 15 00 00 00 50 4C 43 31 |
| client -> server | PLA1 | 2C 00 40 5A 15 00 00 00 50 4C 41 31 |
The lengths encode 4-byte type + object size. The Suricata rules additionally match little-endian version 1 and inspect reassembled TCP data at any buffer offset. In particular PLA1 follows PLH1 in the client stream; anchoring it with startswith can miss a coalesced buffer. These signatures match protocol prefixes rather than fully validating framing or HMAC state; TCP reassembly still matters.
The Proofpoint IOC table lists 154.36.188[.]201 as post-infection infrastructure for July 15, without a port. The preserved process dump separately records effective configuration and a concrete attempt to that address on TCP/443, followed by WSA=10060 (timeout).
Hash and filename IOCs
| Artifact | SHA-256 | Confidence/source |
|---|---|---|
| Campaign ZIP | 7108FF29916D064216AA2ECE7FB395F1E3A73D12D19895BFFC0BD46806CBF85A |
Exact public/research lineage |
| Staged IMG | 38EC1F5E23F65B10AE3027BEABFA0BF7F9FB686355A9E33C7E7E44E6A998E04C |
Exact artifact identity |
Tax_Notice_23665.exe |
93DD8B7B393289F88493596FAA4AE70054D9EB4FE47F2DD334F0C6BB5262F2A8 |
Exact host identity |
nvdaHelperRemote.dll |
7295090C2CB63EBC43F932451971C41F9D015D2741E97AE3D9855F5AE87CFF94 |
Exact carrier identity |
| Embedded launcher B | 46B34789196733FAB62193F0AAEDB198B09F1362F9B10CA1DD70CF81D68B01AD |
Static reconstruction; derived bytes not published |
Filename leads:
Tax_Notice_23665.exenvdaHelperRemote.dllPackClientLauncher.exePackClientConsole.exePackClientCore.primary.dll.pblobPackClientCore.primary.dll.json
Names are mutable and should not be the only detection condition.
ATT&CK mapping
| Technique | Mapping | Confidence |
|---|---|---|
| T1574.001 — DLL | Signed host resolves malicious colocated helper DLL | Confirmed |
| T1053.005 — Scheduled Task/Job | NvSvc at-logon persistence |
Confirmed in runtime evidence |
| T1113 — Screen Capture | GDI worker and BGRX response contract | Confirmed implementation; live frame not completed |
| T1134.002 — Create Process with Token | Duplicated/retargeted token passed to CreateProcessAsUserW |
Confirmed implementation |
| T1055 — Process Injection | Malware-spawned surrogate contains unregistered A/B mappings and a thread starting at mapped A entry | Strongly supported at parent-technique level; subtype unresolved |
Triage order
- Preserve process/task/image-load metadata and hashes.
- Verify the target/signer/path of
\\NvSvc, neighboring tasks, Startup Apps entries, Run/RunOnce values, and user/common Startup folders. The runtime record shows an enabled Startup Apps entry but does not identify its backing registration. - Inspect bare/unusual
svchost.exeinstances for parent, user, current directory, modules, private executable memory, thread starts, and named mutants matchingPackClientLauncher.Session.*. - Search for the exact host/carrier pair and cache markers across the affected user profile.
- Decode already-acquired captures with the passive tools.
- Scope adjacent hosts using behavior joins first, historical hash/IOC matches second.
Rule limitations
- Suricata rules assume the listed prefix is contiguous in the normalized TCP stream; sensor configuration matters.
- Sigma field names and command-line normalization vary by backend.
- YARA marker rules identify a code/data constellation, not a campaign actor by themselves.
- Sigma regex/backend semantics must be checked on the destination platform. The bare-svchost rule expects an absolute drive path; aliases, environment-variable paths, and missing parent telemetry are coverage limits.
- The screenshot-worker rule accepts its distinctive token after renaming. Active-session tokens additionally require image/original-filename identity. Similarly named unrelated programs can still match.
- Tests use synthetic positive/negative examples, not the original malware or a representative benign deployment corpus. Production false-positive and detection rates have not been measured.
- Exact hashes cover this lineage only.