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
- HTA / WSF stager.
mshta.exeruns an HTA from Cloudflare Pages that hides its window, beacons to the fixed tracking hostoisadjfoinsiduhfnoisdnfosdnoifnsoid[.]pages[.]devwith the lure title and?track, and imports the next stage from Cloudflare R2 ord2nq35tel3ucuo[.]cloudfront[.]net. WSF variants do the same through Windows Script Host. - 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.
- .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+Stategadget with an ActivitySurrogateSelector chain to loadTestAssembly.dlldirectly intomshta.exe. - TestAssembly.dll downloader. Downloads a decoy document and a three-file sideloading bundle with randomised extensions such as
.luy,.pzsand.syk, opens the decoy and launches the bundle. All recovered builds share the assembly GUIDb2b3adb0-1669-4b94-86cb-6dd682ddbea3. - Signed-host sideloading. The Microsoft-signed Windows ADK binary
GatherOsState.exeloadsslc.dllfrom its own directory and calls itsSLOpenexport, 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.
| Channel | Artefact | Purpose |
|---|---|---|
| OneDrive | /antino/heartbeats/{id}.json | Registration 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 |
| Outlook | Subject command_req_[session_id] | Operator tasking, polled every 10 seconds |
| Outlook | Subject 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.
| Indicator | Talos description |
|---|---|
1fadc90b61ce536abda78eb387a7f3d745f00c16775d3f762845ccc0fde567da | Antino Gen 1 slc.dll backdoor |
40e7e77aff603f4c2ef17b3bc8ea836e714d0734a1e5b946e52f95536ec5c91d | Configured Antino Gen 1 standalone backdoor |
09ef7c736bccfafefc44d9910d499173b88063b73b221fc0dc9e9105107e5cff | Antino Gen 2 slc.dll backdoor |
e2eb7703047b37b28dc34e6990205d758a2454b39bc655b460606745fadcb530 | Antino Gen 2 slc.dll backdoor |
0c39264337a1186b2e765e24073399cbdcba118306614eb411e315887af578bd | Antino Gen 2 standalone fake-installer backdoor |
5c5c060b272cd4a5c3767edc0e9478bd35b7e1756e183d0446a5491bd65519cb | Configured Antino standalone backdoor |
d753a615aedf8e58ffc75b2b7ebd320c0cbe6bcb5cbb885db749a2a85c55d3bf | Antino-chain TestAssembly.dll downloader |
e809da86bd81463347fa7f922d3e088755a94a331889d32acb55aa8f57778a34 | Malicious HTA stager (CSIS Indo-Pacific lure) |
103[.]27[.]110[.]220 | Historical serving IP for the Antino payload hosted on wps-cn[.]com |
osc-cdn[.]com | Actor-used spear-phishing sender domain |
oisadjfoinsiduhfnoisdnfosdnoifnsoid[.]pages[.]dev | Cloudflare Pages execution-tracking domain |
d2nq35tel3ucuo[.]cloudfront[.]net | Antino-chain CloudFront staging domain |
pub-abfa7742e315485a98a5fafd6dbfb68e[.]r2[.]dev | Antino-chain Cloudflare R2 staging domain |
pub-0173d1566dcd4fd49fa25f11f14bfe4c[.]r2[.]dev | Antino-chain Cloudflare R2 staging domain |
microsoft-flash[.]com, wps-cn[.]com | Standalone 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
- Enforce DMARC. Move your own domains from
p=nonetoquarantineorreject; 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. - Constrain script hosts. Block or alert on
mshta.exeandwscript.exefetching content frompages.dev,r2.devandcloudfront.net; where business allows, remove the.htaand.wsffile associations. - Watch signed-binary sideloading.
GatherOsState.exeoutside a Windows ADK install path, especially loadingslc.dllfrom a user-writable directory, is a high-fidelity signal. - Profile Graph API callers. Antino reaches
graph.microsoft.comandlogin.microsoftonline.comfrom 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. - Hunt Scripted Diagnostics abuse. Registry Run-key writes or PowerShell launched by
sdiagnhost.exeoutside a user-initiated troubleshooter warrant review. - 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.


