Skip to navigation

Threat reportMalwareTL-2026-4715

NetamLoader: Unknown APT Targets Government-Customized Windows 10 OS in Asia via Patch My PC-Themed XAML/.NET Loader

highACTIVE

Kaspersky Securelist reports an unattributed APT using a multi-stage .NET/XAML loader framework (NetamLoader) that masquerades as Patch My PC components and abuses AppDomainManager injection, BinaryFormatter TypeConfuseDelegate deserialization and XAML execution, with AMSI bypass and an AES-128-CBC/HMAC-SHA256 C2 channel. One confirmed victim in Asia; the framework targets a customized government-only Windows 10 build.

Key facts for NetamLoader XAML loader

IdentifiersTL-2026-4715
Also known asNetamLoader
SeverityHIGH
First disclosed
Exploitation statusExploited in the wild
Affected productsUnknown (government customized build) Customized government-only Windows 10 OS (CmitUpdateAgent update mechanism); Patch My PC Patch My PC components (PatchMyPC-ScriptRunner.exe) abused as legitimate-looking host
Weaknesses (CWE)CWE-502
MalwareNetamLoader
MITRE ATT&CK techniquesT1012 Query Registry, T1016 System Network Configuration Discovery, T1027.013 Encrypted/Encoded File, T1036.005 Match Legitimate Resource Name or Location, T1070.004 File Deletion, T1071.001 Web Protocols, T1082 System Information Discovery, T1112 Modify Registry, T1132.001 Standard Encoding, T1134.001 Token Impersonation/Theft, T1140 Deobfuscate/Decode Files or Information, T1480.001 Environmental Keying and 6 more in the attack flow
MotivationUNKNOWN
Target sectorsgovernment administration
Target regionsAsia
Detection rules9 (1 shown free)
Sources5 cited sources

Detection coverage for NetamLoader XAML loader

As of 2026-10-31, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-4715 across Splunk SPL, Microsoft KQL and Sigma, covering 31 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.

Free detection: NetamLoader - PatchMyPC-ScriptRunner Executed From Windows Update Staging Directory (-updatepackage)

Detects the NetamLoader execution trigger: PatchMyPC-ScriptRunner.exe run with -updatepackage -applicationid=<GUID> from C:\Windows\SoftwareDistribution\Download\Install\, where a malicious PatchMyPC-ScriptRunner.exe.config performs AppDomainManager injection and fabric.config/Resources.resx drive BinaryFormatter TypeConfuseDelegate deserialization. XAML-1 derives its AES key from this exact command line (environmental keying), so the command line is stable and high-fidelity. Legitimate Patch My PC runs from its own install path, not from the Windows Update download cache.

  • Languages: Splunk SPL, Microsoft KQL, Sigma
  • ATT&CK: T1574.014, T1036.005, T1480.001
  • Data sources: sysmon, windows_security, microsoft_defender_for_endpoint
  • Severity: high
  • Confidence: high

Splunk SPL

index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image="*\\PatchMyPC-ScriptRunner.exe" Image="*\\SoftwareDistribution\\Download\\*" CommandLine="*-updatepackage*" CommandLine="*-applicationid=*"
```NetamLoader TL-2026-4715 stage 1: ScriptRunner launched from the update staging cache; the command line is the XAML-1 decryption key```
| eval cmdline_lower=lower(CommandLine), launched_from_update_staging="true"
| table _time host User ParentImage Image CommandLine cmdline_lower launched_from_update_staging ProcessGuid

Microsoft KQL

DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "PatchMyPC-ScriptRunner.exe"
| where FolderPath contains @"\SoftwareDistribution\Download"
| where ProcessCommandLine contains "-updatepackage" and ProcessCommandLine contains "-applicationid="
| project Timestamp, DeviceName, AccountName, FolderPath, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA1, MD5, ReportId

Sigma

title: NetamLoader PatchMyPC-ScriptRunner Launched From Windows Update Staging Directory
id: 3f6a1c52-8d47-4b19-a2e0-5c7b9d104e11
status: experimental
description: Detects PatchMyPC-ScriptRunner.exe started with -updatepackage and -applicationid from the SoftwareDistribution Download staging directory, the execution trigger of the NetamLoader AppDomainManager injection chain.
references:
    - https://securelist.com/netamloader/121676/
    - https://attack.mitre.org/techniques/T1574/014/
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-10-29
tags:
    - attack.persistence
    - attack.t1574.014
    - attack.defense-evasion
    - attack.t1036.005
    - attack.t1480.001
logsource:
    category: process_creation
    product: windows
detection:
    selection_img:
        Image|endswith: '\PatchMyPC-ScriptRunner.exe'
    selection_path:
        Image|contains: '\SoftwareDistribution\Download'
    selection_cli:
        CommandLine|contains|all:
            - '-updatepackage'
            - '-applicationid='
    condition: all of selection_*
falsepositives:
    - Legitimate Patch My PC deployments that stage ScriptRunner inside the Windows Update download cache (uncommon)
level: high

