
Analysis and cleanup guide for BadBox malware on Allwinner H713 Android projectors: ADB access, infection proof, firmware backup, dropper removal, and verification.
Sep 26, 2026 · @R
A cheap Android projector (Wielo / Atongmu AT-M269, Allwinner H713) ships with a system-level dropper that turns it into a residential proxy node. This doc shows how to get in without opening the case, prove the infection, back up the firmware, remove the malware and verify the result.
No-name LCD projector sold under changing brands. The board and firmware are shared across many H713 projectors (HY300 clones and others), so everything here applies more widely.
| Property | Value |
|---|---|
| Sold as | Wielo Smart Projector, model AT-M269 (FCC ID 2BAAR-AT-M269D) |
| Manufacturer | Shenzhen Atongmu Technology; firmware and apps from OEM "ASHD" |
| Hardware revision | persist.sys.cm.hardversion = AT-M269_720P_HP_202410221430 |
| SoC | Allwinner H713M (ro.boot.hardware = sun50iw12p1), quad Cortex-A53; board exdroid, platform ares |
| RAM / storage | 1 GB DDR @ 576 MHz / 8 GB eMMC (7,818,182,656 bytes) |
| Wi-Fi / Bluetooth | AIC8800 (aic8800d80, driver rwnx 6.4.3.0) |
| Kernel | Linux 5.4.99, 32-bit (armv7l), built 8 Dec 2025 |
| Real build | h713m_tuna_p3-user 11 RP1A.201005.006 eng.work3.20251208.154308 release-keys, firmware H713M-android11-v1.0, build host ishang-PC |
| OS | Android 11 (SDK 30), user build, security patch 2022-02-05 |
| Disguise | Reports itself as Google ADT-3 (brand/model/device, manufacturer askey); real model in ro.product.model2 = AT-M269 |
| Partitions / boot | Virtual A/B, active slot _b, dynamic partitions (retrofit) in super; AVB 2.0, vbmeta.device_state = locked, verifiedbootstate empty; OEM unlock not allowed; /system 100% full |
| Security | ro.debuggable=1, ro.adb.secure=0, service.adb.root=1, ADB on tcp/5868, SELinux permissive, privapp permissions permissive, AOSP test keys |
| Region defaults | Timezone Asia/Shanghai, DTV area cn / DTMB |
# Read the identity yourself
adb shell getprop ro.product.model # ADT-3 <- spoofed, to pass Google certification
adb shell getprop ro.product.model2 # AT-M269 <- real model
adb shell getprop ro.board.platform # ares, H713 platform name
adb shell getprop ro.build.type # user <- release build
ADB is listening on the network, on a non-standard port, with no authorisation prompt and root rights.
# 1. Find open ports (projector on an isolated network)
nmap -p- 10.56.215.10
# 5868/tcp open <- nmap guesses "diameters"; it is actually adbd
# 2. Confirm from the device side (e.g. via Termux on the projector)
getprop service.adb.tcp.port # 5868
getprop ro.adb.secure # 0 -> no "allow debugging?" prompt
getprop init.svc.adbd # running
# 3. Connect from a computer
adb connect 10.56.215.10:5868
adb root
adb shell id # uid=0(root)
adb shell 'echo adb_keepalive > /sys/power/wake_lock' # keep CPU/Wi-Fi awake (needs root adbd)
adb shell cat /sys/power/wake_lock # adb_keepalive must be listed
adb shell input keyevent KEYCODE_SLEEP # display + lamp off, ADB stays connected
# when done
adb shell input keyevent KEYCODE_WAKEUP # lamp on
adb shell 'echo adb_keepalive > /sys/power/wake_unlock' # release the wakelock
/sys/class/backlight/tv > brightness/bl_power have no effect.
Two preinstalled system apps run as the system user (UID 1000). One downloads a loader, loader downloads four proxy modules and a second, independent loader.
Firmware (preinstalled, UID 1000)
├─ com.android.sysapp /system/priv-app/AshdSysApp
│ OTA updater, can replace the whole firmware (update.zip / payload.bin)
│ C2: wjtysj.ishanghd.com/hx_kt.php
│
└─ com.android.umanalytics.yiyou /system/app/AndroidAnalytics_yiyou
Dropper; Umeng + Baidu tracking
└─ downloads cache/plugin.jar (DEX, from *.ishanghd.com)
├─ app installer: pulls app lists per device profile, pm install -r
│ └─ installs Disney+ etc. and com.google.adtest (payload)
└─ "hs" task loader, C2 api.loritor.cc / api.nizero.cc, every 6 h
└─ 4 encrypted modules code_cache/.hs/.file/.rf/*.rf
SKN0041 com.ad.proxy SKN0054 com.szns.sdk
SKN0058 com.link.core SKN0061 ddth2 (VpsSdk)
-> all four: residential proxy clients
com.google.adtest (/data/app, installed by yiyou)
Second loader "com.speed", own C2 (api.logobi.cc, api.pechlo.cc, ...)
Native plugin loader, may install/delete packages -> backup channel
> strangers' internet traffic routed through your connection, and your device is tracked (serial, MACs, Wi-Fi SSID/BSSID).
adb shell "netstat -tnp | grep ESTABLISHED"
# tcp6 ... ::ffff:43.116.39.73:188 ESTABLISHED 4795/com.android.umanalytics.yiyou
# tcp6 ... ::ffff:198.44.189.x:9200 ESTABLISHED 4795/com.android.umanalytics.yiyou
# ... ~25 lines, same process, many IPs, odd ports
# -> an "analytics" app does not hold 25 parallel sessions: this is a proxy node
adb shell pm list packages -i | grep -v 'installer=null\|com.android.vending'
# package:com.google.adtest installer=com.android.umanalytics.yiyou <- payload
# package:com.disney.disneyplus installer=com.android.umanalytics.yiyou <- cover
# -> a system "analytics" app installing packages = dropper
adb shell dumpsys package com.google.adtest | grep -E 'codePath|firstInstallTime'
# fake Google name, lives in /data/app, installed silently
adb shell 'ls -laR /data/data/com.android.umanalytics.yiyou' | grep -E 'plugin.jar|\.rf|files/apps'
# cache/plugin.jar <- downloaded loader (DEX)
# code_cache/.hs/.file/.rf/-1.dex_assdk_huang_*SKN00xx*.rf <- 4 encrypted modules
# files/apps/com.google.adtest.apk <- stored payload for reinstall
# directories are chmod 777