A China-nexus espionage cluster has spent the past year breaking into government and policy organisations across Asia with a backdoor that never talks to a conventional command server. Cisco Talos, in research published on 30 September 2026, describes UAT-11587 and its previously undocumented Rust implant Antino, which receives tasking from Outlook mailbox messages and sends heartbeats and stolen files to OneDrive, all through Microsoft Graph. Talos counts approximately 350 compromised endpoints across eight countries and at least 16 affected or targeted institutional environments. Because Antino's traffic terminates at graph.microsoft.com and login.microsoftonline.com, network allow-lists will not stop it; detection has to shift to the endpoint processes making those calls and to the delivery chain that installs them.

Who is UAT-11587 and who was targeted?

Talos first observed UAT-11587 activity in September 2025 and assesses with high confidence that the actor is China-nexus. It bases that on the totality of evidence rather than a single indicator, including decoy documents carrying a zh-CN language tag, a Simplified Chinese author value and a +08:00 timestamp, Antino build paths referencing the China-focused Rust mirror rsproxy.cn, and lure themes consistent with Chinese intelligence interests. Talos also found a JavaScript downloader referencing a CloudFront distribution previously reported in UNC6384 delivery activity, but rates that overlap as low confidence. It notes overlaps with Antino-related espionage that Symantec attributed to a group it calls Jewelbug, but tracks UAT-11587 separately because it could not verify a link to Jewelbug's financially motivated operations.

Talos identified at least 10 confirmed and five probable affected institutional environments, plus one intended target, and assesses with moderate-to-high confidence that the campaign targeted organisations in Taiwan, India, the Philippines, Cambodia, Pakistan, Thailand, Myanmar and Syria. Affected or targeted sectors were:

  • Defence, military and national security
  • Executive government and central public administration
  • Foreign affairs and diplomatic services
  • Justice, law enforcement, border and interior security
  • Legislative and parliamentary institutions
  • Government IT and shared e-government services
  • Think tanks, universities and research institutions
  • Civil society, human rights and public policy organisations

Talos assesses with moderate confidence that the operation is intelligence gathering. The largest single wave came on 8 and 9 June 2026, when around 57 newly observed endpoints associated with India appeared.

Spear-phishing tradecraft: SPF passes, DMARC fails, mail still lands

UAT-11587 sent mail through Migadu using the attacker-controlled osc-cdn[.]com domain as the RFC 5321 envelope sender while the visible RFC 5322 From header showed the impersonated organisation. SPF passed for the envelope domain; DMARC detected the misalignment and failed, but the displayed domain had a non-enforcing p=none policy, so the receiving provider delivered the message anyway.

The emails rebuilt Gmail's attachment preview card from four inline Base64 PNGs wrapped in a link to a Cloudflare Pages URL of the form //my-<project>.pages.dev/File_download?m=<target-identifier>. Talos points out that the protocol-relative // prefix may be missed by tools that only extract fully qualified URLs, and the ?m= value permits per-recipient tracking. Lures ranged from a Taiwan "Information Warfare" workshop and a reproduced Taiwan Ministry of Finance ruling on legislators' expenses to a "CSIS Indo-Pacific Forecast 2026" event agenda and news-style geopolitical headlines.

The five-stage infection chain

  1. HTA / WSF stager. mshta.exe runs an HTA from Cloudflare Pages that hides its window, beacons to the fixed tracking host oisadjfoinsiduhfnoisdnfosdnoifnsoid[.]pages[.]dev with the lure title and ?track, and imports the next stage from Cloudflare R2 or d2nq35tel3ucuo[.]cloudfront[.]net. WSF variants do the same through Windows Script Host.
  2. JScript downloader and decryptor. Fetches an encrypted JavaScript orchestrator and two encrypted .NET serialized gadget resources, applies custom Base64 decoding and RC4 decryption with an embedded key, and runs the orchestrator in memory.
  3. .NET BinaryFormatter deserialization. The first resource appears designed to disable the .NET check that blocks ActivitySurrogateSelector gadget chains; the second uses the System.Windows.Forms.AxHost+State gadget with an ActivitySurrogateSelector chain to load TestAssembly.dll directly into mshta.exe.
  4. TestAssembly.dll downloader. Downloads a decoy document and a three-file sideloading bundle with randomised extensions such as .luy, .pzs and .syk, opens the decoy and launches the bundle. All recovered builds share the assembly GUID b2b3adb0-1669-4b94-86cb-6dd682ddbea3.
  5. Signed-host sideloading. The Microsoft-signed Windows ADK binary GatherOsState.exe loads slc.dll from its own directory and calls its SLOpen export, starting Antino.

