Desinfektionsversuch der Badbox Malware von der von AliExpress gekauften TV-Box H20 (RK3228a CPU und Mali-400MP2 GPU)

Weblog vom 29.01.2025: Desinfektionsversuch der Badbox Malware von der von AliExpress gekauften TV-Box H20 (RK3228a CPU und Mali-400MP2 GPU)
Kategorie:IT Security
Stichworte:Internet, Router, Station, TVBox, Hongtop, Hongxin, Shenzhen, AliExpress, China, H20, H20 pro, Malware, BadBox, Firmware, Vodafone, BSI, Firmware, SmartTV, Android, ADB, Analyse, File-Analyse, DNS, dcylog.com, ycxrl.com, Entfernung, Bereinigung, Säuberung, Desinfektion, HLauncher


Die Story beginnt damit, dass ich mir zwei Android-TV-Boxen auf AliExpress gekauft habe und dann irgendwann eine Warn-e-mail von meinem Provider Vodafone reinkam, der mir mitteilte, dass irgendwas bei mir mit der Badbox-Malware infiziert sei und Schindluder im Internet treibe.

Das musste ich mir genauer anschauen. Zuerst analysierte ich das Android der beiden Boxen, ob irgendwas verdächtig ist und fand schon ein paar Apps, die mir nicht ganz koscher vorkamen.

Also guckte ich mir auch die Internet-Kommunikation für die H20 Box mit Rockchip RK3228a CPU (32bit Quad Core) mit einer Mali-400MP2 GPU an. Und dann später auch für die zweite, leistungsfähigere Box, nämlich die H20pro mit Allwinner 616-Chipsatz und G31 Mali-Chipsatz, beide gekauft im Topsion Store über AliExpress. Und auch auf der zweiten Box fand ich die Malware vor.

Nun will ich alle vorhergehenden Analysen in einen Topf werfen und versuchen, die Malware von den Geräten zu entfernen, so dass sie keinen Schaden mehr anrichten und können und ich sie weiter verwenden kann. Anfangen werde ich in diesem Artikel mit der H20 (ohne Pro).

Außerdem will ich möglichst den Firmware-Updater, also das Programm, das die Firmware der TV-Boxen aktualisiert, deaktivieren, damit die Boxen keine Chancen erhalten, sich neue Schadsoftware per Firmware-Update herunterzuladen und neu zu infizieren.

Erste Maßnahme: Verbindung zu den C&C-Domains kappen

Als erste Maßnahme hatte ich ja bereits die Domains dcylog.com bzw. ycxrl.com, über die die Boxen Verbindung zum Command-and-Control-Server aufnehmen wollen, bei mir im DNS-Server Pi-Hole umgeleitet, so dass sie nicht mehr ins Internet kommen.

Andere, ähnliche TV-Boxen mit Namen wie T95 (Max/Pro), X12 (Plus), X88 (Pro), G96 (Max), H96 (Max), X96q, MXQ (pro), 4K, 6K, 8K oder ähnlich, die auch mit der Badbox Malware infiziert sind, verwenden andere Domains. Folgende Command-and-Control-Server-Domains konnte ich anhand der Quellen unten zusammentragen:

6f33933ce4a5c0e1b32fea736a61351a.com bitemores.com bluefish.work cast.jutux.work catmos99.com cbphe.com cbpheback.com coslogdydy.in cxlcyy.com cxzyr.com dcylog.com echojoy.xyz flyermobi.com giddy.cc goologer.com home.1ztop.work huuww.com jolted.vip jutux.work logcer.com meiboot.com msohu.shop mtcpmpm.com old.1ztop.work pccyy.com pcxrl.com pcxrlback.com pixelscast.com pixlo.cc soyatea.online swiftcode.work tvsnapp.com veezy.sitev ycxad.com ycxrl.com ycxrldow.com yydsmr.com ztword.com

Damit auch keine (evtl. schädlichen) Firmware-Updates mehr möglich sind, leite ich auch die Domains ota.szhxws.com und www.szhxws.com um. Die erste scheint für Firmware-Updates zuständig zu sein. Bei der zweiten telefoniert die Box wohl einfach nur für statistische Zwecke nach Hause. Beides wird durch die Domain-Umleitung durch Local DNS / DNS Records - Einträge in meinem Pi-Hole unterbunden. http://ota.szhxws.com/ott/dev/plugin_conf.xml <plugins> <plugin id="ad"> <status>0</status> </plugin> <plugin id="dyncli"> <status>0</status> </plugin> <plugin id="sdkv35"> <status>1</status> </plugin> </plugins>
Wer keinen eigenen DNS-Server wie Pi-Hole laufen hat, kann auch direkt auf der Box die Verbindungen zu den verdächtigen Domains unterbinden, indem er sie in /etc/host einträgt, was sogar noch sicherer ist und auch funktioniert, falls der eigene DNS-Server mal ausfällt:
/etc/hosts 127.0.0.1 dcylog.com 127.0.0.1 ycxrl.com 127.0.0.1 ota.szhxws.com 127.0.0.1 www.szhxws.com 127.0.0.1 szhxws.com
Und wer den Internet-Verkehr weiter beobachten will und zu einem eigenen Webserver umleiten will, kann als IPs die des eigenen Webservers benutzen. So konnte ich den relativ früh nach dem Systemstart stattfindenden Request zu wahrscheinlich ota.szhxws.com mit protokollieren, wo PCAPdroid und Wireshark noch nicht aktiv sind:
2025-01-28 08:47:18 10.10.10.4 HEAD /OtaUpdater/android product=H20&version=202309281601&sn=6UKR5FYF1W&country=DE&language=de 80 - 10.10.10.202 rk29sdk/4.0 - 404 0 2 274
Wie schon von mir vermutet, wird hier die exakte Version der TV-Box und sogar dessen Seriennummer übermittelt, um dann ggf. die richtige Firmware für ein etwaiges Update für den Download bereitzustellen.

