
How Routine Android TV Debloating Saved My Homelab From a Global Botnet
/ 7 min read
Table of Contents
Context
Earlier today, tech news broke regarding a massive consumer hardware supply chain compromise: Google’s Threat Intelligence Group published their findings on the XCPE botnet in an advisory titled Shutting the Door on the XCPE Botnet. According to the report, Chinese ODM manufacturer Videostrong Technology (the parent company behind MECOOL and OEM hardware supplier for numerous white-label brands) had embedded a factory-level firmware backdoor into consumer Android TV boxes. Over 1.3 million devices worldwide were infected out of the box, secretly operating as residential proxy nodes, stealing credentials, and launching DDoS attacks from living rooms.
The issue hit close to home when local tech discussions and an original post on X by @bayhansexmach3 pointed out that popular domestic Turkish brands like Next and Hiremco source their underlying TV box hardware and firmware directly from this exact MECOOL / Videostrong ODM supply chain.
As someone running a carefully isolated homelab with dual-stack OPNsense, strict DNS-over-TLS enforcement, and dedicated server workloads, I immediately opened a shell to inspect the Next UHD Google TV box sitting in my living room.
What follows is my notes on the incident, how an earlier weekend debloating pass had already neutralized the threat, and how I finalized its containment at both the operating system and network levels.
The Discovery
I opened an ADB session to my TV box (192.168.1.147:5555) to audit active packages against the indicators of compromise (IoC) highlighted in the Google TAG report:
adb connect 192.168.1.147:5555adb shell "pm list packages | grep -i -E 'oem|xcpe|cpe|video|strong|mecool'"The output confirmed the underlying ODM heritage:
package:com.amazon.amazonvideo.livingroompackage:com.google.android.videospackage:com.oem.qapackage:com.sdt.mecoolrcupairpackage:com.oemserviceThe telltale packages were right there: com.sdt.mecoolrcupair (linking Shenzhen Skyworth Digital / SDT to MECOOL’s remote hardware) and com.oemservice.
I inspected the filesystem path and package definition for com.oemservice:
adb shell "pm path com.oemservice"package:/system/priv-app/app_xcpe_preset/app_xcpe_preset.apkThe binary was the exact backdoor identified by Google TAG: an APK bundled directly in /system/priv-app/, granting it android.uid.system privileges to execute background shell commands, manipulate accessibility services, and silently establish residential proxy tunnels.
Why My Box Was Already Immune
Before panicking, I queried the package’s live runtime state:
adb shell "dumpsys package com.oemservice | grep -E 'enabled|flags'"adb shell "pm list packages -d"The response was surprising:
User 0: ... enabled=3---package:com.next.iptvpackage:com.sdt.producttestpackage:com.android.tv.feedbackconsentpackage:com.oem.qapackage:com.jettv.playerpackage:com.google.android.feedbackpackage:com.android.printspoolerpackage:com.next.roketpackage:com.oemserviceThe backdoor was already sitting inside the disabled packages list.
Weeks earlier, when setting up this TV box, I had followed my own open-source Android TV optimization workflow:
When I first set up the device, my goal was purely operational hygiene: eliminate manufacturer bloatware, stop idle telemetry, improve UI responsiveness, and replace the cluttered stock launcher with a lightweight interface (kutu-home). During that routine inspection, I had frozen all unneeded vendor daemons using pm disable-user --user 0:
com.oemservicecom.oem.qacom.sdt.producttestcom.next.roketcom.next.iptv
Because Android’s PackageManagerService enforces package disabling at the OS kernel level, enabled=3 (COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) meant that the system refused to deliver BOOT_COMPLETED intents, schedule background alarms, or launch background services for this UID. The botnet payload had been rendered inert on day one without me even knowing what it was.
Fortifying Against Re-infection
While the backdoor was dormant, two attack vectors remained:
- OEM Backup Managers: Vendor helper services that silently reinstall bundled OEM apps.
- Firmware Overwrites (OTA): Since the device uses A/B seamless system updates (
ro.product.ab_ota_partitions), an over-the-air firmware update pushed by the manufacturer would re-flash/systemand potentially resurrect the disabled packages.
I ran a quick process check to identify remaining vendor background daemons:
adb shell "ps -A | grep -i sdt"system 1383 394 1337252 20012 0 0 S com.sdt.backupappmangeru0_a29 3447 394 1338468 22780 0 0 S com.sdt.otaTo eliminate both risks, I froze the OEM backup manager and the OTA updater daemon:
# Stop OEM re-installeradb shell "pm disable-user --user 0 com.sdt.backupappmanger"adb shell "am force-stop com.sdt.backupappmanger"
# Stop silent OTA firmware flashingadb shell "pm disable-user --user 0 com.sdt.ota"adb shell "am force-stop com.sdt.ota"
# Re-affirm Google Play Protect verifieradb shell "settings put global package_verifier_enable 1"With com.sdt.ota disabled, the box is completely severed from manufacturer update channels, ensuring no future firmware payload can overwrite the system partition.
Dual-Stack Network Isolation in OPNsense
Device-level disabling is effective, but defense-in-depth requires enforcing boundaries at the network edge. Even if someone factory resets the TV box or a new zero-day runs in memory, the firewall should prevent it from ever behaving like a proxy node or botnet client.
The IPv6 Dynamic Address Challenge
Restricting an Android device at the firewall is tricky because modern Android enforces RFC 4941 Privacy Extensions: the device generates temporary, randomized IPv6 addresses that rotate every few hours. Pinning a static IPv6 firewall rule fails as soon as the address expires.
Instead of writing brittle IP rules, I utilized OPNsense’s MAC Address Alias type:
- Alias Name:
tvbox_hosts - Type:
MAC address - Content:
48:5c:2c:0b:36:12
OPNsense resolves MAC aliases by continuously inspecting its local ARP table (for IPv4) and NDP neighbor table (for IPv6). Whenever the TV box generates a new temporary IPv6 address, OPNsense automatically detects the link-layer binding on igb0 and updates the underlying packet filter (pf) table:
pfctl -t tvbox_hosts -T show 192.168.1.147 2a00:1d36:...:677e:4b7d:2b47:66b2 2a00:1d36:...:b6ad:babf:24d4:995f 2a00:1d36:...:2f59:88e6:2b8e:b114 fdf8:79bc:...:e44a:412e:794f:7e1bThe Firewall Policy
A streaming box only needs a handful of outbound ports to function:
- Port
53/853: Local DNS (forced to AdGuard Home via an existing redirect rule). - Port
80&443: HTTP/HTTPS for streaming CDNs (YouTube, Netflix, Jellyfin, Google TV). - Port
123: NTP time synchronization. - Port
5228:5230: Google Cloud Messaging / Firebase push notifications.
Everything else—arbitrary TCP ports, high UDP ports, residential proxy relays, and SSH/Telnet scans—must be dropped.
I added the following rules to OPNsense’s LAN interface:
# Rule 1: Allow local LAN communication (Chromecast, Jellyfin, Remote app)pass in quick on igb0 inet46 from <tvbox_hosts> to (igb0:network)
# Rule 2: Allow outbound traffic exclusively on streaming portspass in quick on igb0 proto { tcp, udp } from <tvbox_hosts> to any port { 80, 443, 123, 5228:5230 }
# Rule 3: Reject everything elseblock return in quick on igb0 inet46 from <tvbox_hosts> to anyA quick verification test via ADB confirmed the rule behavior:
# 1. Local gateway & DNS reachabilityadb shell "ping -c 2 192.168.1.1" # 0% packet loss (PASS)adb shell "ping -c 2 192.168.1.10" # 0% packet loss (PASS)
# 2. Outbound HTTPSadb shell "nc -w 2 -W 1 www.google.com 443" # Connected (PASS)
# 3. Outbound Unauthorized High Port / ICMPadb shell "ping -c 2 -w 2 8.8.8.8" # 100% packet loss (REJECTED)adb shell "nc -w 2 -W 1 1.1.1.1 22" # Connection refused (REJECTED by firewall)Lessons on Supply Chain Security and Debloating
This experience highlighted a few fundamental takeaways for homelab operators and systems engineers:
- Hardware Brand Names Mean Nothing in White-Label Tech: The front panel said “Next”, but the board was designed by Shenzhen Skyworth Digital, running firmware derived from Videostrong/MECOOL with a pre-installed backdoor. In the cheap consumer hardware segment, brand trust is an illusion.
- Attack Surface Reduction is Proactive Security: Debloating is often treated merely as a performance hobby—something to squeeze an extra 200MB of RAM out of an underpowered stick. In reality, disabling unvetted OEM packages eliminates potential command-and-control backdoors before vulnerabilities are even published.
- Layered Defense Works: Even if an OS backdoor remains undetected, strict egress filtering and forced local DNS make it nearly impossible for malicious code to weaponize an internal host.
If you have an Android TV box in your home, spending twenty minutes to audit its package list with ADB and pinning its outbound network access is well worth the time.