Talos also found standalone Antino executables served as fake installers from microsoft-flash[.]com and wps-cn[.]com.

Inside Antino: Microsoft 365 as a dead drop

Antino is a Rust-compiled Windows backdoor seen in 32-bit and 64-bit builds and in two generations. Gen1 builds (October 2025) encode host details into the session ID; Gen2 builds (December 2025 to January 2026) carry an AntinoApp manifest and use a random UUID. Build paths such as D:\a\antino\antino\... follow the GitHub Actions Windows runner layout, suggesting compilation on GitHub-hosted runners.

Gen2 authenticates to Microsoft Graph with the OAuth 2.0 client-credentials flow, letting a registered Entra ID application access the operator's Outlook mailbox and OneDrive without an interactive sign-in. Note that these are the threat actor's Microsoft 365 resources, not the victim's tenant.

ChannelArtefactPurpose
OneDrive/antino/heartbeats/{id}.jsonRegistration and check-in with host telemetry, resent every minute
OneDrive/antino_downloads/{file}Data exfiltrated from victims
OneDrive/antino_uploads/{file}Tools staged for delivery to victims
OutlookSubject command_req_[session_id]Operator tasking, polled every 10 seconds
OutlookSubject command_res_[session_id]Implant results

Supported commands include cmd, powershell, system_info, execute_program, list_files, upload_file, download_file, load_shellcode, add_to_run and exit. With use_sleep_mask enabled, load_shellcode hooks Sleep and VirtualAlloc and registers a vectored exception handler so the injected payload is encrypted and non-executable while sleeping. execute_program and add_to_run abuse the Windows Scripted Diagnostics framework: Antino instantiates CLSID {1F3D8AA5-9EBF-4EE4-85C2-EA40379AEDE8} with the Program Compatibility Wizard package, writes its own PowerShell into the temporary C:\Windows\Temp\SDIAG_<GUID> directory, and lets sdiagnhost.exe -Embedding execute it, for example to create an HKCU Run value. The configuration lives in a .cfg PE section XORed with the alternating key 0xAB 0xCD; persistent copies are staged under %LOCALAPPDATA%\Windows GatherOSStateKit\.

Indicators of compromise (selected)

Talos published 63 SHA-256 hashes and more than 80 network indicators (URLs, domains and an IP address). The selection below is copied from the Talos report; use the Talos IOC repository for the full list.

IndicatorTalos description
1fadc90b61ce536abda78eb387a7f3d745f00c16775d3f762845ccc0fde567daAntino Gen 1 slc.dll backdoor
40e7e77aff603f4c2ef17b3bc8ea836e714d0734a1e5b946e52f95536ec5c91dConfigured Antino Gen 1 standalone backdoor
09ef7c736bccfafefc44d9910d499173b88063b73b221fc0dc9e9105107e5cffAntino Gen 2 slc.dll backdoor
e2eb7703047b37b28dc34e6990205d758a2454b39bc655b460606745fadcb530Antino Gen 2 slc.dll backdoor
0c39264337a1186b2e765e24073399cbdcba118306614eb411e315887af578bdAntino Gen 2 standalone fake-installer backdoor
5c5c060b272cd4a5c3767edc0e9478bd35b7e1756e183d0446a5491bd65519cbConfigured Antino standalone backdoor
d753a615aedf8e58ffc75b2b7ebd320c0cbe6bcb5cbb885db749a2a85c55d3bfAntino-chain TestAssembly.dll downloader
e809da86bd81463347fa7f922d3e088755a94a331889d32acb55aa8f57778a34Malicious HTA stager (CSIS Indo-Pacific lure)
103[.]27[.]110[.]220Historical serving IP for the Antino payload hosted on wps-cn[.]com
osc-cdn[.]comActor-used spear-phishing sender domain
oisadjfoinsiduhfnoisdnfosdnoifnsoid[.]pages[.]devCloudflare Pages execution-tracking domain
d2nq35tel3ucuo[.]cloudfront[.]netAntino-chain CloudFront staging domain
pub-abfa7742e315485a98a5fafd6dbfb68e[.]r2[.]devAntino-chain Cloudflare R2 staging domain
pub-0173d1566dcd4fd49fa25f11f14bfe4c[.]r2[.]devAntino-chain Cloudflare R2 staging domain
microsoft-flash[.]com, wps-cn[.]comStandalone Antino fake-installer delivery domains