Warnung: Mit den falschen ADB-Befehlen oder falls man die falschen Apps deinstalliert, kann man seine TV-Box durchaus bricken, sprich unbrauchbar machen, so dass sie nicht mehr läuft. Also seid vorsichtig und lest alles genau durch und tut nur Dinge, von denen ihr wisst, dass sie die richtigen sind. Ich übernehme keine Haftung, für rein gar nichts.
Falls eure TV-Box nicht mehr startet, hilft eventuell ein Hardware-Reset: Bei den H20 und H20pro (und ähnlichen) Boxen befindet sich der Reset-Taster hinten in der Klinkenbuchse (kein Scherz!) und muss mit einem Zahnstocher oder etwas anderem, nicht elektrisch leitendem, gehalten werden, während man das Stromkabel einsteckt. Video dazu unter https://youtu.be/kIPIU03FjYE. Bei meiner H20pro kam dann leider aber kein Wiederherstellungsmenü, sondern der Bildschirm blieb schwarz, nur die LED wurde rot.
Bei anderen, mit Badbox infizierten Boxen (von denen es reichlich gibt, siehe erster Artikel der Reihe) sollte die Dekontaminierung ganz ähnlich verlaufen. Die C&C-Domains kann man mit Pi-Hole oder PCAPdroid herausfinden (siehe dazu dritter Artikel der Reihe. Die Malware-Apps werden sich unterscheiden, das Prinzip ist aber das Gleiche. Bei anderen Boxen als der H20 und H20pro muss man natürlich noch mehr Umsicht walten lassen.
Wie gesagt: Alles hier auf eigenes Risiko!

Die Datei /etc/hosts kann man über ADB editieren. Wie man ADB unter Windows installiert, erklärt mein Artikel über den ADB-Zugriff auf ein Xiaomi-Redmi-Android-Smartphone. Auch die Android TV-Box ist ein Android-Gerät und da läuft es genauso. Die Befehle, die in dem Artikel nach "ADB-Shell aufrufen und Befehle eingeben" folgen, lasst ihr für diesen Fall natürlich weg, die betreffen nur das im Artikel besprochene Speicherkarten-Problem dort.

Stattdessen müssen wir folgende Befehle eingeben:
11:15:03.43 C:\ >> adb root adbd is already running as root 11:21:51.76 C:\ >> adb remount remount succeeded
Das ist wichtig, da man ansonsten auf die /etc/hosts nicht zugreifen kann und stattdessen den Fehler /system/bin/sh: can't create /etc/hosts: Read-only file system bekommt.

Nach diesen Vorbereitungen geht es weiter in der ADB Shell, also direkt auf der TV-Box. Schauen wir erst einmal, was in der /etc/hosts so drin steht und machen eine Sicherheitskopie:
11:15:08.96 C:\ >> adb shell H20:/ # cat /etc/hosts 127.0.0.1 localhost ::1 ip6-localhost H20:/ # cp /etc/hosts /etc/hosts.bak
Danach können wir mittels des cat-Befehls und des >>-Operators Zeilen an unsere /etc/hosts anhängen. Einen Editor wie Nano oder Vim wird man vergeblich auf der Box suchen, die ist speicherplatzoptimiert und hat keine für den Betrieb unnötige Programme installiert:
H20:/ # cat >>/etc/hosts eintippen oder Copy und paste einfügen: 127.0.0.1 dcylog.com 127.0.0.1 ycxrl.com 127.0.0.1 ota.szhxws.com 127.0.0.1 www.szhxws.com 127.0.0.1 szhxws.com dann CTRL+Z und CTRL+D drücken, damit man wieder rauskommt.
Dann nochmal zur Sicherheit das Ergebnis anschauen, ob das so passt, ansonsten muss man halt mit cp /etc/hosts.bak /etc/hosts die Sicherheitskopie wiederherstellen und es noch einmal versuchen.
H20:/ # cat /etc/hosts 127.0.0.1 localhost ::1 ip6-localhost 127.0.0.1 dcylog.com 127.0.0.1 ycxrl.com 127.0.0.1 ota.szhxws.com 127.0.0.1 www.szhxws.com 127.0.0.1 szhxws.com
Passt. Jetzt sollte man zur Sicherheit die Box neu starten und schauen, ob die Einträge alle noch vorhanden sind. Gut. Ab sofort werden alle (mir für die H20 Box bekannte vermeintlich) schädlichen Domainabfragen auf die Box selbst umgeleitet. Das heißt: Das Ganze ist ja dann auf der Box selbst gespeichert und nicht mehr von einem laufenden, umleitenden DNS-Server abhängig, was bedeutet, dass man die Box auch zu einem Freund mitnehmen kann, der keinen eigenen DNS-Server laufen hat.

Zweiter Schritt: eine Ersatz-Launcher-App besorgen

Auf anderen TV-Boxen, die Sicherheitsforscher untersucht haben, versteckte sich die Schadsoftware oft im Launcher. Der Launcher ist das Stück Software, das nach dem Hochfahren angezeigt wird, um darin die Apps auszuwählen, die man starten will - darum ja auch "Launcher", englisch für "Starter". Der sieht im Original so aus:



Der muss auf jeden Fall vom Gerät runter. Das Problem ist nur, ohne Launcher kann man keine Apps mehr starten! Also muss vorher, also bevor wir den wohl infizierten Original-Launcher vom Gerät löschen, ein Alternativ-Launcher installiert werden. Davon gibt es einige im Google Play Store zu finden, von dem man sich im Prinzip einen aussuchen kann, der einem gefällt. Aber Bei der Bedienung daran denken, dass der Wunschkandidat auf einer TV-Box mit Fernbedienung und nicht auf einem Smartphone mit Touch laufen soll.

Ich habe mir den Simple TV Launcher ausgesucht. Der ist schön schlank und schnell ohne unnötigen Schnick-Schnack und ich finde sehr gut bedienbar mit den Pfeiltasten auf der Fernbedienung. Ich will nicht mit der Maus-Emulation rummachen, wenn ich nur eine App starten will. Das sieht dann so aus und ich habe alles, was ich brauche:




Ich kann mir einstellen, wieviele Zeilen und Spalten ich haben möchte und habe dann dementsprechend viele Felder, die ich mit installierten Apps belegen kann.

Die kann ich nach einem OK-Klick auf ein leeres Feld (+) aus der Liste der installierten Apps auswählen.

Und wenn ich mehr Programme brauche, passe ich einfach die Anzahl der Felder an. Easy-Peasy und genug für mich. Super-Bunt fällt allerdings aus. Brauche ich aber auch nicht.

Wichtig ist, dass der Launcher vorher einmal aktiv war, also der Auswahl-Dialog angezeigt wird, indem gefragt wird, ob man den ersten, vorinstallierten oder den zweiten, alternativen Launcher benutzen möchte.

Ab da an kennt Android den Launcher und nimmt automatisch den Zweiten, wenn der Erste gelöscht wurde.

Dritter Schritt: verdächtige Apps deaktivieren oder deinstallieren

Jetzt heißt die Devise: Vorsichtig sein und Geduld haben.

Vorsichtig deshalb, weil wir nicht die falschen System-Apps entfernen wollen, die dann vielleicht fehlen, damit das System auf der TV-Box startet und korrekt läuft.

Geduldig deshalb, weil wir uns eine nach der anderen, verdächtigen App vornehmen und dann überprüfen, ob die Zugriffe auf die Domains dcylog.com bzw. ycxrl.com und ota.szhxws.com sowie www.szhxws.com aufhören. Die ersten beiden sind für die Malware, die beiden letzten für Systemupdate und Nachhause-Telefonieren.

Ob die DNS und HTTP-Abfragen noch aktiv sind, können wir mit PCAPdroid, Firewall ohne Root oder dergleichen direkt auf dem Android-Gerät sehen, siehe dazu die vorhergehenden Artikel der Reihe. Oder wir leiten doch noch einmal den Internetverkehr für die Domains auf eine eigene IP mit einem Webserver um, dessen Logfiles wir dann beobachten.


Dann checken wir eine verdächtige App nach der anderen unter Einstellungen / Apps / System-Apps aus. Die zweite Zeile kann dabei wertvolle Zusatzinformation liefern. Für das HX[chin.] zum Beispiel, dass die App wohl vom Hersteller (SZHXWS oder kurz HX) kommt und angeblich was für den Gerätetest enthält. Eventuell haben wir auch einen "Öffnen"-Button und können die App starten, um zu sehen, was es ist. Soweit möglich erfolgt die Überprüfung in der Reihenfolge: Nach dem Beenden schauen wir, ob die Zugriffe noch stattfinden. Wenn sie aufgehört haben, dann haben wir einen Bad Boy gefunden, entweder für Malware oder Update. Je nachdem, wie der Intervall der Zugriffe ist, müssen wir nach jedem Schritt bis zu 15 Minuten oder vielleicht auch länger warten. Gehen die Zugriffe nach dem Beenden weiter, können wir noch Deaktivieren versuchen. Und wieder beobachten.

Danach sollten wir eine Liste haben der Apps, bei denen der Zugriff aufgehört hat. Diese Bad Boys werden jetzt alle deaktiviert und geschaut, ob die Box noch läuft. Danach starten wir die TV Box neu und schauen, ob unsere Kandidaten, die auf deaktiviert waren, immer noch deaktiviert sind. Ansonsten müssen auch diese, wie die Bad Boys, die sich nicht deaktivieren ließen, per ADB deinstalliert werden. Wohlgemerkt nur die, bei denen nachgewiesen der Zugriff aufgehört hat.

Wir sollten dann eine Hand voll Apps habe, die wir für "böse" halten, und die wir mit ADB deinstallieren. Das ist nicht ungefährlich und die Box kann schnell mal nicht mehr hochfahren, wenn die falsche System-App gelöscht werden. Ich hatte euch oben ja schon gewarnt. Also bitte: vorsichtig vorgehen.

Desinfektion der H20 Badbox mit Rockchip RK3228a CPU und Mali-400MP2 GPU



Ganz oben auf der Liste der verdächtigen Kandidaten steht bei mir die HLauncher-App (com.hx.mboxlauncher).

Nur leider kommen wir der mit normalen Android-Bordmitteln (Einstellungen / Apps) nicht bei. Hier gibt es weder ein "Beenden erzwingen", "Deaktivieren" oder "Deinstallieren".

Wir müssen also doch wieder ADB bemühen. Zuerst lassen wir uns alle installierten Packages ausgeben und da besonders die, die "hx" im Namen haben:
12:50:45.48 C:\ >> adb shell pm list packages | grep -i hx package:com.hx.guardservice package:com.hx.devicemonitor package:com.hx.update package:com.hx.appcleaner package:com.hx.rcs package:com.hx.mboxlauncher package:com.hxdevicetest package:com.hx.videotest
Da ist ja auch unser Hauptverdächtiger: com.hx.mboxlauncher. Die Box idlet im neuen Launcher und ich habe die Zugriffe der Box auf die bad Domains umgeleitet auf meinen eigenen Webserver, um das Beobachten und schnell auswerten zu können:
13:42:56.02 C:\ >> grep 10.10.10.202 C:\inetpub\logs\LogFiles\W3SVC1\u_ex250127.log | grep /terminal/ 2025-01-27 11:01:43 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 56 2025-01-27 11:06:43 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 12 2025-01-27 11:11:43 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 10 2025-01-27 11:16:44 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-27 11:21:44 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-27 11:26:44 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-27 11:31:44 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 9 2025-01-27 11:36:45 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 13 2025-01-27 11:41:45 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 9 2025-01-27 11:51:45 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 9 2025-01-27 11:56:45 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 9 2025-01-27 12:06:46 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 9 2025-01-27 12:11:46 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 10 2025-01-27 12:26:47 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-27 12:31:47 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-27 12:36:47 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 7
Schön alle 5 bis 15 Minuten versucht die H20 Badbox mit dem C&C-Server zu kommunizieren. Mal schauen, was passiert, wenn wir die App com.hx.mboxlauncher zwangsweise beenden. Wenn dies unser böser Bube ist, sollten die Abfrage aufhören.
13:42:37.09 C:\ >> adb shell am force-stop com.hx.mboxlauncher

Das hat leider nichts gebracht. Es erfolgte ein weiterer Zugriff um 12:46:48 UTC, also nach 10 Minuten. Nichtsdestotrotz deaktiviere ich die App, damit sie nicht neu gestartet wird: 12:58:35.24 C:\ >> adb shell pm disable com.hx.mboxlauncher Package com.hx.mboxlauncher new state: disabled Sofort verschwindet der Eintrag HLauncher aus der Liste der Apps.

Damit ändert sich jetzt allerdings nichts. Das verhindert nur, dass die App beim nächsten Systemstart wieder gestartet wird. Weitere Zugriffe zeigen, dass die Box immer noch versucht, den C&C-Server zu erreichen.

Aber vielleicht ist die HLauncher-App ja auch nicht (allein) für die Zugriffe verantwortlich. Das wissen wir zu diesem Zeitpunkt noch nicht genau.


Also muss sich die Malware woanders (oder auch zusätzlich woanders) verstecken. Geben wir uns doch mal eine Liste der laufenden Prozesse aus, die HX im Namen tragen:
14:01:57.55 C:\ >> adb shell ps | grep -i hx system 953 184 969164 34856 ep_poll b4cb61a8 S com.hxdevicetest system 961 184 967572 33100 ep_poll b4cb61a8 S com.hx.videotest system 7396 184 969632 36572 ep_poll b4cb61a8 S com.hx.devicemonitor system 9592 184 968652 32804 ep_poll b4cb61a8 S com.hx.appcleaner
und beenden wir diese - eine nach dem anderen - und beobachten dabei, ob die TV-Box normal weiterläuft... Fangen wir mit com.hx.appcleaner an:
14:04:38.86 C:\ >> adb shell kill 9592 14:04:39.97 C:\ >> adb shell ps | grep -i hx system 953 184 969164 34856 ep_poll b4cb61a8 S com.hxdevicetest system 961 184 967572 33100 ep_poll b4cb61a8 S com.hx.videotest system 7396 184 969632 36572 ep_poll b4cb61a8 S com.hx.devicemonitor system 9698 184 968652 32716 ep_poll b4cb61a8 S com.hx.appcleaner
So wie es ausieht, startet ein übergeordneter Prozess com.hx.appcleaner gleich wieder. Vielleicht hilft "Beenden erzwingen"...
14:04:53.19 C:\ >> adb shell am force-stop com.hx.appcleaner 14:04:56.02 C:\ >> adb shell ps | grep -i hx system 953 184 969164 34856 ep_poll b4cb61a8 S com.hxdevicetest system 961 184 967572 33100 ep_poll b4cb61a8 S com.hx.videotest system 7396 184 969632 36572 ep_poll b4cb61a8 S com.hx.devicemonitor system 9698 184 968652 32804 ep_poll b4cb61a8 S com.hx.appcleaner
Nein, das war auch nichts. Und wenn wir die App deaktivieren?
14:04:52.64 C:\ >> adb shell pm disable com.hx.appcleaner Package com.hx.appcleaner new state: disabled 14:06:32.73 C:\ >> adb shell ps | grep -i hx system 953 184 969164 34856 ep_poll b4cb61a8 S com.hxdevicetest system 961 184 967572 33100 ep_poll b4cb61a8 S com.hx.videotest system 7396 184 969632 36572 ep_poll b4cb61a8 S com.hx.devicemonitor system 9698 184 968652 32716 ep_poll b4cb61a8 S com.hx.appcleaner 14:06:44.20 C:\ >> adb shell kill 9698 14:06:56.14 C:\ >> adb shell ps | grep -i hx system 953 184 969164 34856 ep_poll b4cb61a8 S com.hxdevicetest system 961 184 967572 33100 ep_poll b4cb61a8 S com.hx.videotest system 7396 184 969632 36572 ep_poll b4cb61a8 S com.hx.devicemonitor system 9769 184 968652 32808 ep_poll b4cb61a8 S com.hx.appcleaner
Nein, das funktioniert auch nicht.

Vielleicht, wenn wir die verdächtigen Kandidaten deaktivieren und die Box neu starten. Wir hatten oben ja schon eine Liste mit HX-Apps ausgeben lassen. Versuchen wir es damit:
14:16:11.17 C:\ >> adb shell pm disable com.hx.guardservice Package com.hx.guardservice new state: disabled 14:16:30.58 C:\ >> adb shell pm disable com.hx.devicemonitor Package com.hx.devicemonitor new state: disabled 14:16:42.91 C:\ >> adb shell pm disable com.hx.update Package com.hx.update new state: disabled 14:16:53.05 C:\ >> adb shell pm disable com.hx.appcleaner Package com.hx.appcleaner new state: disabled 14:17:27.58 C:\ >> adb shell pm disable com.hxdevicetest Package com.hxdevicetest new state: disabled 14:17:45.72 C:\ >> adb shell pm disable com.hx.videotest Package com.hx.videotest new state: disabled 14:17:58.26 C:\ >> adb shell pm disable com.hx.rcs Package com.hx.rcs new state: disabled
Und starten dann die Box neu. Diese fährt auch einwandfrei hoch, doch wir sehen, das lediglich das Package com.hx.devicemonitor nicht mehr in den Prozessen auftaucht. Der Rest wurde beim Hochfahren der Box wieder automatisch gestartet:
14:19:13.21 C:\ >> adb shell ps | grep -i hx system 918 183 968652 32652 ep_poll b36e21a8 S com.hx.appcleaner system 951 183 969036 32720 ep_poll b36e21a8 S com.hxdevicetest system 961 183 967572 33136 ep_poll b36e21a8 S com.hx.videotest
Leider taucht dann doch wieder ein POST-Aufruf um 13:32 UTC auf, 25 Minuten nach dem letzten.

Ich muss also schwerere Geschütze auffahren und die Apps komplett deinstallieren. Allerdings benutze ich hier die Option "-k", um Cache und Daten der App zu behalten und deinstalliere mittels "--user 0" nur für den aktuellen User. Das löscht die App nicht komplett vom System, so dass ich sie bei einem versehentlichen Deinstallieren aus /system/priv-app bzw. /system/app wiederherstellen kann. Da sind alle nicht zum Android-Kern-System gehörigen APK-Dateien zuhause:
H20:/ # ls /system/priv-app/ BackupRestoreConfirmation DownloadProvider GooglePartnerSetup Phonesky SystemUI BugReport ExternalStorageProvider GoogleServicesFramework ProxyHandler TvProvider CalendarProvider FusedLocation HLauncher RemoteService TvSettings ChangeLedStatus GmsCore HXDeviceMonitor Settings VideoTest ConfigUpdater GoogleBackupTransport HXDeviceTest_v2 SettingsProvider VideoTestGuard ContactsProvider GoogleExtServices InputDevices SharedStorageBackup VpnDialogs CtsShimPrivPrebuilt GoogleFeedback MediaCenter Shell DefaultContainerService GoogleLoginService MediaProvider StatementService DocumentsUI GoogleOneTimeInitializer PackageInstaller StressTest H20:/ # ls /system/app/ AppCleaner CtsShimPrebuilt HTMLViewer PinyinIME WallpaperBackup BasicDreams DownloadProviderUi KeyChain PrintSpooler WebViewGoogle Bluetooth ExactCalculator LatinIME RKDeviceTest WifiDisplay CaptivePortalLogin Gallery LiveWallpapersPicker RKUpdateService CertInstaller GoogleCalendarSyncAdapter Music RkExplorer Chrome GoogleContactsSyncAdapter PacProcessor SystemUpdate Clean GoogleExtShared PicoTts UserDictionaryProvider
Wenn man möchte, kann man sich auch vorher eine Sicherheitskopie der dort liegenden APKs machen:
14:48:41.65 d:\TEMP\h20-priv-app >> adb pull /system/priv-app /system/priv-app/: 72 files pulled, 0 skipped. 14.3 MB/s (414208372 bytes in 27.636s) 14:54:36.90 d:\TEMP\app >> adb pull /system/app /system/app/: 63 files pulled, 0 skipped. 14.0 MB/s (241383531 bytes in 16.404s)
Wiederherstellen der App, falls nötig, würde über die ADB funktionieren über den Befehl adb shell pm install -r --user 0 /system/priv-app/HLauncher/HLauncher.apk. Trotzdem die Warnung, nicht zu viel zu deinstallieren. Wenn die Box gar nicht mehr hochfährt, so dass ADB nicht mehr funktioniert, hat man verloren.

14:57:17.23 C:\ >> adb shell pm uninstall -k --user 0 com.hx.mboxlauncher Success Seltsamerweise taucht die HLauncher-App direkt nach dem Uninstall-Befehl mit 0 Bytes (0 B) in der App-Liste wieder auf. Und auch nach dem Neustart der Box bleibt dieser Eintrag in der App-Liste bestehen.

Während ich auf einen eventuellen Neueintrag eines POST-Requests im Log warte, schicke ich die APKs durch VirusTotal.



Es gibt folgende Auffälligkeiten, die aber wohl False Positives sind, weil sie nur von einem Scan-Provider gefunden werden. HLauncher selbst ist laut VirusTotal sauber.

Score APK Scanner Virus / Malware Hash APK
1/55 ChangeLedStatus.apk Babable PUP.HighConfidence c3bd761d64a1cf6ddb168d71dfabda8d490e9fde7a2b715f4e178f8a24b8ef8f
1/66 GoogleLoginService.apk VirIT EICAR-Test-File 77cfd23b01c8b3c42b5b429233baa9eedecf480c8b15495f1e3843546b193f4d
1/63 Phonesky.apk MaxSecure Android.Android.WIN32.SpyNote.e d1ea5f95e85d1bb1674de05431d6298f6cc6d1ab69c7aa4d5d03d748f647b786
1/67 RemoteService.apk Symantec Mobile Insight AdLibrary:Generisk 4a912238b4d51e131992967e2a763629fba76956a9238316186d551a26fe6a8e

Leider gibt es Neueinträge im Weblog, sprich die Box versucht immer noch Verbindung zum Command-and-Control-Server aufzunehmen.

HLauncher ist es wohl nicht. Welche App14:04: dann?

Es ist gar nicht einfach herauszufinden, welche App denn nun die Request an die Bad Domains absetzt. Die in meinem Fall an 10.10.10.4 umgeleitet werden. In den Android-Apps erscheint nur "Android", in PCAPdroid ebenfalls. Das Abhören über die Android-Erweiterung von Wireshark liefert gar keine App.

Da fällt mir nur netstat ein, dass auch den Process anzeigen kann, der die Verbindung initiiert hat. Also führe ich wiederholt
10:56:03.34 d:\TEMP >> adb shell netstat -t -n -p -a -W -e
aus und schaue, wer denn was an 10.10.10.4, meinen Webserver, geschickt hat.
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program Name tcp 4328 0 ::ffff:10.10.10.202:54298 ::ffff:10.10.10.4:80 ESTABLISHED 1000 61125 550/system_server
Die Zeit passt mit dem Logfile-Eintrag des Webservers zusammen, in dem der POST /terminal/client/register Zugriff verzeichnet ist. Wir haben also gefunden, wer dahinter steckt: Es war der Prozess "system_server" mit der ID 550. Das bringt uns allerdings nicht weiter, denn das ist ein allgemeiner Prozess, der beim Booten gestartet wird und dann allerlei Services verwaltet. Er gehört also zum Kernsystem und gibt uns leider keine Information darüber, welche App denn nun die böse ist.

Den SystemServer-Prozess selbst dürfen wir natürlich nicht deinstallieren, sonst würde das System gar nicht mehr laufen. Welche SystemServer als Strohmann benutzt, bleibt im Dunkeln.

Eine App nach der anderen deinstallieren

Als letzte Strategie bleibt nur, auf gut Glück eine App nach der anderen zu deinstallieren, das System neu zu starten und zu schauen, ob es a) noch hochfährt und b) die Zugriffe noch stattfinden. Spätestens jetzt sollte man sich ein Priv-App und App-Backup, wie oben gezeigt, lokal auf dem PC anlegen.
11:37:44.37 d:\TEMP >> adb shell ps | grep -i hx system 932 184 968652 32672 ep_poll b23fc1a8 S com.hx.appcleaner system 960 184 969036 32728 ep_poll b23fc1a8 S com.hxdevicetest system 976 184 967572 33092 ep_poll b23fc1a8 S com.hx.videotest 11:37:56.97 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hx.appcleaner Success 11:38:28.10 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hxdevicetest Success 11:38:40.28 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hx.videotest Success 11:38:52.31 d:\TEMP >> adb shell reboot