Known false positives:

  • Patch My PC package deployments that legitimately stage ScriptRunner under SoftwareDistribution\Download
  • Internal red-team or software-packaging tests replicating the NetamLoader trigger

Tuning notes: Requires Sysmon EventCode 1 (or Security 4688 with command-line auditing) indexed in index=sysmon; adjust index/sourcetype to your environment. Allow-list known Patch My PC package GUIDs after validating them against the vendor catalog. The Image path condition is the main discriminator - keep it even if the command-line match is relaxed.

8 more detection rules (Splunk SPL, Microsoft KQL, Sigma) · unlock with TL Creds. Sign up free to unlock the detection rules or query them with the Threadlinqs MCP server (Purple)
  • NetamLoader - Malicious Config/Resx Files Staged In SoftwareDistribution\Download · unlock with TL Creds
  • NetamLoader - Self-Cleanup Deletion of ScriptRunner Prefetch, CLR UsageLogs and Staged Config Files · unlock with TL Creds
  • NetamLoader - Network Contact With [indicator] C2 or /model_v4/ Polling URL · unlock with TL Creds
  • NetamLoader - AppFabric/HostIntegration and XAML Assemblies Loaded By Staged ScriptRunner · unlock with TL Creds
  • NetamLoader - [indicator] Loading CLR and XAML Assemblies (DllSurrogate Payload Host) · unlock with TL Creds
  • NetamLoader - HTTPS Polling of /model_v4/<instance_id> With b= and c= POST Parameters · unlock with TL Creds
  • NetamLoader - DllSurrogate AppID Registration and CLR ETW Disable Variable · unlock with TL Creds
  • NetamLoader - [indicator] Outbound HTTPS Beaconing to Public Hosts / [indicator] · unlock with TL Creds

Indicators of compromise for NetamLoader XAML loader

As of 2026-10-31, Threadlinqs Intelligence tracks 31 indicators of compromise for TL-2026-4715.

Sample indicators (3 of 31)

  • IP address: 104.18.14[.]219
  • Domain: openaigpt4v[.]com
  • File hash: e4537a1762fcafd2fd96bfc825bad34f9db9a24d

Defanged, TLP:CLEAR. Full set of 31 indicators: unlock with TL Creds.

31 indicators of compromise · unlock with TL Creds. Compare plans

How NetamLoader XAML loader works

In H1 2026 Kaspersky detected a highly sophisticated infection chain on a customized, government-only Windows 10 build used in Asia (the host logs contain the keyword CmitUpdateAgent). A CAB archive (SHA1 e4537a1762fcafd2fd96bfc825bad34f9db9a24d) was found in C:\Windows\SoftwareDistribution\Download\ and unpacked into an Install\ folder containing legitimate Patch My PC components plus three malicious files: PatchMyPC-ScriptRunner.exe.config, fabric.config and Resources.resx. Kaspersky did not observe how the CAB was delivered to the victim; the researchers assess it as a supply-chain-style attack. Execution is triggered by running PatchMyPC-ScriptRunner.exe -updatepackage -applicationid=<GUID>.

The .config file uses AppDomainManager injection (appDomainManagerType Microsoft.ApplicationServer.Caching.DataCacheFactoryConfiguration from assembly Microsoft.HostIntegration.Connectors) so that the Windows Server AppFabric cache client loads fabric.config. That file points to System.Resources.ResXResourceSet, which parses Resources.resx containing a Base64 BinaryFormatter object. Deserialization uses a TypeConfuseDelegate gadget to call XamlReader.Parse(), loading XAML-1. XAML-1 derives an AES key from the SHA-256 of the lower-cased host process command line (environmental keying), decrypts XAML-2 and calls Environment.Exit(0) on failure. XAML-2 holds two compressed XAML files: XAML-2-1 patches AMSI (it overwrites Console.Clear() with the bytes 41 C7 00 01 00 00 00 33 C0 C3 and redirects the CAmsiAntimalware::Scan virtual-table entry to it so every scan returns AMSI_RESULT_CLEAN), and XAML-2-2 reflectively loads the first-stage .NET loader and passes it a JSON configuration.

The .NET 1 loader removes evidence (deletes the three malicious files, the CLR UsageLogs entry and the PatchMyPC-ScriptRunner Prefetch file, and filters lines containing GetExtendedUpdateInfoHandler from CmitUpdateAgent logs), requires administrator rights, builds an instance ID and a system ID from SusClientId, disables ETW for the CLR via COMPlus_ETWEnabled=0 set through WScript.Shell, and abuses a remote COM object (CLSID ab8902b4-09ca-4bb6-b78d-a8f59079a8d5) with a second deserialization/TypeConfuseDelegate chain to load XAML-3 into dllhost.exe, separating the payload from the original process tree. The .NET 2 plugin runs in dllhost.exe (a DllSurrogate appid {ff259bcd-2f0a-44de-b34a-0092fec1d8a2} is registered, and CoLockObjectExternal keeps the process alive), waits 20-40 minutes before first contact, runs a watchdog of roughly 28 hours, and long-polls https://openaigpt4v.com/model_v4/<instance_id> with POSTed ?b=<encrypted>&c=<instance_id> parameters. Proxy settings are resolved via WinHTTP default proxy, impersonation of the explorer.exe token, or DefaultWebProxy. Traffic uses AES-128-CBC with HMAC-SHA256 (encrypt-then-MAC, derived keys per seed). Downloaded XAML tasking is executed inside a short-lived isolated AppDomain via another TypeConfuseDelegate (TimeZoneInfo.ClearCachedData replaced by XamlReader.Parse through AppDomain.DoCallBack) and the AppDomain is then unloaded.

