
CVE-2026-12960 - Unsachgemäßer Export von Android-Anwendungskomponenten in der ASUS Router App (com.asus.aihome). PoC, Exploit-APK, Video und Anbieterbericht. Behoben in 1.0.0.9.74.
Unsachgemäßer Export von Android-Anwendungskomponenten in der ASUS Router App
Eine Komponente, die in der Android-App „ASUS Router“ (com.asus.aihome) enthalten ist, wurde mit android:exported="true" und ohne android:permission deklariert. Jede andere App auf demselben Gerät, ohne jegliche Berechtigungen, konnte ihr einen manipulierten Intent senden und die ASUS Router App dazu bringen, im Namen des Benutzers eine vom Angreifer kontrollierte URI zu öffnen.
Am 17.03.2026 an ASUS gemeldet. Von ASUS behoben und am 03.07.2026 als CVE-2026-12960 veröffentlicht.
Entdeckt und gemeldet von Sedric Louissaint von Show Up Show Out Security.
| CVE | CVE-2026-12960 |
| Produkt | ASUS Router App für Android (com.asus.aihome) |
| Betroffen | ≤ 1.0.0.9.71 |
| Behoben in | 1.0.0.9.74 |
| Schwachstelle | CWE-926: Unsachgemäßer Export von Android-Anwendungskomponenten |
| CVSS 4.0 | 6.0 Medium CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N |
| CNA | ASUS |
| Herstellerhinweis | https://www.asus.com/security-advisory/ |
| Getestet auf | com.asus.aihome 1.0.0.9.71 (Google Play), Android-11-Emulator |
Die App enthält das Baidu Push SDK, das Folgendes deklariert:
<service
android:name="com.baidu.android.pushservice.CommandService"
android:exported="true" />
Es gibt kein android:permission-Attribut, daher greift Androids Zugriffskontrolle auf Komponentenebene nie ein. Jede installierte App kann startService() auf den Dienst aufrufen.
CommandService.onStartCommand() liest ein PublicMsg-Parcelable aus dem public_msg-Extra des eingehenden Intents und übergibt es an handlePrivateNotification(), das anhand des vom Angreifer gelieferten mOpenType-Felds verzweigt:
mOpenType | Verhalten |
|---|---|
1 | startActivity(ACTION_VIEW, Uri.parse(mUrl)) mit der mUrl des Angreifers |
2 | Intent.parseUri(mPkgContent, 0), dann startActivity() / sendBroadcast() |
Weder der Absender noch die Nutzlast wird validiert. Da die resultierende Activity aus der eigenen UID und dem eigenen Prozess der ASUS-App gestartet wird, scheint alles, was auf dem Bildschirm erscheint, von der vertrauenswürdigen Router-Verwaltungs-App zu stammen, die der Benutzer gerade geöffnet hat.
In der Wirkung ist daran nichts Baidu-spezifisch. Das SDK liefert die exportierte Komponente, die Host-App erbt sie, und die Identität der Host-App ist es, die ausgeliehen wird.
PublicMsg-Parcelable, das dem Feldlayout des Ziels entspricht.mOpenType = 1 und mUrl auf eine vom Angreifer kontrollierte URI.CommandService. Keine Berechtigung erforderlich, keine SecurityException.onStartCommand() → handlePrivateNotification().startActivity(ACTION_VIEW, Uri.parse(mUrl)) wird aus dem Prozess der ASUS-App ausgelöst.Die PublicMsg-Feldreihenfolge, die aus writeToParcel im dekompilierten Smali-Code rekonstruiert und in poc/PublicMsg.java neu implementiert wurde:
String mMsgId, mAppId, mTitle, mDescription, mUrl, mPkgName
int mPkgVercode, mNotificationBuilder, mNotificationBasicStyle
int mOpenType, mUserConfirm
String mCustomContent, mPkgContent
int mAdvertiseStyle
String mAdvertiseSmallIconUrl, mAdvertiseLargeIconUrl, mAdvertiseClickUrl,
mAdvertiseBigPictureUrl, mAdvertiseBigPictureClickUrl, mAdvertiseDownloadClickUrl
Bei falscher Reihenfolge wird das Parcel zu Datenmüll entserialisiert. Bei korrekter Reihenfolge akzeptiert der Dienst die Nachricht, als hätte Baidus eigene Push-Infrastruktur sie gesendet.
Sechs URI-Schemata, ein exportierter Dienst, null Berechtigungen:
| # | Schema | Ergebnis |
|---|---|---|
| 1 | https: | Browser öffnet eine vom Angreifer kontrollierte Phishing-Seite |
| 2 | sms: | SMS-Editor, vorausgefüllt mit einer Social-Engineering-Nachricht |
| 3 | tel: | Telefon-App, vorausgefüllt mit einer vom Angreifer kontrollierten Nummer |
| 4 | mailto: | E-Mail-Editor, vorausgefüllt zum Exfiltrieren von Anmeldedaten |
| 5 | market: | Play-Store-Umleitung für eine Malware-Installation |
| 6 | geo: | Maps-Umleitung zu einem gefälschten Service-Center |
media/poc_commandservice.mp4 ist der vollständige 31-sekündige Durchlauf: Build, Installation, Auslösen, und der Emulator, der nacheinander auf jede Nutzlast reagiert.
| Angriff 1: Phishing-Seite | Angriff 2: SMS-Editor | Angriff 3: Telefon-App | Berechtigungen der PoC-App |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
Dieser letzte Screenshot ist das gesamte Argument. Keine Berechtigungen angefordert. Die App, die gerade sechs Aktionen über die ASUS Router App ausgelöst hat, hat den Benutzer um überhaupt nichts gebeten.
Erfordert ADB, ein JDK und die Android-SDK-Build-Tools (aapt2, d8/dx, zipalign, apksigner) sowie platforms;android-30.
./poc/poc_commandservice_exploit.sh <device_serial>
Das Skript durchläuft drei Phasen:
CommandService-Aktionen von com.android.shell aus und meldet, ob eine abgelehnt wird. Ein berechtigungsgeschützter Dienst würde hier eine SecurityException auslösen. Dieser Dienst akzeptierte alle drei.exploit_commandservice.apk und installiert ihn. Eine vorgefertigte Kopie liegt in poc/, falls du diesen Schritt überspringen möchtest.Phase-1-Ausgabe auf einem verwundbaren Gerät:
[ACCESS] passthrough.notification.CLICK → service accepted intent
[ACCESS] privatenotification.CLICK → service accepted intent
[ACCESS] privatenotification.DELETE → service accepted intent
Phase 1 result: 3/3 actions accepted without permission check
Und der ServiceRecord von dumpsys activity services, der den Aufrufer aufzeichnet:
intent={act=com.baidu.android.pushservice.action.privatenotification.CLICK
cmp=com.asus.aihome/com.baidu.android.pushservice.CommandService}
recentCallingPackage=com.android.shell
startRequested=true callStart=true
Phase 3, von einer echten privilegienfreien App statt von der Shell:
W PoCExploit: [OK] attack1_url_open → com.asus.aihome/com.baidu.android.pushservice.CommandService
W PoCExploit: [OK] attack2_sms_compose → ...
(all 6 succeed)
startService() gab den Ziel-ComponentName statt null zurück, und es wurde keine SecurityException ausgelöst. Android hat den Intent aufgelöst und zugestellt.