Daran denken: Nach jedem Neustart muss man bei der H20 Box in den Entwickleroptionen die Option "USB settings (Connect to Computer)" eingeschaltet werden, um wieder mittels ADB auf die Box zugreifen zu können.

Den Zugriff auf die Box können wir mit dem Befehl adb devices überprüfen. Danach überprüfen, ob die Prozesse com.hx.appcleaner, com.hxdevicetest und com.hx.videotest auch nicht mehr laufen: 11:40:35.87 d:\TEMP >> adb devices List of devices attached 6UKR5FYF1W device 11:41:32.67 d:\TEMP >> adb shell ps | grep -i hx Die PS-Liste ist leer. Die verdächtigen Prozesse wurden nicht gestartet. Die Box läuft noch. Testen wir eine App, Youtube oder Firefox oder dergleichen. Funktioniert noch. Gut.

Jetzt müssen wir wieder mindestens eine Viertel Stunde warten und unsere Webserver-Logfiles beobachten, ob ein POST /terminal/client/register-Zugriff auftaucht.

Und leider tun sie es. Es ist wirklich ein Geduldsspiel. Also versuchen wir auf Verdacht den nächsten Rutsch, diesmal nehmen wir uns auch den Updater vor, der ich hinter com.hx.update vermute. Dann sollte auch der "HEAD /OtaUpdater/android product=H20..."-Request verschwinden:
11:41:38.22 d:\TEMP >> adb shell pm list packages | grep -i hx package:com.hx.guardservice package:com.hx.devicemonitor package:com.hx.update package:com.hx.rcs 12:15:42.59 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hx.guardservice Success 12:16:10.32 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hx.devicemonitor Success 12:16:25.24 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hx.update Success 12:16:39.63 d:\TEMP >> adb shell pm uninstall -k --user 0 com.hx.rcs Success 12:16:46.57 d:\TEMP >> adb reboot
Nach dem Neustart heißt es wieder warten und hoffen, dass es nicht zuviel war, dass ich deinstalliert habe.

