
CVE-2026-12960 - Esportazione impropria dei componenti dell'applicazione Android nell'app ASUS Router (com.asus.aihome). PoC, APK dell'exploit, video e report del fornitore. Corretto nella versione 1.0.0.9.74.
Esportazione impropria dei componenti dell'app Android ASUS Router
Un componente incluso nell'app Android ASUS Router (com.asus.aihome) era dichiarato
android:exported="true" senza android:permission. Qualsiasi altra app sullo stesso
dispositivo, senza alcuna autorizzazione, poteva inviargli un Intent appositamente
predisposto e far aprire all'app ASUS Router un URI controllato dall'attaccante per
conto dell'utente.
Segnalato ad ASUS il 2026-03-17. Corretto da ASUS e pubblicato come CVE-2026-12960 il 2026-07-03.
Scoperto e segnalato da Sedric Louissaint di Show Up Show Out Security.
| CVE | CVE-2026-12960 |
| Prodotto | App ASUS Router per Android (com.asus.aihome) |
| Versioni vulnerabili | ≤ 1.0.0.9.71 |
| Corretto nella versione | 1.0.0.9.74 |
| Debolezza | CWE-926: Esportazione impropria dei componenti dell'applicazione Android |
| CVSS 4.0 | 6.0 Medio 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 |
| Avviso del fornitore | https://www.asus.com/security-advisory/ |
| Testato su | com.asus.aihome 1.0.0.9.71 (Google Play), emulatore Android 11 |
L'app include l'SDK Baidu Push, che dichiara:
<service
android:name="com.baidu.android.pushservice.CommandService"
android:exported="true" />
Nessun attributo android:permission: il controllo degli accessi a livello di
componente di Android non viene quindi mai eseguito. Qualsiasi app installata può
chiamare startService() su di esso.
CommandService.onStartCommand() legge un PublicMsg Parcelable dall'extra
public_msg dell'Intent in arrivo e lo passa a handlePrivateNotification(), che
dirama sul campo mOpenType fornito dall'attaccante:
mOpenType | Comportamento |
|---|---|
1 | startActivity(ACTION_VIEW, Uri.parse(mUrl)) con l'mUrl dell'attaccante |
2 | Intent.parseUri(mPkgContent, 0) poi startActivity() / sendBroadcast() |
Né il mittente né il payload vengono validati. Poiché l'activity risultante viene avviata dall'UID e dal processo dell'app ASUS stessa, qualsiasi cosa appaia sullo schermo sembra provenire dalla fidata app di gestione del router che l'utente ha appena aperto.
In pratica, nulla di tutto ciò è specifico di Baidu: l'SDK fornisce il componente esportato, l'app ospitante lo eredita e l'identità dell'app ospitante è ciò che viene presa in prestito.
PublicMsg Parcelable che corrisponde alla
disposizione dei campi del target.mOpenType = 1 e mUrl su un URI controllato dall'attaccante.CommandService. Nessuna autorizzazione richiesta, nessuna
SecurityException.onStartCommand() → handlePrivateNotification().startActivity(ACTION_VIEW, Uri.parse(mUrl)) viene attivata dal processo
dell'app ASUS.L'ordine dei campi di PublicMsg, ricostruito da writeToParcel nello smali
decompilato e reimplementato in poc/PublicMsg.java:
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
Sbaglia l'ordine e la Parcel viene de-marshallata in dati spazzatura. Azzeccalo e il servizio accetta il messaggio come se fosse stato inviato dalla stessa infrastruttura push di Baidu.
Sei schemi URI, un servizio esportato, zero autorizzazioni:
| # | Scheme | Risultato |
|---|---|---|
| 1 | https: | Il browser apre una pagina di phishing controllata dall'attaccante |
| 2 | sms: | Compositore SMS precompilato con un messaggio di ingegneria sociale |
| 3 | tel: | Dialer precompilato con un numero controllato dall'attaccante |
| 4 | mailto: | Compositore email precompilato per esfiltrare credenziali |
| 5 | market: | Reindirizzamento al Play Store per l'installazione di malware |
| 6 | geo: | Reindirizzamento in Maps a un falso centro assistenza |
media/poc_commandservice.mp4 è la registrazione
completa di 31 secondi: build, installazione, attivazione e l'emulatore che reagisce
a ciascun payload a turno.
| Attacco 1: pagina di phishing | Attacco 2: compositore SMS | Attacco 3: dialer | Autorizzazioni dell'app PoC |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
Quell'ultimo screenshot è l'intera argomentazione. Nessuna autorizzazione richiesta. L'app che ha appena eseguito sei azioni tramite l'app ASUS Router non ha chiesto nulla all'utente.
Richiede ADB, un JDK e gli strumenti di build dell'Android SDK (aapt2, d8/dx,
zipalign, apksigner) oltre a platforms;android-30.
./poc/poc_commandservice_exploit.sh <device_serial>
Lo script esegue tre fasi:
CommandService da
com.android.shell e segnala se qualcuna viene rifiutata. Un servizio protetto da
autorizzazione genera una SecurityException in questo punto. Questo ha accettato
tutte e tre.exploit_commandservice.apk e
lo installa. Una copia precompilata è in poc/ se preferisci saltare
questo passaggio.Output della fase 1 su un dispositivo vulnerabile:
[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
E il ServiceRecord da dumpsys activity services, che registra il chiamante:
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
Fase 3, da una vera app non privilegiata anziché dalla 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() ha restituito il ComponentName del target invece di null e non è
stata lanciata alcuna SecurityException. Android ha risolto l'Intent e lo ha
consegnato.