Talos lists ten Cloudflare Pages delivery hosts of the form my-xxxxxxxx[.]pages[.]dev, including my-662ylt3w[.]pages[.]dev and my-3lyt6wcp[.]pages[.]dev. Detection content: ClamAV signatures in the Win.Trojan.UAT-11587-*, Html.Trojan.UAT-11587-* and Txt.Trojan.UAT-11587-* families, and Snort 2/3 SIDs 1:66880, 1:66881 and 1:66882.

Defensive playbook

  1. Enforce DMARC. Move your own domains from p=none to quarantine or reject; UAT-11587's spoofing worked precisely because the impersonated domain did not enforce. Inbound, treat DMARC failures from high-trust partner domains as suspicious regardless of their policy.
  2. Constrain script hosts. Block or alert on mshta.exe and wscript.exe fetching content from pages.dev, r2.dev and cloudfront.net; where business allows, remove the .hta and .wsf file associations.
  3. Watch signed-binary sideloading. GatherOsState.exe outside a Windows ADK install path, especially loading slc.dll from a user-writable directory, is a high-fidelity signal.
  4. Profile Graph API callers. Antino reaches graph.microsoft.com and login.microsoftonline.com from a non-Office process. Baseline which binaries legitimately call those endpoints and alert on the rest; consider tenant restrictions at your proxy to limit access to foreign Microsoft 365 tenants, and test whether app-only token requests are covered in your environment.
  5. Hunt Scripted Diagnostics abuse. Registry Run-key writes or PowerShell launched by sdiagnhost.exe outside a user-initiated troubleshooter warrant review.
  6. Deploy the vendor content (ClamAV, Snort SIDs) and sweep the full IOC list across EDR, proxy and DNS logs back to September 2025.

Microsoft Defender XDR hunting starting points

// 1. Script hosts pulling stages from the cloud services UAT-11587 used
DeviceNetworkEvents
| where Timestamp > ago(90d)
| where InitiatingProcessFileName in~ ("mshta.exe","wscript.exe")
| where RemoteUrl has_any ("pages.dev","r2.dev","cloudfront.net")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl

// 2. GatherOsState.exe loading slc.dll outside System32
DeviceImageLoadEvents
| where Timestamp > ago(90d)
| where InitiatingProcessFileName =~ "GatherOsState.exe" and FileName =~ "slc.dll"
| where FolderPath !startswith @"C:\Windows\"
| project Timestamp, DeviceName, InitiatingProcessFolderPath, FolderPath, SHA256

// 3. Non-browser, non-Office processes calling Microsoft Graph (tune the exclusions)
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl has "graph.microsoft.com"
| where InitiatingProcessFileName in~ ("GatherOsState.exe","mshta.exe","rundll32.exe")
    or InitiatingProcessFolderPath has @"\Windows GatherOSStateKit\"
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath, RemoteUrl

// 4. Run-key persistence written via the Scripted Diagnostics host
DeviceRegistryEvents
| where Timestamp > ago(90d)
| where InitiatingProcessFileName =~ "sdiagnhost.exe" or InitiatingProcessParentFileName =~ "sdiagnhost.exe"
| where RegistryKey has @"\CurrentVersion\Run"
| project Timestamp, DeviceName, RegistryKey, RegistryValueName, RegistryValueData

YARA starting point from published build artefacts

rule UAT11587_Antino_Chain_Strings
{
  meta:
    description = "Starting point: strings published by Cisco Talos for Antino and TestAssembly.dll"
  strings:
    $guid = "b2b3adb0-1669-4b94-86cb-6dd682ddbea3" ascii wide nocase
    $pdb1 = "\\antino\\antino\\target\\" ascii
    $pdb2 = "antino_client_template.pdb" ascii
    $app  = "AntinoApp" ascii wide
  condition:
    uint16(0) == 0x5A4D and any of them
}

The bigger picture

Antino joins a growing set of implants that hide C2 inside the SaaS platforms enterprises cannot block. The lesson from Talos's research is less about the Rust code than about where detection has to live: in email authentication enforcement at the front of the chain, in script-host and sideloading telemetry in the middle, and in process-level attribution of Microsoft Graph traffic at the end. Government and policy organisations across the Indo-Pacific should assume they are in scope and sweep back to September 2025.