Seltsamerweise werden immer noch neue OTA, also auch Register-Request im Logfile an. Entweder sitzt die Malware noch viel tiefer im System oder es reicht nicht, sie nur für User 0 zu deinstallieren.

Dies kann aber nicht sein, da User 0 der einzige User auf dem System ist:
12:55:14.28 d:\TEMP >> adb shell pm list users Users: UserInfo{0:Eigentümer:13} running
Da die OTA-Zugriffe recht früh, nur ein paar Minuten nach Neustart, auftauchen, nehme ich mir den Update-Service vor, da der eine schnellere Überprüfbarkeit bietet. Ich bin das ständige Warten langsam satt.

Bisher haben wir folgende Packages deinstalliert, die alle HX im Namen hatten. Ein Vergleich zwischen der Auflistung aller Packages exklusive deinstallierter und aller Packages inklusive deinstallierter fördert diese zu Tage:
13:09:30.28 d:\TEMP >> adb shell pm list packages -f -i hx 13:09:55.78 d:\TEMP >> adb shell pm list packages -f -i -u hx package:/system/priv-app/VideoTestGuard/VideoTestGuard.apk=com.hx.guardservice installer=null package:/system/priv-app/HXDeviceMonitor/HXDeviceMonitor.apk=com.hx.devicemonitor installer=null package:/system/app/SystemUpdate/SystemUpdate.apk=com.hx.update installer=null package:/system/app/AppCleaner/AppCleaner.apk=com.hx.appcleaner installer=null package:/system/priv-app/RemoteService/RemoteService.apk=com.hx.rcs installer=null package:/system/priv-app/HLauncher/HLauncher.apk=com.hx.mboxlauncher installer=null package:/system/priv-app/HXDeviceTest_v2/HXDeviceTest_v2.apk=com.hxdevicetest installer=null package:/system/priv-app/VideoTest/VideoTest.apk=com.hx.videotest installer=null
Da das offensichtlich noch nicht gereicht hat, deinstalliere ich noch ein paar verdächtige und meiner Meinung nach eher unnützlicher Packages:
package:/system/app/PinyinIME/PinyinIME.apk=com.android.inputmethod.pinyin installer=null R package:/system/app/RKUpdateService/RKUpdateService.apk=android.rockchip.update.service installer=null package:/system/priv-app/ChangeLedStatus/ChangeLedStatus.apk=com.example.changeled installer=null package:/system/app/Clean/Clean.apk=com.charon.rocketfly installer=null R package:/system/app/RKDeviceTest/RKDeviceTest.apk=com.rockchip.devicetest installer=null R package:/system/app/RkExplorer/RkExplorer.apk=com.android.rockchip installer=null package:/system/priv-app/MediaCenter/MediaCenter.apk=com.rockchips.mediacenter installer=null
13:56:39.89 d:\TEMP >> adb shell pm uninstall -k --user 0 com.android.inputmethod.pinyin Success 13:58:18.48 d:\TEMP >> adb shell pm uninstall -k --user 0 android.rockchip.update.service Success 13:58:29.86 d:\TEMP >> adb shell pm uninstall -k --user 0 com.example.changeled Success 13:58:42.66 d:\TEMP >> adb shell pm uninstall -k --user 0 com.charon.rocketfly Success 13:58:58.31 d:\TEMP >> adb shell pm uninstall -k --user 0 com.rockchip.devicetest Success 13:59:12.96 d:\TEMP >> adb shell pm uninstall -k --user 0 com.android.rockchip Success 13:59:32.77 d:\TEMP >> adb shell pm uninstall -k --user 0 com.rockchips.mediacenter Success
Oops, das war wohl zu viel. Es gibt nach dem Hochfahren keine Internetverbindung mehr und ein Klick auf Einstellungen / Netzwerk friert das System ein bzw. es dauert ewig, bis das System reagiert. Dann scheint der WLAN-Schalter funktionslos. Versuchen wir, das wieder zu reparieren... Welche App könnte zu viel deinstalliert gewesen sein und ist für Netzwerk / WLAN zuständig?
14:13:48.51 d:\TEMP >> adb shell pm install -r --user 0 /system/app/RkExplorer/RkExplorer.apk Success 14:14:53.56 d:\TEMP >> adb reboot
Nein, WLAN geht immer noch nicht.
14:15:06.02 d:\TEMP >> adb shell pm install -r --user 0 /system/app/RKDeviceTest/RKDeviceTest.apk Success 14:22:01.45 d:\TEMP >> adb reboot
Der WLAN-Schalter reagiert zwar flotter, aber es tut sich nichts.
14:22:07.99 d:\TEMP >> adb shell pm install -r --user 0 /system/app/RKUpdateService/RKUpdateService.apk Success 14:26:35.76 d:\TEMP >> adb reboot
Nach dem Wiederhochfahren zeigt sich das folgende Bild:



