
تنفيذ بلغة Rust لإثبات مفهوم حقن ضغطات المفاتيح من Marc Newlin (CVE-2023-45866).
⚠️ إخلاء مسؤولية: لأغراض البحث والتعليم فقط
هذا المشروع هو إثبات مفهوم (PoC) يوضح حقن ضغطات المفاتيح عبر بلوتوث، تمت إعادة تنفيذه بلغة Rust. وهو مخصص بشكل صارم للأغراض التعليمية وأبحاث الأمن السيبراني.
من خلال تنزيل هذا الكود أو استنساخه أو استخدامه، فإنك توافق على استخدامه بطريقة مسؤولة ووفقًا لجميع القوانين واللوائح المعمول بها.
مرحبًا بك في Rusty Injector — وهو تطبيق بلغة Rust مستوحى من إثبات مفهوم حقن ضغطات المفاتيح عبر بلوتوث لمارك نيوين، المرتبط بـ CVE-2023-45866 و CVE-2024-21306 و CVE-2024-0230.
حاليًا، هذا المستودع يطبق فقط CVE-2023-45866، الذي يستغل ثغرات حقن ضغطات المفاتيح في BlueZ على نظام التشغيل Linux.
أدناه لقطة شاشة لوصف NIST، بما في ذلك تقييم CVSS:
لقطة 1: وصف NIST لـ CVE-2023-45866.
أما CVE-2024-21306 و CVE-2024-0230، فليس لدي خطة لتنفيذها بنفسي، لكن المساهمات مرحب بها بحرارة.
قبل الخوض في أي تفاصيل، أشجعك على مشاهدة عرض مارك نيوين في مؤتمر NullCon 2024، حيث يقدم شرحًا واضحًا وشاملًا لهذه الثغرات: Hi, My Name Is keyboard لمارك نيوين..
كما قمت بتوفير مقطع فيديو يشرح هذه الثغرة بشكل مبسط. ستجده هنا: How a Simple Bluetooth Hack Can Hijack Your Device - Hi, my name is keyboard.
📌 إذا لاحظت أي نقاط مفقودة، أو مجالات يمكن تبسيطها بشكل أفضل، أو أخطاء محتملة في الشرح أدناه، فلا تتردد في تعديله وتقديم طلب دمج. سيسعدني مراجعة مساهماتك وإضافتها إلى المستودع.
بما أننا غطينا فقط ثغرة CVE-2023-45866 التي تستهدف أنظمة تشغيل Linux، سنشرح فقط عملية الوصول إلى هذا الاستغلال المحدد الذي يستهدف مكتبة BlueZ.
أولاً، يجب أن تفهم أن هذه الثغرة قابلة للاستغلال فقط عبر Bluetooth BR/EDR لأنها تستهدف بروتوكول HID القائم على هذه التقنية. قد تعلم أن التنفيذ المعماري للبلوتوث مقسم إلى طبقات متعددة مثل نموذج OSI لبروتوكول الإيثرنت، كما يمكنك ملاحظته في الرسم التخطيطي أدناه.
رسم بياني 1: مكدس Bluetooth BR/EDR (معدل أساسي - معدل بيانات محسن) مبسط. تمثل الطبقة السفلية من المكدس الطبقة المادية بهوائي مخصص، وتمثل المستوى الأعلى مستوى التطبيق أو ما نسميه أحيانًا نظام التشغيل. عندما يريد جهازان التواصل مع بعضهما البعض، فإنهما يمران عبر هذه الطبقات المختلفة: من الأعلى إلى الأسفل للحزم الصادرة ومن الأسفل إلى الأعلى لحزم البلوتوث الواردة.
بعد عملية الاستعلام (inquiry)، بمجرد أن تحدد الأجهزة رغبتها في إنشاء اتصال، تشرع في عملية الاقتران (pairing). تتيح هذه العملية المصادقة المتبادلة بين الأجهزة وإنشاء مفتاح تشفير يُستخدم بعد ذلك لتأمين الاتصال.
توفر مواصفات البلوتوث مستويات مختلفة من المصادقة والأمان. اعتمادًا على الآلية المستخدمة للمصادقة، قد يختلف مستوى الأمان للاتصال. يمكن للأجهزة المصادقة بناءً على الأجهزة الطرفية للإدخال والإخراج التي تمتلكها، وهو مفهوم يُشار إليه بنماذج الارتباط (association models). ربما واجهت هذا عند إقران جهازين—على سبيل المثال، طلب إدخال رمز PIN معروض على الجهاز الآخر.
هناك أربعة نماذج ارتباط للاقتران، تحددها قدرات الإدخال/الإخراج (I/O) للأجهزة:
أدناه جدول يوضح نموذج الارتباط المستخدم بناءً على قدرات أجهزة إنترنت الأشياء لدينا.
رسم بياني 2: جدول يوضح نماذج ارتباط Bluetooth BR/EDR مستوحى من مواصفات بلوتوث الأساسية v5.3 - 2.3.5.1 اختيار طريقة توليد المفاتيح الجدول 2.8: تعيين قدرات IO لطريقة توليد المفاتيح (صفحة 1573). لمزيد من المعلومات حول أنماط الأمان ونماذج الارتباط، يرجى مراجعة هذه المقالة المثيرة التي نشرتها Thyrasec: Bluetooth Security: Classic & BLE!
أنا متأكد من أنك مفتون بطريقة "Just Works"، وهي بالضبط مكان وجود ثغرتنا. إليك المشكلة: تنشئ هذه الطريقة الاقتران دون الحاجة إلى تأكيد أو تفاعل من المستخدم، مما لا يترك أي وسيلة للتحقق من صحة الجهاز المقترن. على أنظمة Linux، كان مكدس BlueZ، بشكل افتراضي، يقبل طلبات الاقتران الواردة من الأجهزة المصنفة على أنها NoInputNoOutput (لتمكين التوافق مع الإصدارات السابقة). خيار تصميم "رائع" حقًا، ألا توافقني؟
لقطة 2: تحديث التكوين الافتراضي لـ BlueZ لتمكين أمان البلوتوث وتصحيح CVE-2023-45866.
بعد الاقتران بالجهاز المستهدف، ينشئ نظامنا اتصالاً ببروتوكول اكتشاف الخدمة (SDP) عبر المنفذ 1 من طبقة L2CAP. كما هو موضح في الرسم البياني 1، تعمل طبقة L2CAP كوسيط بين طبقات الخدمة السفلية والعليا، حيث توفر تجزئة وتعدد إرسال وإعادة تجميع لحزم البيانات. من خلال اتصال SDP، نتعرف على جميع الخدمات المتاحة على الجهاز المستهدف ونتصل بخدمة بروتوكول التفاعل البشري (HID). يستخدم نظام التشغيل ملف HID لمعالجة الإدخال من لوحات المفاتيح والفئرات التي تعمل بتقنية البلوتوث، ويعمل عبر المنفذين 17 (HID Control) و 19 (HID Interrupt) من طبقة L2CAP. للوصول إلى ملف HID، لا يلزم أي مصادقة وأي جهاز متصل بالمنفذين 17 و 19 من L2CAP يتم التعرف عليه كجهاز HID.
يمكن للمهاجم انتحال خدمات وفئة جهاز لوحة مفاتيح بلوتوث لاسلكية، واستغلال نموذج الارتباط "Just Works" عن طريق تحديد قدرة "NoInputNoOutput"، وحقن ضغطات مفاتيح غير مصرح بها في الجهاز المستهدف.
لأكون صادقًا تمامًا، كان الهدف الوحيد هو إعادة تطبيق إثبات المفهوم بلغة Rust لاكتساب فهم أعمق لتفاصيل هذا الاستغلال. لهذا السبب، في هذا التكرار الأول، تم استلهام البنية العامة من إثبات المفهوم بلغة Python لمارك نيوين: Github "hi_my_name_is_keyboard". في إعادة عمل مستقبلية، يمكن تنفيذه بطريقة أكثر خصوصية بلغة Rust.
الصناديق (مكتبات Rust) المستخدمة أثناء هذا التنفيذ:
[dependencies]
bluer = { version = "0.17.3", features = ["l2cap", "bluetoothd", "id", "rfcomm"] }
tokio = "1.42.0"
regex = "1.11.1"
clap = { version = "4.5.23", features = ["derive"] }
الاعتماد الرئيسي في مشروعي كان "BlueR"، وهو واجهة برمجة تطبيقات Rust مبنية على مكتبة BlueZ الأصلية بلغة C. يمكنك الاطلاع على عملهم هنا: GitHub BlueR. كما قمت بدمج Tokio لتمكين استخدام الدوال غير المتزامنة async التي توفرها مكتبة BlueR. بالإضافة إلى ذلك، استخدمت Clap، وهو محلل للوسائط سطر الأوامر، و Regex، وهو صندوق يطبق التعبيرات المنتظمة في Rust، للتحقق من صحة مدخلات المستخدم لـ 'bt_addr' (عنوان بلوتوث).
بعد ملاحظة تنفيذ مارك نيوين، قمت بتقسيم البنية إلى عدة خطوات لتكرار نفس الوظائف:
--iface أو -i والتي تشير إلى واجهة/محول البلوتوث المراد استخدامه. هذه الوسيطة اختيارية، إذا لم يتم تحديد شيء، فسيحاول الوصول إلى واجهة افتراضية.--target أو -t وهي إلزامية وتحدد عنوان بلوتوث الهدف.NoInputNoOutput لتمكين الوصول إلى طريقة الاقتران "Just Works" أثناء الاتصال بالجهاز الهدف.0x002540 لانتحال شخصية لوحة مفاتيح.لقد حاولت التعليق على الكود الخاص بي قدر الإمكان. إذا تصفحته، ستتعرف بسهولة على كل هذه الخطوات. لجعله أكثر أناقة، ستكون الخطوة التالية هي جعله أكثر خصوصية بلغة Rust، وإنهاء التشغيل بشكل لائق وإضافة العديد من الوظائف الأخرى مثل القدرة على تحليل نصوص لوحة المفاتيح (الحمولات المعدة) أو وجود واجهة مستخدم رسومية. مرة أخرى، كان هذا فقط للأغراض التعليمية، ولست متأكدًا من العمل على تكرار آخر لهذا البرنامج. ولكن مرة أخرى، المساهمات مرحب بها بحرارة. إذا كانت لديك أي أسئلة، فلا تتردد في السؤال.
أول شيء يجب ملاحظته: تم تطوير واختبار هذه الأداة على Ubuntu 24.04.
لاستخدام هذه الأداة، تحتاج إلى تعطيل خدمة HID الافتراضية المسجلة بواسطة BlueZ، بحيث يمكن إعادة تسجيلها عند تشغيل الاستغلال. اتبع هذه الخطوات:
/etc/systemd/system/bluetooth.target.wants/bluetooth.serviceExecStart=/usr/libexec/bluetooth/bluetoothd
إلى السطر التالي:
ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=inputsudo systemctl daemon-reload
sudo systemctl restart bluetoothالآن كل ما عليك فعله هو سحب المشروع وتنفيذه عن طريق بنائه باستخدام cargo build أو تشغيله مباشرة عن طريق تحديد الوسائط بـ:
cargo run -- -i [BT_INTERFACE] -t [BT_TARGET].
لقطة 3: واجهة سطر أوامر Rusty Injector.
إليك مثال:
cargo run -- -i hci0 -t AA:BB:CC:DD:EE:FF
شيء آخر يجب ملاحظته هو أنه إذا كنت ترغب في تعديل الكود واستخدام دالة "set_address" من خلال السمة Configuration، فيجب عليك تثبيت أداة bdaddr لتتمكن من استخدامها:
# build bdaddr from the bluez source
cd ~/
git clone --depth=1 https://github.com/bluez/bluez.git
gcc -o bdaddr ~/bluez/tools/bdaddr.c ~/bluez/src/oui.c -I ~/bluez -lbluetooth
sudo cp bdaddr /usr/local/bin/
يرجى الملاحظة، إذا لم تحدد أي واجهة بلوتوث، فسيحاول الوصول إلى واجهة افتراضية. وبالطبع، لا تنس توصيل واجهة بلوتوث بنظام Ubuntu الخاص بك.🙃
أعتقد أنني غطيت كل شيء—أنت الآن جاهز للاستفادة القصوى من Rusty Injector! إذا واجهت أي مشاكل أو كان لديك تعليقات أو ملاحظات، فلا تتردد في فتح مشكلة (issue). أتمنى لك تجربة رائعة وتسلية ممتعة في الاختراق! 🚀