Kaspersky stated that after analysing TTPs, code similarities and infrastructure it could not link the activity to any known APT group. Kaspersky detection names are HEUR:Trojan.MSIL.NetamLoader.gen, Trojan.MSIL.Zapchast.* and Trojan.Script.Agent.*. Severity is analyst-assigned based on government targeting and the sophistication of the evasion chain; only one victim is confirmed.

MITRE ATT&CK techniques by tactic:

Discovery

T1012 Query Registry; T1016 System Network Configuration Discovery; T1082 System Information Discovery

Defense Evasion

T1027.013 Encrypted/Encoded File; T1036.005 Match Legitimate Resource Name or Location; T1070.004 File Deletion; T1140 Deobfuscate/Decode Files or Information; T1480.001 Environmental Keying; T1497.003 Time Based Checks; T1620 Reflective Code Loading

Command and Control

T1071.001 Web Protocols; T1132.001 Standard Encoding; T1573.001 Symmetric Cryptography

defense-impairment

T1112 Modify Registry; T1685 Disable or Modify Tools

Privilege Escalation

T1134.001 Token Impersonation/Theft

Execution

T1559.001 Component Object Model

stealth

T1574.014 AppDomainManager

Remediation for NetamLoader XAML loader

Immediate actions

  • Block openaigpt4v.com and hunt for outbound HTTPS to /model_v4/ with b= and c= query parameters
  • Hunt for PatchMyPC-ScriptRunner.exe launched from C:\Windows\SoftwareDistribution\Download\Install\ with -updatepackage, or with a sibling .exe.config, fabric.config or Resources.resx
  • Hunt for dllhost.exe making external HTTPS connections or loading System.Xaml/PresentationFramework, and for a DllSurrogate appid {ff259bcd-2f0a-44de-b34a-0092fec1d8a2}
  • Scan for the published file hashes and Kaspersky detection names HEUR:Trojan.MSIL.NetamLoader.gen, Trojan.MSIL.Zapchast.* and Trojan.Script.Agent.*

Workarounds

  • Enforce allow-listing so third-party patch tools cannot run from update staging directories
  • Block egress from dllhost.exe to the internet except where required

Longer-term hardening

  • Alert on creation of <exe>.config files containing appDomainManagerType/appDomainManagerAssembly outside installer paths
  • Restrict and audit code delivered into SoftwareDistribution\Download and verify update package provenance and signatures on customized OS builds
  • Monitor for AMSI tampering and COMPlus_ETWEnabled changes; keep ETW/CLR telemetry forwarded off-host
  • Avoid BinaryFormatter-based components and enforce application allow-listing for third-party patch tooling

Affected and fixed versions

  • Unknown (government customized build) — Customized government-only Windows 10 OS (CmitUpdateAgent update mechanism)
    Vulnerable versions: Customized Windows 10 build; BuildLab string 17763.rs5_release.180914-1434 shown in the C2 beacon example
  • Patch My PC — Patch My PC components (PatchMyPC-ScriptRunner.exe) abused as legitimate-looking host

Timeline of NetamLoader XAML loader

Last updated · revalidated 1× · latest source

  • C2 domain locked-ioc-25 is dated 2023-09-27 in the Securelist report (reported as the domain's first-seen/registration date).
  • Approximate period start: Securelist states the first sample was detected via KSN in the first half of 2026; no exact date is given.
  • Approximate period end of the H1 2026 window in which the locked-ioc-29 CAB infection chain was detected on a customized government Windows 10 host in Asia; exact date not published.
  • Kaspersky states that, after analysing TTPs, code similarities and infrastructure, it could not link locked-ioc-29 to any known APT group; the CAB delivery vector to the victim was not observed.
  • Securelist documents the implant's C2 timing: first contact after 20-40 minutes (1200-2400 s), 5-6 minute polling after a successful C2 response, 22-28 hour polling intervals when the C2 is unresponsive, and a process watchdog of about 28 hours (100801 s). Dated to the report; the timing is a behavioral property, not an observed event date.
  • Kaspersky names detections HEUR:Trojan.MSIL.locked-ioc-29.gen, Trojan.MSIL.Zapchast.* and Trojan.Script.Agent.* and publishes IOCs; BeaconBeagle shows no C2 match for locked-ioc-25 or locked-ioc-27.
  • Kaspersky Securelist publishes the locked-ioc-29 analysis, assessing it as a likely supply-chain attack and stating it could not link it to any known APT.

Update history

Sources cited for NetamLoader XAML loader

Drafted by the Threadlinqs research pipeline from 5 sources; published ; last updated .

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level

Latest Threats