Wenn ich auf "Bis zum Neustart des Geräts ausblenden" anwähle, dann geht der WLAN-Schalter in den Einstellungen und ich bekommen auch wieder eine Verbindung zu meinem WLAN, aber das System Update abgestürzt ist, soll natürlich nicht sein. Dem scheint noch irgendetwas zu fehlen. Bevor wir das nächste Package reinstallieren, warten wir noch ein Weilchen, ob sich neue Logfile-Einträge ergeben. Während ich wieder ein Viertelstündchen warte, sinniere ich über die Frage nach, warum man den Handler, der sich mit WLAN befasst, nicht einfach WiFiHandler oder so nennen kann...

Und für wahr, es gibt einen neuen POST /terminal/client/register-Request. Das heißt, dass die hier nicht mit R für reinstalliert sauber sein dürften.
R package:/system/app/RKUpdateService/RKUpdateService.apk=android.rockchip.update.service installer=null package:/system/priv-app/ChangeLedStatus/ChangeLedStatus.apk=com.example.changeled installer=null package:/system/app/Clean/Clean.apk=com.charon.rocketfly installer=null R package:/system/app/RKDeviceTest/RKDeviceTest.apk=com.rockchip.devicetest installer=null R package:/system/app/RkExplorer/RkExplorer.apk=com.android.rockchip installer=null package:/system/priv-app/MediaCenter/MediaCenter.apk=com.rockchips.mediacenter installer=null
Das heißt auch, das es durch die Nicht-R-Packages momentan nicht schlimmer werden kann und ich sie re-installieren kann. Mal schauen, ob das System dann wenigstens ohne Absturz läuft. Dummerweise mögen sich nicht alle Apps wieder installieren lassen:
15:01:26.91 d:\TEMP >> adb shell pm install -r --user 0 /system/priv-app/ChangeLedStatus/ChangeLedStatus.apk Failure [INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.example.changeled-1: Package /data/app/com.example.changeled-1/base.apk code is missing] 15:02:59.63 d:\TEMP >> adb shell pm install -r --user 0 /system/app/Clean/Clean.apk Success 15:03:22.49 d:\TEMP >> adb shell pm install -r --user 0 /system/priv-app/MediaCenter/MediaCenter.apk Failure [INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.rockchips.mediacenter-1: Package /data/app/com.rockchips.mediacenter-1/base.apk code is missing] 15:06:10.45 d:\TEMP >> adb reboot
Da hat wohl einer (der TV Box- oder der Malware-Entwickler) nicht sauber die APKs hinterlegt. Die Fehlermeldung mit der System Update Absturz-Meldung ist immer noch da. Da kann ich jetzt nichts mehr dran ändern. Da muss ich jetzt wohl immer die Fehlermeldung weg klicken.

