What I can assert, and what I cannot
This article is the companion to the technical account: there I described how I rebuilt my projector's firmware, here I show why I did it, figures to back it up.
A word on method before anything else, because it governs how everything that follows should be read. I distinguish three things, and I will keep them separate throughout:
- What established publications have documented, which I cite and have not reproduced.
- What I measured myself, on my machine, with tools I name and readings I publish.
- What I do not know, and will not fill in with assumptions.
It is tedious to write. It is also the only way to make an article of this kind useful to anyone other than its author.
What the publications established before me
January 2023 β an individual, a Pi-hole, and the first report
The whole affair begins with an ordinary purchase. Daniel Milisic, a Canadian consultant, ordered an Android T95 box on Amazon to run a Pi-hole on it β a network-wide ad filter.
The Pi-hole itself gave it away: barely plugged in, the box was querying domains associated with malicious campaigns. Milisic traced the trail, identified the offending components, and published a public repository in January 2023 with a neutralization script, having found no clean ROM.
I pause on this point because it struck me: three years apart, this is exactly the method I used. Logging names from the network, because the machine cannot monitor itself. We will return to this in the conclusion; it is no coincidence.
March 2025 β a security firm names the network
The Satori team at HUMAN Security published on 5 March 2025 an analysis of a network it named BADBOX 2.0: over a million low-cost Android devices β connected TVs, boxes, tablets β shipped with a backdoor installed before sale. The report describes several fraud schemes grafted onto it, including the resale of access to residential connections.
This is the broader context. It does not mention my projector β it describes the phenomenon it belongs to.
December 2024 to July 2025 β the authorities step in
In the meantime, the affair changes scale and stops being a hobbyist story.
- December 2024 β Germany's federal cybersecurity authority (BSI) sinkholed a command-and-control server and cut off communication from 30,000 devices on German soil.
- December 2024 β Bitsight in turn sinkholed a domain and counted more than 160,000 unique IP addresses within 24 hours. Their report includes a detail I haven't seen anywhere else: the infection no longer affects only unbranded devices, but also products from known manufacturers.
- March 2025 β a joint operation between HUMAN, Google, Trend Micro, and the Shadowserver Foundation neutralized more than 500,000 devices.
- June 5, 2025 β the FBI published a public advisory (reference I-060525-PSA) on consumer connected devices being used for criminal activities. It explicitly mentions projectors.
- July 2025 β Google filed a lawsuit against the network operators.
The fantasy hypothesis can therefore be dismissed: a federal authority, a US federal agency, and several security companies have been working on the same subject for two years.
February 2026 β a professional monitors his own connection
Johny Metellus, an IT manager, published on February 15, 2026 the account of a projector bought on Amazon that had become, according to his analysis, a relay for criminal traffic for two months. His findings are precise: one request every 65 seconds to a domain mimicking Facebook's, and the transmission of a complete device fingerprint β MAC address, identifier, firmware version β 2.17 seconds after power-on.
One detail caught my attention: his device is sold under the AODIN brand. Yet mine, branded Magcubic, queries servers on the aodintech.com domain. I note this as an observation, without drawing any conclusion from it: these devices clearly share a common base, resold under multiple brands.
May 2026 β a national CERT dissects a projector
On May 25, 2026, Azerbaijan's incident response center published the analysis of a $35 projector. It identified two components, com.hotack.silentsdk and com.hotack.writesn, and a domain, usmyip.kkoip.com, whose very name announces its purpose: recording the user's IP address.
The CERT notes that similar components were found on projectors sold under the Hotack, Huyukang, and Nonete brands. Again: a common base, multiple labels.
What these sources have in common β and where they differ
They converge on the mechanism: factory-installed components, invisible to the user, that contact remote servers without consent and serve as infrastructure for commercial or criminal activities.
But β and this is what most follow-up articles omit β they cover devices different from mine, with different components and different domains. The Azerbaijani CERT analyzed a HY300 Pro+; Johny Metellus an AODIN X1BQ; neither a HY350 Max.
That is precisely why I looked at mine.
The manufacturer's response
On April 22, 2026, Magcubic published a statement about certain APK files present on its products. I summarize it faithfully, sticking to what it says:
- it announces βthe following APK filesβ β and no list follows, neither in the English version nor in the French one;
- it states that these files are necessary for local services and contain no malware;
- it limits the matter to devices in the HY300 series fitted with the H713 chip;
- it states that models fitted with the H726 chip do not contain this APK;
- it recommends using the device offline and installing applications from a USB drive.
The HY350 Max is an H726. The statement does not mention it, and I draw no conclusion from that: a manufacturer who assembles hardware around a software base provided by a third party does not necessarily know the contents of that base. I simply note that my model is not addressed anywhere, and that I therefore had to look for myself.
What about the others?
I looked for public responses from the other brands mentioned in these cases β right of reply, press releases, social media posts. I found none.
The only statement from an industry player I was able to identify comes from Google, and it amounts to distancing itself: the devices in question are not Play Protect certified, the company essentially says, and certified devices pass tests that these have not. That is correct, and it does not tell the buyer who already has the device at home very much.
To be fair: Magcubic is among the very small number of manufacturers to have published anything. One may find this statement incomplete β it announces a list it never provides β and regret that it does not address my model. It remains the case that most of the brands involved have, to my knowledge, never said anything at all.
My method
The tools
Everything that follows was obtained using open-source or Android-supplied tools, on my own machine.
Firmware unpacking custom tool for the Allwinner container, lpunpack, debugfs
Package analysis jadx (decompilation), manifest reading
System state adb, dumpsys, pm list packages -U, /proc/net/tcp
Network capture tcpdump on the device (rooted variant)
Domain name log MyPublicWiFi, software access point with URL log
Name verification DNS resolution from a third-party hostThe access point that made all this possible
I pause here on MyPublicWiFi, because without it half of this article would not exist, and because the service it provides is not the one you would think of.
The principle is simple: the software turns a Windows PC into a Wi-Fi access point and logs the domain names requested by devices that connect to it. You plug the projector into it as you would a router, and read what it requests.
But the decisive function lies elsewhere. In its network access modes, it offers βNo Internet Sharingβ: the projector receives an address, a name server, a fully functional network β and no route to the outside.
This is the mode that made the first capture possible, and it had to exist. The stock firmware ships with a silent installer in working order; opening a route to observe it would have meant letting it succeed. Here, it talks into the void and we listen. We measure an intention without ever running the risk of a transmission.
For the second capture, βRouter (NAT)β mode did the opposite: it routes traffic according to the Windows routing table, so through a VPN once connected. The queried infrastructure saw a data center address, not my home.
And this is where the validity of the comparison lies: the same instrument served both conditions. A βbeforeβ captured with Pi-hole and an βafterβ captured differently would not compare honestly. Here, only the parameter being studied changes.
This software deserves an article of its own, and it will get one.
Four captures, four conditions
A network capture means nothing if you don't specify the conditions. I did four of them, all on the same day, on the same machine, with the device powered on and left idle:
| Firmware | Internet Access | Duration | Instrument | |
|---|---|---|---|---|
| 1 | stock | no | 26 min | DNS log + sockets |
| 2 | stock | yes (via VPN) | 2 min | DNS log + sockets |
| 3 | CleanRom | no | 10 min | packet capture |
| 4 | CleanRom | yes | 10 min | packet capture |
Captures 1 and 3 are comparable to each other, as are captures 2 and 4. Comparing a βbeforeβ with a route to an βafterβ without one would prove nothing, and that is a mistake I was careful not to make.
What each instrument sees, and doesnβt see
A name log records the domains a device attempts to resolve. It sits outside the machine, so it is unaffected by what runs on it β that is its strength. But it sees neither the content nor even whether a connection followed, and it is blind to any IP address reached without going through DNS.
A packet capture sees everything coming in and going out, in both directions, addresses included. But the content of encrypted sessions escapes it β and you need root to do it.
Hence the use of both.
App analysis
Seven names are circulating: two actually existed on my machine
A list of seven packages circulates for this device family. I checked each one, not by searching for strings β a misleading method β but by looking for app directories in the stock partitions.
| Package | Present on my HY350 Max? |
|---|---|
com.htc.storeos | yes β /product/app/StoreOs_QZ |
com.htc.htcotaupdate | yes β /product/app/HtcOtaUpdate_QZ |
com.htc.expandsdk | no |
com.htc.eventuploadservice | no |
com.hotack.writesn | no |
com.hotack.silentsdk | no |
com.htc.htclauncherhighenglishd08 | no |
Two out of seven. The other five appear only as names in configuration lists inherited from the platform: memory-killer exemption lists, launcher display filters, string tables. An entry naming a package that isn't there does nothing.
I point this out because the temptation to announce seven removals was strong. That would have been false, and a reader who checks would notice.
A word about silentsdk, absent from the list above: according to published analyses, it is not preinstalled by default β it gets downloaded at runtime by the installer. Its absence on a fresh unit therefore doesn't prove much, and that's exactly what makes the installer so central.
The most serious issue: system identity
If there's only one thing to take away from this whole article, it's this.
com.htc.storeos sharedUser = android.uid.system (uid 1000)
pkgFlags = [ SYSTEM HAS_CODE β¦ ]
com.htc.htcotaupdate sharedUser = android.uid.system (uid 1000)It's worth pausing on what that means. Android is built on a simple principle: each app gets its own user ID, and cannot touch the files or processes of others. That's the sandbox, and it's what keeps a phone reasonably secure despite the hundreds of apps installed on it.
UID 1000 is the identity of the Android system itself. An app that carries it is no longer in a sandbox: it sits alongside the package manager, the window manager, the account manager. It can install and uninstall silently, read protected settings, and survive a factory reset.
This level isn't obtained by checking a box. The app has to be signed with the firmware's platform key β the device's master key. Someone, somewhere in the chain, deliberately handed this key to a silent installer.
And this shared identity has a formidable practical consequence for anyone trying to investigate: all per-app accounting becomes useless. Android's network counter lumps these components together with dozens of legitimate system services. There's no way to attribute a single byte to them. Only domain names can tell them apart β which is what the rest of this article is about.
A setuid su binary shipped from the factory
Second finding, of the same kind. The original firmware contains:
-rwsr-sr-x 1 root shell 5788 /system/xbin/hotacksu
^
the setuid bit: the program runs as root
regardless of which user launches itThis is Android's su binary, renamed. And it's not there by accident: its path appears in the filesystem permissions table, compiled into libcutils.so, libadbd_fs.so and mkfs.erofs. In other words, the Android build tree was modified to grant it this privilege when the image was built.
One honest caveat, and it matters: on the original firmware, this binary doesn't work. I tried it β SELinux refuses the transition and it fails. It's there, armed, but neutralized by the security policy. Still, its mere presence, together with this declaration in the permissions table, says a lot about how this image was built.
The manufacturer's interface
Decompiling com.htc.magcubicos, the device's home screen and settings panel, reveals:
- a cleartext HTTP call to
store-api.aodintech.com, in the startup method; - the
com.baidu.mobstattracker, started when the app launches β 357 files, 4 MB of code; - the
INTERNET,INSTALL_PACKAGES,GET_ACCOUNTS_PRIVILEGEDandPACKAGE_USAGE_STATSpermissions; - on the "System information" screen, five launch points to the manufacturer's OTA and three components from the
hotackfamily, four of which are accessible via an undocumented key combination.
A settings app that bundles an ad tracker and the permission to install packages isn't a configuration anomaly. It's a design choice.
Network measurements
Reading 1 β no route: intent in its purest form
First measurement, 26 minutes, device idle, deliberately denied internet access. Since the stock firmware ships with a silent installer in working order, opening a route for the sake of the measurement would have let it succeed.
Result: 904 DNS requests, or about 35 per minute, on a device nobody touches.
| Requests | Domain | Type |
|---|---|---|
| 250 | server2.mphotool.com | third-party screen mirroring |
| 249 | server.mphotool.com | third-party screen mirroring |
| 216 | store-api.aodintech.com | silent app installation |
| 87 | www.google.cn | connectivity check, Chinese endpoint |
| 44 | ntp.ntsc.ac.cn, ntp.aliyun.com | Chinese time servers |
| 22 | time.android.com | legitimate |
| 22 | play.googleapis.com, www.google.com | legitimate |
| 8 | hmma.baidu.com, dxp.baidu.com | Baidu telemetry |
| 6 | ota.triplesai.com, otaapi.triplesai.com, ota-api.aodintech.com | non-OEM update channel |
The silent-installation endpoint is hit every 5 to 10 seconds, without interruption. If anything, the isolation makes the measurement cleaner, not less so: nothing triggers these requests, no response ever comes back, and the pace doesn't let up either.
Measurement 2 β with a route: the permanent channel
Second measurement, just two minutes long, with real access routed through a VPN so the infrastructure being contacted wouldn't discover my home address. Done right before the reinstall, so that anything that might have been dropped was wiped immediately after.
The connections go through:
3.12.169.56:443 mphotool 3 concurrent sessions, continuously
119.28.17.161:443 store-api present in 60 of 60 samplesThe silent-installation endpoint keeps an encrypted channel open for the entire observation, held by the system UID, to a Tencent Cloud address. This is no longer a resolution attempt: it's an established session, on a device nobody touches.
The reading trap
This is the most counterintuitive thing this investigation taught me, and it applies to anyone reading a DNS log.
With a route, store-api.aodintech.com is resolved only once. The first capture counted 216: those were retries, because nothing ever went through.
A single request followed by a persistent channel therefore represents more contact than a burst of one-off resolutions β not the other way around. Counting DNS log lines to gauge a device's activity would lead to exactly the wrong conclusion.
These endpoints are alive
Since my device couldn't resolve these names during the first capture, the question remained open: does this infrastructure still exist? Resolution carried out from a separate machine with normal access:
store-api.aodintech.com -> 119.28.17.161 Tencent Cloud
ota-api.aodintech.com -> 124.156.99.68 Tencent Cloud
ota.triplesai.com -> 111.230.36.129 Tencent Cloud
otaapi.triplesai.com -> 111.230.36.129 Tencent Cloud
server.mphotool.com -> 3.12.169.56 AWS
server2.mphotool.com -> 3.12.169.56 AWS
hmma.baidu.com -> 103.235.46.195 Baidu
api.bigbigcloud.cn -> NXDOMAIN (manufacturer's official channel, dead)The infrastructure being contacted is live. A nice detail: the only domain in the list that's actually dead is the manufacturer's official update channel β which incidentally explains why the original online update no longer works for anyone.
Captures 3 and 4 β after cleanup
Same conditions, same durations, on the rebuilt ROM. The rooted variant gives access to tcpdump: this time the measurement covers the packets themselves, at the source, in both directions.
Without the route, 275 packets in 10 minutes. 90 DNS requests, all to Google, plus the connectivity check and SmartTube's crash report. No unicast connection to the outside.
With the route, 3,729 packets in 10 minutes, and six external destinations:
2001:4860:4840:400:: 143,764 B received / 29,733 sent Google
142.251.156.4 109,918 B / 8,328 B Google
2a00:1450:4007:817::2003 5,956 B / 1,324 B Google
2001:4860:4844:400:: 0 B / 24 B Google
2a00:1450:4007:81a::200e 73 B / 0 B Google
2a00:1450:400c:c06::bc 24 B / 28 B GoogleSix destinations, all at Google. None of any other kind. I checked every remaining address in the capture one by one: local network, link-local addresses from neighboring devices announcing their services, ARP, switching frames.
The only four names requested: www.googleapis.com, www.youtube.com, firebaseinstallations.googleapis.com and firebase-settings.crashlytics.com β the last being SmartTube's crash report, which I document and which can be disabled.
The limits of all this
A record without its limits isn't worth much. Here are mine, and I'd rather write them myself.
I never saw what was being exchanged
Everything that matters goes over TLS. Even with a full capture, the content of a session to store-api.aodintech.com would remain encrypted. Reading what's said there would require an interception with a certificate installed on the device β another undertaking, one I didn't carry out.
So I know who talks to whom, when, and how many bytes. Never what is said.
I didn't observe any relaying
The publications I cite describe devices enrolled as residential relays. I measured nothing of the sort.
The only thing that resembled one: on the two-minute capture, the screen-mirroring app received 179,581 bytes and sent 178,345 β nearly symmetric, on a device at rest. A service that just listens doesn't send back the equivalent of what it receives. That's the profile of a relay. Two minutes isn't enough to claim it, and I'm not claiming it.
Sampling doesn't prove an absence
My captures establish what they caught. They never establish that nothing else happened. Twelve domains from the public indicator list weren't observed at all: they probably belong to later stages of the chain, triggered once instructions are received. Their absence disproves nothing.
And nothing here proves anything against me
This is the most honest limitation. These measurements show what changes between two firmware builds; they still assume my tooling is honest. The only level of proof that would remove that trust is reproducibility: publishing the scripts and the database fingerprint so anyone can rebuild and compare. That's the direction to take, and it isn't done yet.
What I take away
What I'm 100 % certain of, because I measured it myself and the raw files exist: two undocumented apps, carrying Android's system identity, were present on an official firmware build from September 2026. One of them maintained a permanent encrypted channel to infrastructure hosted at Tencent. A setuid su binary shipped with the image and was declared in the filesystem's permission table. The settings interface carried an ad tracker and a plaintext commerce call. And after reconstruction, over ten minutes of capture with real use, nothing remains but Google.
What I believe, without being able to prove it: that these components are part of the set described by the publications I cite, and that the screen-mirroring app's traffic profile would deserve longer observation.
What I'll never know: who placed these components, at which stage of the chain, and whether the company selling the device knew about it. A manufacturing chain involves several parties, and any one of them could itself have been compromised. There are victims β starting with those who bought the device β but naming a culprit would be speculation.
There's one thing this work taught me that goes beyond this projector: the system-level identity granted to a silent installer makes the device unauditable by its own means. No counter, no usage statistics, no security app installed on top of it can tell this component apart from the system itself. I had to step outside the machine β log the names from the network β to see anything at all.
That may be the real lesson of this story. A β¬60 device doesn't have the means to monitor itself. It has to be watched from the outside.
Sources
| Date | Author | Publication |
|---|---|---|
| January 2023 | Daniel Milisic | Initial discovery on a T95 box purchased on Amazon, via a Pi-hole β public repository and removal script |
| May 18, 2023 | Electronic Frontier Foundation | Android TV Boxes Sold on Amazon Come Pre-Loaded with Malware |
| December 2024 | Bitsight | BADBOX Botnet Is Back β sinkholing of a command domain, 160,000 IP addresses in 24 hours |
| December 2024 | BSI (Germany) | Sinkholing of a command server, 30,000 devices disconnected in Germany |
| March 5, 2025 | HUMAN Security, Satori team | Satori Threat Intelligence Disruption: BADBOX 2.0 Targets Consumer Devices with Multiple Fraud Schemes |
| June 5, 2025 | FBI / IC3 | Home Internet Connected Devices Facilitate Criminal Activity β public advisory I-060525-PSA |
| March 16, 2026 | well0nez | magcubic-root β Allwinner debloating toolkit, container format, permissions table |
| February 15, 2026 | Johny Metellus | I Had No Idea β My Amazon Projector Was a Criminal Proxy Node for Two Months |
| April 22, 2026 | Magcubic | Official Statement Regarding Certain APK Files on Magcubic HY300 Series Products |
| May 25, 2026 | CERT.GOV.AZ (Azerbaijan) | A $35 projector has turned into a source of hidden cyberthreats |
| June 6, 2026 | maximilian-sh | hy350max-badbox-removal β HY350 Max-specific findings, indicators of compromise |
| β | Android Open Source Project | A/B updates and verified boot |
Component analysis β network calls, permissions, trackers, hidden launch points β come from decompiling the applications on the original image and from measurements taken on my device. None of this comes from any external source.