
CVE-2026-12960 - ASUS Routerアプリ (com.asus.aihome) におけるAndroidアプリケーションコンポーネントの不正なエクスポート。PoC、エクスプロイトAPK、動画、ベンダー報告書。1.0.0.9.74で修正済み。
ASUS Router アプリにおける Android アプリケーションコンポーネントの不適切なエクスポート
ASUS Router Android アプリ(com.asus.aihome)に同梱されているコンポーネントは、
android:permission を指定せずに android:exported="true" と宣言されていました。
同じ端末上の他のアプリは、権限を一切保持していなくても、細工した Intent を送信し、
ASUS Router アプリにユーザーに代わって攻撃者制御の URI を開かせることができました。
2026-03-17 に ASUS へ報告。ASUS によって修正され、2026-07-03 に CVE-2026-12960 として公開されました。
発見・報告者: Sedric Louissaint( Show Up Show Out Security)
| CVE | CVE-2026-12960 |
| 製品 | ASUS Router アプリ for Android(com.asus.aihome) |
| 影響を受けるバージョン | ≤ 1.0.0.9.71 |
| 修正バージョン | 1.0.0.9.74 |
| 脆弱性種別 | CWE-926: Android アプリケーションコンポーネントの不適切なエクスポート |
| CVSS 4.0 | 6.0 中 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 |
| ベンダーアドバイザリ | https://www.asus.com/security-advisory/ |
| テスト環境 | com.asus.aihome 1.0.0.9.71(Google Play)、Android 11 エミュレータ |
このアプリには Baidu Push SDK が同梱されており、次のように宣言されています:
<service
android:name="com.baidu.android.pushservice.CommandService"
android:exported="true" />
android:permission 属性がないため、Android のコンポーネントレベルのアクセス制御は
一切実行されません。インストールされているどのアプリも、このサービスに対して
startService() を呼び出すことができます。
CommandService.onStartCommand() は、受信した Intent の public_msg エクストラから
PublicMsg Parcelable を読み取り、handlePrivateNotification() に渡します。
このメソッドは攻撃者が指定した mOpenType フィールドに応じて分岐します:
mOpenType | 挙動 |
|---|---|
1 | 攻撃者の mUrl を使って を実行 |
送信元もペイロードも検証されません。結果として起動されるアクティビティは ASUS アプリ 自身の UID とプロセスから起動されるため、画面に表示される内容は、ユーザーが開いた ばかりの信頼できるルーター管理アプリから来たかのように見えます。
実質的には、これは Baidu 固有の問題ではありません。SDK がエクスポートされた コンポーネントを同梱し、ホストアプリがそれを継承し、借用されるのはホストアプリの ID なのです。
PublicMsg
Parcelable を構築します。mOpenType = 1 に設定し、mUrl を攻撃者制御の URI に設定します。CommandService に Intent を送信します。権限は不要で、SecurityException も発生しません。onStartCommand() → handlePrivateNotification() が実行されます。startActivity(ACTION_VIEW, Uri.parse(mUrl)) が発火します。writeToParcel から復元され、poc/PublicMsg.java に
再実装された PublicMsg のフィールド順序:
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
順序を間違えると、Parcel はガベージとしてアンマーシャルされます。正しく合わせれば、 Baidu 自身のプッシュ基盤が送信したかのように、サービスはメッセージを受け入れます。
6 つの URI スキーム、1 つのエクスポートされたサービス、権限ゼロ:
media/poc_commandservice.mp4 は、ビルド、インストール、
発火、そして各ペイロードに対するエミュレータの反応を含む、全 31 秒の録画です。
| 攻撃 1: フィッシングページ | 攻撃 2: SMS 作成画面 | 攻撃 3: ダイヤラ | PoC アプリの権限 |
|---|---|---|---|
![]() | ![]() |
最後のスクリーンショットがすべてを物語っています。権限は一切リクエストされていません。 ASUS Router アプリを通じて 6 つのアクションを実行したアプリは、ユーザーに何も求めていません。
ADB、JDK、Android SDK ビルドツール(aapt2、d8/dx、zipalign、
apksigner)、および platforms;android-30 が必要です。
./poc/poc_commandservice_exploit.sh <device_serial>
このスクリプトは 3 つのフェーズで実行されます:
com.android.shell から 3 つの CommandService アクションを送信し、
いずれかが拒否されるかを報告します。権限で保護されたサービスは、ここで
SecurityException をスローします。このサービスは 3 つすべてを受け入れました。exploit_commandservice.apk をパッケージ化して署名し、
インストールします。省略したい場合は、プリビルド版が poc/ にあります。脆弱なデバイスでのフェーズ 1 の出力:
[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
そして、呼び出し元を記録する dumpsys activity services の ServiceRecord:
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
シェルではなく実際の権限のないアプリからのフェーズ 3:
W PoCExploit: [OK] attack1_url_open → com.asus.aihome/com.baidu.android.pushservice.CommandService
W PoCExploit: [OK] attack2_sms_compose → ...
(all 6 succeed)
startService() は null ではなくターゲットの ComponentName を返し、
SecurityException もスローされませんでした。Android は Intent を解決して配信しました。
poc/
poc_commandservice_exploit.sh Automated three-phase reproduction script
ExploitCommandService.java PoC activity + broadcast receiver source
PublicMsg.java Parcelable matching the target's field layout
AndroidManifest_PoC.xml PoC manifest (note: no <uses-permission>)
exploit_commandservice.apk Prebuilt PoC, debug-signed, zero permissions
media/
poc_commandservice.mp4 Full PoC recording
attack1-browser.jpg Stills pulled from the recording
attack2-sms.jpg
attack3-dialer.jpg
poc-app-no-permissions.jpg
vendor/
asus-security-advisory-submission.pdf The report as filed with ASUS
PoC の発信元 URL は Burp Collaborator のサブドメインで、ナビゲーションが実際に 発生したことを確認するために使用されました。現在はすでに無効です。再現する場合は 独自の URL に置き換えてください。
ベンダー側の修正は、1 つの属性で済みます:
<service
android:name="com.baidu.android.pushservice.CommandService"
android:exported="false" />
あるいは、コンポーネントを外部から到達可能にする必要が本当にある場合は、
signature 保護レベルの権限でゲートし、逆シリアライズした PublicMsg を
処理前に検証してください。ASUS は 1.0.0.9.74 で修正を提供しました。
ユーザー側: ASUS Router アプリを 1.0.0.9.74 以降 に更新してください。
Android アプリを配布しているすべての開発者へ: サードパーティ SDK が何を
エクスポートしているかを監査してください。自身のリリースビルドに対して
aapt dump xmltree base.apk AndroidManifest.xml を実行し、そこに含まれる
すべての exported="true" を確認してください。配布するマニフェストは、マージした
すべてのマニフェストの合計であり、そのすべてに責任があります。
| 日付 | イベント |
|---|---|
| 2026-03-17 | PoC APK、自動スクリプト、動画とともに ASUS へ報告 |
| 2026-06-23 | ASUS(CNA)により CVE-2026-12960 を予約 |
| 2026-07-03 | CVE 公開。1.0.0.9.74 で修正利用可能 |
| 2026-07-25 | 公開レポートと PoC をリリース |
本内容は、調整済み開示とベンダーによる修正後に、防御的および教育的用途のために 公開されています。PoC は修正済みバージョンを対象としており、URI を起動する以外の ことはしません。所有していないデバイスや、書面によるテスト許可がないデバイスに対して 実行しないでください。
startActivity(ACTION_VIEW, Uri.parse(mUrl))2 | Intent.parseUri(mPkgContent, 0) を実行し、その後 startActivity() / sendBroadcast() を実行 |
| # | スキーム | 結果 |
|---|
| 1 | https: | ブラウザが攻撃者制御のフィッシングページを開く |
| 2 | sms: | ソーシャルエンジニアリングメッセージが事前入力された SMS 作成画面 |
| 3 | tel: | 攻撃者制御の番号が事前入力されたダイヤラ |
| 4 | mailto: | 認証情報を窃取するために事前入力されたメール作成画面 |
| 5 | market: | マルウェアインストールのための Play ストアへのリダイレクト |
| 6 | geo: | 偽のサービスセンターへのマップリダイレクト |
![]() |
![]() |