Jetzt weiß ich auch bald nicht mehr, was ich noch deinstallieren könnte. Etwas verdächtig bzw. überflüssig erscheinen mir noch:
package:/system/app/Gallery/Gallery.apk=com.android.gallery installer=null package:/system/app/Music/Music.apk=com.android.music installer=null package:/system/priv-app/StressTest/StressTest.apk=com.cghs.stresstest installer=null
Die erste App, Gallery läuft als App "Kamera", ab Systemstart, wobei ich mich frage, wozu eine Box eine Kamera braucht. Aber es scheint nur ein Bildanzeigeprogramm zu sein. Trotzdem beende und deaktiviere ich es über die App-Einstellungen. Und sei es auch nur, um Speicher zu sparen. Die zweite App, Music, wird nicht automatisch gestartet. Die kann so bleiben.

Die dritte App, "Stresstest for 7.0" läuft ab Systemstart, was wohl unnötig ist. Also beende ich die App und da sie sich nicht über den Einstellungsdialog deaktivieren lässt, tue ich das wieder über ADB:
15:16:59.91 d:\TEMP >> adb shell pm uninstall -k --user 0 com.cghs.stresstest Success 15:23:50.02 d:\TEMP >> adb reboot
Die HEAD /OtaUpdater/android-Requests für die Firmware-Update-Anfrage haben zwar aufgehört, die POST /terminal/client/register-Requests kommen aber immer noch. Das heißt, die Malware ist immer noch aktiv. Auch wenn sie jetzt wegen DNS-Umleitung und BSI-Sinkhole eigentlich nichts mehr anrichten kann, ist das Ziel, die Malware vom System zu entfernen, nicht erreicht.

