Published in coordination with Google Threat Intelligence Group and Mandiant. Their report on the wider UNC7017 campaign is available here.
Executive summary
- Detection: On 28 May 2026, ManageEngine EDR recorded AOMEI Backupper installing Radmin, a commercial remote-administration tool. The same execution chain appeared on a second, unrelated customer endpoint in another country within the same window.
- Delivery: Within the 232-file AOMEI promotional bundle, upgrade-now.html programmatically triggered a sibling executable through AOMEI’s own in-application content flow.
- Integrity gap: Neither configuration file is cryptographically authenticated by the client, and the checksum used to validate the downloaded archive is declared inside the same unauthenticated file that names it.
- Blind spot: Tampering lasted only a few minutes at a time on isolated dates. The dropper observed on 28 May had self-deleted, and its hash returned no results on VirusTotal. A matching sample was later found by searching for its product string.
- Payload: Radmin Server was installed from a genuine Famatech installer but arrived without a server address or credential. Alongside it, an attacker-built DLL was placed beside the Radmin launcher, which side-loads it and registers an encrypted PocketPy implant as a COM server inside a signed dllhost.exe surrogate.
- Consequence: The chain operates with the privileges of the AOMEI process that launches it and supports runtime code delivery over the C2 channel. Although Radmin Server was installed, we found no evidence that it was running. Remote access instead depended on the implant’s outbound connection to the C2 server. GTIG and Mandiant track the activity as UNC7017, the dropper as CROSSROAD and the backdoor as SHINYROAD.
The delivery mechanism
Nothing in this attack exploited a software defect. There was no CVE, no memory corruption, and no unpatched component. The adversary used AOMEI Backupper's promotional content channel exactly as it was designed to work. The compromise only becomes clear once that channel is understood.
So, first, the channel.
AOMEI Backupper runs background services that poll AOMEI's infrastructure over HTTPS for promotional material. Two of them matter here, and they use separate remote configuration files for different jobs.
down_html.ini determines what reaches the endpoint. Backupper.exe requests the file, reads the package URL and expected MD5 declared inside it, downloads the archive named by that URL, validates it against the declared checksum, extracts the contents into a staging directory, and relocates them into the application's resource directory.
Notifycfg.ini determines what reaches the endpoint. ABNotify.exe retrieves the file from a separate AOMEI host and follows its instructions, causing the bundled upgrade-now.html to load in the application’s WebView inside a one-by-one-pixel window. The HTML then triggers execution.
Figure 1: Two configuration paths converge on the same directory: one delivers the content, the other executes it.
The two paths converge on the same location. One controls what lands in html\; the other controls what can be executed from it. Neither configuration file is cryptographically authenticated by the client, and the checksum used to validate the archive is declared inside the same unauthenticated file that names it.
That destination matters. html\ exists for rendering assets, not executables. Nothing in the application’s normal operation would place a binary there.
The investigation
What the endpoint recorded
The two detections on 28 May came from organisations that shared no infrastructure, no administrators, and no supplier relationship. On 7 June, one of them raised the activity with us.
By then, the artifacts were gone. The dropper had self-deleted, and its hash was not found in VirusTotal. The executable was no longer available to examine. What we could trust was the telemetry: EDR had captured the execution as it happened, preserving the process lineage, file paths, signatures, and command line. That record became the starting point for reconstructing the chain on AOMEI Backupper 8.3.0.
| Process | Signed | Recorded action |
|---|---|---|
| Backupper.exe | Yes | Extracted archive contents into ...\8.3.0\tmphtml\, then relocated them to ...\8.3.0\html\ |
| ABNotify.exe | Yes | Started upgrade-now.exe from ...\8.3.0\html\upgrade-now\ |
| upgrade-now.exe | No | Dropped Radmin components and self-deleted |
| rsetup64.exe | Yes | Installed Radmin Server with /intsetup |
Table 1: Process lineage reconstructed from EDR telemetry.
Figure 2. Process lineage on the affected endpoint.
The telemetry also preserved something the deleted executable could not: where it came from and how it got there.
The archive was extracted into tmphtml\ and then relocated into html\, following AOMEI’s own sequence for handling popup resources. ABNotify.exe subsequently launched upgrade-now.exe from that same html\ hierarchy.
That path mattered. The executable had travelled through the application's normal extraction workflow and then executed from the application's own rendering directory. What initially looked like an unsigned executable in an unusual location was, in fact, part of a chain that followed the application's own content-delivery path.
Figure 3. The dropper node expanded, with the static-analysis alert on the same process.
rsetup64.exe /intsetup invokes the genuine Radmin Server installer. Although Radmin Server normally listens for inbound connections, our telemetry confirms only that it was installed. As the payload analysis reveals, remote access in this chain depended on a separate component.
Why we could not reproduce it
On 7 June, we notified AOMEI Technology. Its initial explanation was that the content had been intercepted and modified in transit. We installed AOMEI Backupper in a controlled environment, polled the same promotional endpoint, and watched.
The mechanism worked exactly as designed. The same HTML file arrived, the WebView rendered it, and the content pointed to a legitimate AOMEI URL. No executable arrived.
The reproduction showed that the delivery mechanism itself was functioning normally. The flow worked end to end, and the popup behaved exactly as expected.
That left two pieces of evidence pointing in different directions. The endpoint record showed a complete execution chain. Our reproduction of the same path, through the same mechanism and against the same infrastructure, showed nothing at all. One of the two had to be wrong.
We chose to trust the telemetry.
EDR had captured the process lineage as the activity occurred, rather than reconstructing it afterward. The same sequence had also appeared independently on two endpoints in environments that shared no infrastructure, administrators, or suppliers. A reproduction that fails once is a data point, not a refutation.
That changed the question. We stopped asking whether the activity had happened and started asking when it had happened and under what conditions. The difference was time: what the servers returned on 28 May was not what they returned when we tested them.
The evidence did not support AOMEI’s explanation of interception in transit. Both endpoints had retrieved the content over HTTPS from AOMEI-owned hostnames, across different countries and unrelated network paths, and the executable had arrived through the application’s own extraction sequence rather than being written directly to disk by an external process. The content had been altered before it reached either endpoint, within the vendor-hosted delivery path.
Hunting for a sample
We could describe the attack, but we could not demonstrate it. Nothing had survived on either endpoint.
So we treated the telemetry as a specification. From the recorded process lineage we built a behavioural profile: a signed vendor process extracting an archive into its own staging directory; an unsigned child executing from the rendering directory while retaining the vendor's publisher metadata; and a remote-administration installer invoked immediately afterward. We then hunted for samples matching that profile.
The telemetry also preserved the dropper’s file metadata, including its product name, "AOMEI Update Compent." The misspelling provided a distinctive search term. A VirusTotal search for executables with that product name uncovered a matching sample, which every scanning engine had classified as benign VirusTotal link.
We ran the sample in an isolated sandbox. It checked the host’s geolocation and scanned for specific endpoint security agents, terminating when the environment did not meet its criteria. The sample was selective about where it would execute.
That settled whether the file was malicious, and our reproduction had already shown the delivery path serving clean content. The open question was when the path served something else, so we began monitoring it.
Monitoring the delivery path
Knowing how the mechanism worked was not the same as proving that AOMEI’s infrastructure had served the payload. A point-in-time check could not answer that question. By the time we looked, the tampering had already reverted.
So we stopped checking and started watching. We placed continuous automated monitors on the specific AOMEI delivery URLs. At fixed intervals, the monitors retrieved both the configuration and the referenced package, then compared the served content and its hash with the previous retrieval.
On 16 July, the monitor caught the change in progress. For a brief window, the content served by the AOMEI delivery path changed, along with its hash. The modified package contained the malicious payload. Within minutes, the content reverted to the authentic baseline.
Figure 4. Notifycfg.ini as served during the 16 July window.
That observation changed the case. We were no longer inferring what might have happened from endpoint evidence and a failed reproduction. We had directly observed the delivery path serving the modified content.
We shared the complete attack profile with AOMEI Technology. GTIG and Mandiant had received our initial indicators in June, and the full attack profile followed on 17 July. On 20 July, while our monitoring setup was down, they observed the same pattern recur and captured the short-lived change.
Figure 5. Investigation timeline, 28 May to 20 July 2026.
Payload analysis
GTIG and Mandiant’s analysis covers additional malware builds observed across the campaign.
The dropper
The intercepted archive contained 232 files of AOMEI promotional content, with internal links pointing to legitimate AOMEI properties. Two files stood out: upgrade-now.exe, an unsigned executable bundled alongside the promotional assets, and upgrade-now.html, which constructed a link to the executable and triggered it programmatically.
The bundle is rendered in AOMEI Backupper’s in-application upgrade popup, a WebView that loads the promotional HTML. The crafted upgrade-now.html did not need to exploit the WebView. Instead, a script created a link to upgrade-now.exe, the executable bundled in the same archive, and clicked it automatically. The WebView treated the click as URL navigation and handed the executable off to the system shell.
Figure 6. The script in upgrade-now.html that creates a link to the bundled executable and clicks it.
Figure 7. Notifycfg.ini points the popup at upgrade-now.html on the local disk.
The execution mechanism depends on the HTML being loaded locally. Notifycfg.ini directs the popup to upgrade-now.html through a file:/// path inside the AOMEI installation directory (Figure 7), causing the embedded WebView to treat it as local content. The page’s script then triggers the sibling executable through the WebView’s navigation handling. When loaded from the internet, the same HTML would be subject to different security restrictions that prevent this execution mechanism.
No vulnerability was required, and no user interaction beyond having the application running. The dropper was not fetched separately or written to disk by another process. It arrived in the bundle and ran from the folder the application had just extracted it into.
The executable was built to look like an AOMEI component, carrying AOMEI publisher metadata and copyright information. Besides the missing signature, one further detail gave it away: its product string read "AOMEI Update Compent", a misspelling of "Component" that does not appear in genuine AOMEI builds. The fixed string also provides a useful hunting artefact.
Before doing anything further, the dropper checked whether the environment was one it wanted to operate in. It resolved the host’s public IP through external IP-reflection services and terminated if that IP geolocated to China. It also terminated when geolocation failed, preventing the payload from progressing in offline or network-restricted environments. The dropper additionally checked for specific endpoint security agents and halted if any of them were present.
On a host that passed those checks, the dropper retrieved the second stage and ran rsetup64.exe /intsetup, installing genuine Radmin Server to C:\Program Files (x86)\rserver30. Alongside it came component.zip, holding FamItrfc.exe, BlkScrDl.dll, RuntimeComponent.dll and config.zip. It established persistence through a scheduled task named RadminComponentRuntime, configured to run the Radmin launcher every three hours. It then removed itself by overwriting its own file through an NTFS alternate data stream, leaving no copy on disk for post-incident recovery.
A backdoor that ships unarmed
component.zip holds four files, and no single one of them is a functioning backdoor.
FamItrfc.exe is a genuine, Famatech-signed Radmin binary, unmodified in any way that alters its behaviour. It is the file the scheduled task launches, and its only role in the chain is to load something else.
Radmin itself arrived without a server address or login credential. rsetup64.exe /intsetup runs the genuine Radmin Server installer, and Radmin Server is normally the listening component: a service that waits for inbound connections from a remote operator. On that basis, we initially expected to find an active listener on the endpoint.
That expectation did not hold. After deployment, we found no active listener on the expected port, no Radmin registry configuration and no newly created user account. The installer had run, but the service was never confirmed as started, listening or configured with a credential. The Radmin component was staged but never armed.
The remote-access capability in this chain comes from a separate, outbound channel. The implant, RuntimeComponent.dll, loaded through the FamItrfc.exe → BlkScrDl.dll COM chain, is built to make a reverse TCP connection out to its C2 server. Remote access here is driven by the implant connecting out, not by Radmin’s inbound listener. In our environment, the C2 was unresponsive, so we did not observe a live session.
BlkScrDl.dll is the attacker-built component. Despite its name it is not a Radmin file: it was compiled on a different toolchain and contains none of the graphics APIs the name suggests. When the scheduled task starts FamItrfc.exe, that signed binary side-loads BlkScrDl.dll through search-order hijacking. GTIG and Mandiant’s analysis established this mechanism, which our own sample set could not fully account for. The dropper plays no part in it: it has already self-deleted by the time the task first runs.
RuntimeComponent.dll is the implant. BlkScrDl.dll registers it as an in-process COM server hosted inside a signed Windows dllhost.exe surrogate, so the implant executes within a Microsoft-signed process rather than a binary of its own.
config.zip carries the payload, and the route to it runs entirely in memory. RuntimeComponent.dll reads the archive, decompresses it without writing to disk, extracts metadata.dat, and decrypts that file with ChaCha20 to produce a pocketpy payload. Rather than reconstructing the key schedule externally, we invoked the malware’s own decryption routine in-process, producing a byte-identical result across three runs.
The decrypted configuration revealed a self-updating agent capable of reverse TCP communication, shell execution, and receiving and executing new interpreter code at runtime. Its observed capabilities should therefore be treated as a floor, not a ceiling.
The decrypted configuration also revealed the C2 endpoint: 8[.]218[.]65[.]184:41397. The address does not exist in the file at all. It is produced only by decryption at runtime, which helps explain why the sample could appear benign to public scanning engines even while being deployed in the attack. The implant communicates with a single host over a single TCP port, with no fallback address, domain generation, or peer discovery.
Because remote access depends on the implant connecting out, blocking outbound communication to the C2 cuts off the chain’s only control channel. The implant cannot check in, and the operator has no other way in.
A second vector, credited to GTIG and Mandiant
Our telemetry covers the execution chain described above. During the 20 July tampering window, when our monitoring setup was down, GTIG and Mandiant identified an additional vector used in the same campaign. This vector is significant because it requires no code execution.
Alongside the package redirection, the adversary altered Notifycfg.ini to render an invisible window pointing at a remote HTML file over a UNC WebDAV path. Endpoints that simply launched the application and parsed that popup were prompted to open an outbound SMB or WebDAV connection to attacker-controlled infrastructure, transmitting the logged-in user’s NetNTLMv2 authentication material for offline cracking or relay. No binary needed to run.
That matters for scoping. An endpoint protected against the execution chain, or one where the dropper’s guardrails aborted, may still have leaked credentials through the notification path. Their report covers this vector in full.
Privilege scope
The dropper contains no privilege-escalation code. Across 175 decompiled functions, we found no token-manipulation primitives, calls to GetShellWindow, OpenProcessToken, DuplicateTokenEx, or CreateProcessWithTokenW, or evidence of a UAC bypass. The only process-creation API resolved in the binary was the standard CreateProcessW.
Instead, the dropper inherited its execution context from the process that launched it. A child process normally inherits its parent’s access token, so the dropper ran with the same privilege level as ABNotify.exe itself.
The installation paths suggest elevated execution. Radmin Server and its components were written to C:\Program Files (x86)\, a location that normally requires administrator privileges for writes, and the process tree in Figure 2 places the AOMEI processes beneath ABService.exe, a service. If the launching AOMEI process was running elevated or as SYSTEM, the dropper could inherit that elevated context without implementing its own privilege-escalation mechanism.
For responders, this establishes a boundary around the initial execution: the chain runs with the privileges of the AOMEI process that launches it. That boundary, however, does not necessarily extend to subsequent activity. The implant can retrieve and execute additional code at runtime, and the recovered sample provides no basis for determining what that code could ultimately do.
Figure 8. Attack process chart: Steps 1 to 3 are the application behaving as designed. The chain diverges at step 4.
The wider campaign
GTIG and Mandiant’s report covers activity beyond the two events captured by our telemetry. It documents tampering windows dating back to April 2026, targeting of AOMEI AnyViewer alongside Backupper, the credential-harvesting vector described above, and later-stage post-exploitation tooling disguised as PDF software. It also provides a broader set of indicators and YARA rules.
Organisations running either AOMEI product should hunt across the full April-to-July period using both reports.
MITRE ATT&CK mapping
| Tactic | Technique | ID | Description |
|---|---|---|---|
| Initial Access | Supply chain compromise: Compromise software supply chain | T1195.002 | Transient tampering of down_html.ini, including the declared checksum, and of the referenced archive |
| Execution | Inter-process communication: Component Object Model | T1559.001 | BlkScrDl.dll registers RuntimeComponent.dll as a COM server and triggers its instantiation, loading the implant |
| Execution | Command and scripting interpreter: Python | T1059.006 | Dynamic payload execution via an embedded pocketpy interpreter inside dllhost.exe |
| Persistence | Scheduled task/job: Scheduled task | T1053.005 | RadminComponentRuntime task launching FamItrfc.exe every three hours |
| Discovery | Software discovery: Security software discovery | T1518.001 | Dropper queries for specific endpoint security agents and halts if any are present |
| Stealth | Masquerading: Match legitimate name or location | T1036.005 | Execution from the trusted html\ resource directory; misspelled AOMEI Update Compent product string |
| Stealth | Execution Guardrails | T1480 | Dropper terminates if the host IP geolocates to China, and if geolocation cannot be resolved at all |
| Stealth | Hijack execution flow: DLL side-loading | T1574.002 | FamItrfc.exe side-loading the attacker-built BlkScrDl.dll |
| Stealth | Virtualization/sandbox evasion: System checks | T1497.001 | Termination on detection of specific endpoint security agents, or on failure to resolve geolocation |
| Stealth | Indicator removal: File deletion | T1070.004 | Self-deletion via NTFS alternate data stream |
| Stealth | Obfuscated files or information | T1027 | C2 configuration encrypted at rest; endpoint resolvable only in memory |
| Command and Control | Ingress tool transfer | T1105 | Dropper retrieves component.zip from attacker-controlled infrastructure |
| Command and Control | Remote access software | T1219 | Deployment of Famatech Radmin Server via rsetup64.exe /intsetup, credential provisioned post-check-in |
| Command and Control | Non-standard port | T1571 | Reverse TCP connection over high port 41397 |
Table 2: MITRE ATT&CK mapping
Detection and hunting
Hash-based detection is a poor fit for this campaign. The dropper self-deletes, the C2 address exists only after runtime decryption, and the tampered archive reverts to authentic content within minutes. The more durable indicators are structural: where processes execute, how they are related, and what normally legitimate components are doing.
- Executable launched from a rendering directory: An executable launched from ...\<version>\html\ within an AOMEI Backupper installation is highly unusual. The directory is intended to hold HTML and related rendering assets, not executables. Execution from this path should be investigated.
- Unsigned child of a signed vendor process presenting the vendor’s metadata: upgrade-now.exe presents AOMEI publisher information but is unsigned. Monitoring for unsigned children launched by AOMEI update or notification processes, particularly when those children present the vendor’s publisher metadata, can identify this pattern without relying on file hashes or reputation services.
- Radmin installed without its normal configuration: A Radmin installation with no configured server address or credential should not be dismissed as an inert installation artifact. In this campaign, the component was deployed ahead of activation and received its credential only after the implant checked in.
- The Radmin launcher loading an unexpected DLL: Investigate FamItrfc.exe loading BlkScrDl.dll or any DLL outside the normal Radmin distribution, as well as dllhost.exe instances hosting COM components registered from non-standard paths.
- Outbound connection without preceding DNS resolution: The implant uses a hardcoded IP address rather than a domain name, so its outbound C2 connection does not require a preceding DNS lookup. An unexpected connection to a high TCP port without corresponding DNS activity is therefore a useful behavioural signal.
Sigma rules
The two rules below target the point where the delivery chain becomes observable on the endpoint: Backupper.exe writing an executable into its staging directory, followed by ABNotify.exe launching it from the rendering directory. Both rules detect behaviour and file location rather than hashes, so they remain effective even if the dropper is rebuilt or modified.
Executable written into the staging directory: Fires when Backupper.exe writes any executable into tmphtml\.
title: AOMEI Backupper Staging Executable In Tmphtml Directory
id: d18188bb-42c7-4c37-8a50-b3c865c5508d
status: experimental
description: |
Detects a file creation event for any executable inside the "tmphtml" staging
directory beneath the AOMEI Backupper installation path, where the creating process
is Backupper.exe. The application stages popup resources here before relocating them
to html\; a genuine promotional bundle contains no executables, so an .exe written
to this path indicates a tampered bundle.
author: Veeramani
date: 2026-08-29
tags:
- attack.initial-access
- attack.t1195.002
- attack.stealth
logsource:
category: file_event
product: windows
detection:
selection_process:
Image|contains: '\AOMEI\AOMEI Backupper\'
Image|endswith: '\Backupper.exe'
selection_file:
TargetFilename|contains|all:
- '\AOMEI\AOMEI Backupper\'
- '\tmphtml\'
TargetFilename|endswith: '.exe'
condition: all of selection_*
falsepositives:
- None known; legitimate AOMEI promotional bundles observed contain no executables
level: high
Executable launched from the rendering directory: Fires when ABNotify.exe starts any executable from the html\ hierarchy.
title: AOMEI ABNotify Spawning Executable From Rendering Directory
id: 3768e7d0-ba38-48fa-a630-d25bb50438de
status: experimental
description: |
Detects ABNotify.exe, running from the standard AOMEI Backupper installation path,
spawning any executable located in the html\ rendering hierarchy. This directory is
intended for rendering assets, not executables; a child process launched from here
indicates a hijacked upgrade workflow triggered through the AOMEI notification agent
with no user interaction.
author: Veeramani
date: 2026-06-11
tags:
- attack.stealth
- attack.t1036.005
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|contains: '\AOMEI\AOMEI Backupper\'
ParentImage|endswith: '\ABNotify.exe'
selection_child:
Image|contains|all:
- '\AOMEI\AOMEI Backupper\'
- '\html\'
Image|endswith: '.exe'
condition: all of selection_*
falsepositives:
- None known; legitimate AOMEI rendering bundles observed contain no executables
level: high
Triage and enforcement
On triage: When an updater-spawned process triggers an alert, checking the vendor URL or its current reputation may come back clean because the tampering has already reverted. That check describes the infrastructure as it exists now, not what the endpoint received when the activity occurred. Preserve any content captured in the application’s staging and resource directories, and correlate the alert timestamp with proxy, gateway, and other network telemetry. A clean point-in-time reputation check is weak evidence against a supply-chain compromise.
On enforcement: The environments that generated these alerts were running our behavioural policies in audit mode, so the activity was recorded but not blocked. Whatever product you use, know which behavioural policies are configured for detection only, and make sure that configuration is an intentional decision rather than an inherited default.
Indicators of compromise
Durable indicators reflect design choices the adversary would have to rebuild the toolkit to change. Volatile indicators will rotate.
Durable — File and structural
| Indicator | Note |
|---|---|
| Product string AOMEI Update Compent | Misspelling of “Component”; absent from genuine AOMEI builds |
| Unsigned upgrade-now.exe carrying AOMEI publisher metadata | Genuine AOMEI components are signed |
| Executable present in ...\<version>\html\upgrade-now\ | Rendering directory; normally HTML assets only |
| BlkScrDl.dll alongside a Radmin installation | Attacker-built; not part of the Radmin distribution |
| FamItrfc.exe launched by a scheduled task | Legitimate Famatech binary used as the side-load host |
| RuntimeComponent.dll registered as a dllhost.exe COM server | Embedded PocketPy interpreter; the C2 component |
| config.zip and metadata.dat in the Radmin install path | Encrypted payload, decompressed and decrypted in memory |
Table 3: Durable: File and structural
Durable — Process and identity
| Indicator | Note |
|---|---|
| Scheduled task RadminComponentRuntime | Runs every three hours |
| Radmin installed with no server address or credential | Deployed capability awaiting C2 provisioning |
| rsetup64.exe /intsetup invoked by an unsigned parent | Radmin Server installation triggered by the dropper |
Table 4: Durable: Process and identity
Volatile — Network
| Indicator | Value |
|---|---|
| Command and control | 8[.]218[.]65[.]184:41397 |
| Package URL | hxxps://promotion[.]storagedata[.]com/download/abpopup/upgrade-now[.]zip |
Table 5: Volatile: Network
Volatile — Hashes
| File | SHA-256 |
|---|---|
| down_html.ini | a984fdb0830760446d2b599b263506e01fcf1e560a31a057c3bbe7b3f8ac155d |
| Notifycfg.ini | 2e3b4bfb86224f079b8762ce78bb7ff10afdbf8421b08b23e96429f2e1ee7b50 |
| upgrade-now.exe (28 May endpoint) | 130c3970f1c900191615b99d8be522d6a488a3d3b73938896ed937092007d96a |
| Hunted Virustotal sample | 53b7d01163ccb679001f20e4a8a5e1f33d5d2837c375315f6514cc820f81bd12 |
| component.zip | d167bc898e856da8a4003cb4dfc7de55fea109eee3cd64fc8999710314109464 |
| BlkScrDl.dll | 5837bc26a73cfb46ffd466cf889f03ce2f6a48f1f3fd42ec8be22189d51cab1e |
| WNTestdll.dll | 100657d3e205bfd0e96f1c088ae1739b50657592a696201467b4c65b7d36289a |
Table 6: Volatile: Hashes
Conclusion
Nothing in AOMEI Backupper was exploited. The application performed as designed: it fetched a configuration file over HTTPS, read the package URL and checksum from that file, validated the archive against the declared checksum, extracted the contents into its own directories, and rendered the result. Every check passed because the party controlling the configuration could control what each check was asked to verify.
That is what makes this pattern inexpensive to repeat. Compromising a build pipeline requires deeper access and leaves traces in shipped binaries that may remain discoverable for months. Altering a remote configuration file for a few minutes requires no change to the released software, can disappear before a point-in-time check, and leaves the legitimate application to perform the execution.
The underlying weakness is not unique to AOMEI Backupper. It applies to any desktop application that resolves a download target from a remotely fetched file without independently authenticating that file and its contents. A checksum can establish that a downloaded file matches the value supplied to the client. It cannot establish that the value itself came from the vendor.
Promotional and notification channels deserve the same scrutiny as other software-delivery paths when they can retrieve, extract, and render remotely supplied content. Once that content can influence what the application executes, the channel becomes part of the application’s trusted execution path and should be secured accordingly.
The investigation also carries a lesson about evidence. Behavioural telemetry and a point-in-time infrastructure check answer different questions: telemetry records what happened on an endpoint when it happened, while an infrastructure check records what a server is serving when someone looks. Our reproduction was clean because the malicious content was no longer being served, and the endpoint evidence from 28 May remained exactly as valid as it had been before we ran it. Treating the failed reproduction as a difference in time is what kept the investigation open.
Attacks built to leave a clean present behind depend on investigators asking only what infrastructure serves now. A server can look legitimate when examined and still have served something else minutes, hours, or days earlier. The more useful question for defenders is what the endpoint received when the alert fired, and in this case the telemetry had preserved the answer.
For software vendors, five controls close this pattern:
- Sign configuration files as well as binaries: With asymmetric signing, the client rejects an unauthorised change made at an origin server or CDN edge.
- Deliver checksums independently of the URL they validate: An integrity value carried in the same file as the download instruction can be changed by anyone who can change the instruction.
- Compare delivered content against a published baseline: File-level checksums confirm that a download completed intact. Confirming that the contents match what the vendor shipped needs a separate check.
- Pin update downloads to pre-approved hosts: Update clients should refuse to follow a configuration file that points them to third-party domains or public object storage.
- Keep content channels away from execution paths: A channel built to display promotional material should never write to a directory from which the application executes code.
Vendor status
We notified AOMEI Technology on 7 June 2026. The company has reported taking corrective action on its infrastructure. GTIG and Mandiant separately notified AOMEI and potentially affected organisations. As of publication, we have not independently verified that the compromise has been contained.
Server-side remediation does not clean an endpoint that already received a payload during an earlier tampering window. Organisations running AOMEI Backupper should hunt their own environments rather than treating the vendor fix as sufficient.
Acknowledgements
We thank the security team at the affected customer organisation for escalating the alert rather than closing it, and Google Threat Intelligence Group (GTIG) and Mandiant for their collaboration, independent confirmation of the tampering and notification of affected organisations.
GTIG and Mandiant track the activity as UNC7017, the dropper as CROSSROAD and the backdoor as SHINYROAD. The threat already had enough going on without us adding three more names.