skip to content
Burak Berk Keskin
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:

Terminal
adb connect 192.168.1.147:5555
adb shell "pm list packages | grep -i -E 'oem|xcpe|cpe|video|strong|mecool'"

The output confirmed the underlying ODM heritage:

Terminal
package:com.amazon.amazonvideo.livingroom
package:com.google.android.videos
package:com.oem.qa
package:com.sdt.mecoolrcupair
package:com.oemservice

The 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:

Terminal
adb shell "pm path com.oemservice"
Terminal
package:/system/priv-app/app_xcpe_preset/app_xcpe_preset.apk

The 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:

Terminal
adb shell "dumpsys package com.oemservice | grep -E 'enabled|flags'"
adb shell "pm list packages -d"

The response was surprising:

Terminal
User 0: ... enabled=3
---
package:com.next.iptv
package:com.sdt.producttest
package:com.android.tv.feedbackconsent
package:com.oem.qa
package:com.jettv.player
package:com.google.android.feedback
package:com.android.printspooler
package:com.next.roket
package:com.oemservice

The 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:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
00K00KMIT

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.oemservice
  • com.oem.qa
  • com.sdt.producttest
  • com.next.roket
  • com.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:

  1. OEM Backup Managers: Vendor helper services that silently reinstall bundled OEM apps.
  2. 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 /system and potentially resurrect the disabled packages.

I ran a quick process check to identify remaining vendor background daemons:

Terminal
adb shell "ps -A | grep -i sdt"
Terminal
system 1383 394 1337252 20012 0 0 S com.sdt.backupappmanger
u0_a29 3447 394 1338468 22780 0 0 S com.sdt.ota

To eliminate both risks, I froze the OEM backup manager and the OTA updater daemon:

Terminal
# Stop OEM re-installer
adb shell "pm disable-user --user 0 com.sdt.backupappmanger"
adb shell "am force-stop com.sdt.backupappmanger"
# Stop silent OTA firmware flashing
adb shell "pm disable-user --user 0 com.sdt.ota"
adb shell "am force-stop com.sdt.ota"
# Re-affirm Google Play Protect verifier
adb 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:

OPNsense Shell
pfctl -t tvbox_hosts -T show
OPNsense Shell
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:7e1b

The 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:

OPNsense Firewall Rules
# 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 ports
pass in quick on igb0 proto { tcp, udp } from <tvbox_hosts> to any port { 80, 443, 123, 5228:5230 }
# Rule 3: Reject everything else
block return in quick on igb0 inet46 from <tvbox_hosts> to any

A quick verification test via ADB confirmed the rule behavior:

Terminal
# 1. Local gateway & DNS reachability
adb 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 HTTPS
adb shell "nc -w 2 -W 1 www.google.com 443" # Connected (PASS)
# 3. Outbound Unauthorized High Port / ICMP
adb 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:

  1. 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.
  2. 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.
  3. 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.