Schade, schade, Marmelade

Ich wüsste jetzt auch nicht, was ich noch deinstallieren oder deaktivieren sollte. Es ist anzunehmen, dass die Malware so tief im System verankert ist, dass es nicht mehr richtig laufen würde, wenn man die befallene App deinstalliert.

Eine Möglichkeit, die mir noch einfällt, wäre es, ein kompatible Firmware zu finden und diese auf die Box zu flashen - wenn dies bei der H20 überhaupt so einfach möglich ist. Wobei man sich bei den Quellen im Internet nicht sicher sein kann, sich dann nicht ein Image mit einer anderen Malware-Variante einzufangen. Das würde dann nichts helfen, sondern man stünde mit der Analyse wieder ganz am Anfang.

Weil mir die Box mit der jedes mal erscheinenden Fehlermeldung sowieso nicht gefällt, versuche ich einen Hardreset durchzuführen. Bei meiner H20pro hatte ich das ja schon versucht, aber kein Glück. Aber hier kann ich es ja auch mal versuchen. Ich halte also den Reset-Taster hinten in der Klinkenbuchse mit einem Zahnstocher während ich das Stromkabel einstecke. Video dazu übrigens unter https://youtu.be/kIPIU03FjYE.

Hier bei der H20 Box erscheint dann nach kurzer Zeit nach dem Loslassen etwas von USB und Wiederherstellung auf dem Bildschirm, aber bevor man das richtig lesen kann, startet die Box auch schon neu. Und braucht ein bisschen länger zum Hochfahren. Dann endlich erwartet mich die Box wieder mit dem Standard-Launcher (siehe oben). Alles ist vergessen, die WLAN-Credentials gelöscht, alles zurückgesetzt. Doch halt: nicht alles, die /etc/hosts hat noch die Einträge mit der Umleitung zu meinem Webserver auf 10.10.10.4 drin, komisch.

Soll mir recht sein, muss ich die nicht neu eingeben. Ich gebe also wieder mein WLAN-Passwort an und erhalte dann nach ein paar Minuten neue Einträge im Logfile:
2025-01-28 15:11:08 10.10.10.4 GET /ott/dev/plugin_conf.xml - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 301 0 0 10 2025-01-28 15:11:08 10.10.10.4 GET /ott/dev/plugin_conf.xml - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 15 2025-01-28 15:11:08 10.10.10.4 GET /Update/rk322x/H20/A32/7.1.2_25/version.json - 80 - 10.10.10.202 okhttp/3.4.1 - 404 0 2 15 2025-01-28 15:16:13 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-28 15:21:13 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8 2025-01-28 15:26:13 10.10.10.4 POST /terminal/client/register - 80 - 10.10.10.202 Dalvik/2.1.0+(Linux;+U;+Android+10;+H20+Build/NHG47K) - 404 0 2 8
Alles beim Alten. Malware wieder aktiv :(

Vielleicht versuche ich es später einmal ernsthaft, eine andere Firmware zu installieren. Aber das wird dann Stoff für einen neuen Artikel.

Bis dahin muss ich die Badbox H20 wohl in den Giftschrank sperren. Passieren sollte mit der Umleitung in Hosts und dem BSI-Sinkhole zwar eigentlich nichts mehr, aber man weiß ja nie.

So wichtig ist mir die etwas schwachbrüstige H20 Box aber auch nicht. Die H20pro allerdings ist durchaus brauchbar und vielleicht habe ich mit der mehr Glück. Ich konnte ja jetzt einiges an Erfahrung sammeln (Android ADB-Nerd + 20), da dürfte es bei der schneller gehen.

Es sei denn, es sieht da wieder alles ganz anders aus. Man wird sehen. Da wird auf jeden Fall noch ein Artikel von mir kommen.

Nachtrag 2025-01-31

Bei meiner anderen Box, der H20pro war ich erfolgreicher, wie hier zu lesen: Entfernen der Badbox Malware von der bei AliExpress gekauften TV-Box H20pro (Allwinner H616 CPU und Mali G31 GPU)



Quellen, Literaturverweise und weiterführende Links