
شرح تفصيلي وكود لثغرات CVE-2025-11492 وCVE-2025-11493 - تنفيذ التعليمات البرمجية عن بُعد (RCE) في ConnctWise Automate RMM عبر هجوم Adversary-in-the-Middle
كجزء من اختبار اختراق، اكتشفت ثغرات متعددة في وكيل ConnectWise Automate للمراقبة والإدارة عن بُعد (RMM). يُستخدم ConnectWise من قبل العديد من مزوّدي الخدمات المُدارة (MSPs) لإدارة ومراقبة أجهزة العملاء. مكنت هذه الثغرات من تنفيذ التعليمات البرمجية عن بُعد إذا تمكن المهاجم من إنشاء وسيط على مستوى الشبكة (Adversary-in-the-Middle)، أو يمكن استخدامها لتصعيد الصلاحيات محليًا وتحقيق استمرارية خفية إذا حصل المهاجم على تنفيذ برمجي أو وصول مادي إلى جهاز يعمل بوكيل ConnectWise Automate.
تم إبلاغ ConnectWise بالثغرات في 20 أغسطس 2025. خصصت ConnectWise معرّفات CVE وأصدرت تصحيحًا في الإصدار 2025.9 في 16 أكتوبر 2025.
نشرة ConnectWise:
معرّفات CVE:
2025.9 وتنشر النشرة الأمنية ومعرّفات CVE.أعجبتني استجابات ConnectWise السريعة ونهجهم التعاوني في المعالجة، واستعدادهم للانخراط في نقاش حول أفضل طريقة للتعامل مع التصنيف والمعالجة.
كان تصنيف هذه الثغرات تحديًا مثيرًا. بينما التحول إلى HTTPS يحل عمليًا جميع السيناريوهات في هذا التقرير، كان من الواضح أن هذا كان في الأصل خيارًا تصميميًا (لدعم HTTP) لتحسين موثوقية الاتصال بين الوكيل والخادم. يبدو أن مخطط التشفير يعترف جزئيًا/يحاول التخفيف من مخاطر AiTM، لكنه لم يُطبَّق بشكل متسق. تطلب التعمق في ذلك محاولة تصنيف ما إذا كان الضعف هو http نفسه أو غياب التشفير فوق HTTP بالإضافة إلى منع إعادة الإرسال والتحقق من المكونات الإضافية، وما إلى ذلك، كلها ثغرات مستقلة. في مرحلة ما، كانت ConnectWise تدرس 5+ معرّفات CVE منفصلة لجوانب مختلفة من الثغرات.
بالإضافة إلى ذلك، تغير نطاق الهجوم وناقل الهجوم اعتمادًا على ما إذا كانت الثغرة تُعتبَر من منظور AiTM مثل شبكة Wi‑Fi في مقهى أو من منظور تصعيد الامتيازات المحلية/الوصول المادي. نهج بديل هو اعتبار كل سيناريو ثغرة منفصلة، مثل AiTM RCE، أو LPE، أو الاستيلاء على الاستمرارية، إلخ.
درس أخير هو أنه حتى في 2025، ما زلنا نكافح لمشاركة الملفات بفعالية :D (أمان البريد الإلكتروني لم يتقبّل إرسالي لملفات .dll أو ملفات .zip تحتويها عبر البريد).
يُنشر هذا التقرير بعد إصدار ConnectWise لتصحيح والإفصاح عن معرّفات CVE، وبموافقتهم على أن هذا الإفصاح لا يضر مستخدميهم. علاوة على ذلك، أعتقد أن الإفصاح العام عن هذه الثغرات وتخفيفاتها سيساعد البائعين الآخرين ومحترفي الأمن على فهم المخاطر بشكل أفضل في كل من ConnectWise Automate وأنظمة RMM الأخرى وتخفيفها.
المحتوى مخصص لأغراض البحث الأمني المشروع والمصرح به والتعليم فقط. الاستخدام غير المصرح به لهذه المعلومات لاختراق الأنظمة أو الشبكات أو البيانات غير قانوني وغير أخلاقي. يُقدَّم المحتوى كما هو دون أي ضمانات من أي نوع. يخلي المؤلف(ون) مسؤوليتهم تجاه أي أضرار ناتجة عن استخدام أو إساءة استخدام هذه المعلومات.
إذا كنت تستخدم هذا الكود أو المعلومات لإجراء المزيد من الأبحاث، فالتزم بممارسة الإفصاح المسؤول من خلال الإبلاغ عن أي ثغرات تكتشفها إلى البائع(ين) المتأثر(ين).
بالإضافة إلى التقرير أدناه، يحتوي هذا المستودع على كود PoC لتوضيح الثغرات. راجع automate_server/README.md للحصول على تفاصيل حول تنفيذ الخادم المزوّر وتعليمات الاستخدام.
يمكن أيضًا استخدام هذا الكود لإجراء المزيد من البحث الأمني (الأخلاقي) على ConnectWise Automate.
التقرير التالي (أو نسخة قريبة منه)، وكود PoC بلغة Python في هذا المستودع، تم توفيرهما إلى ConnectWise، إلى جانب التخفيفات الموصى بها.
القسم المُزال الخاص بالتخفيفات يتناول بمزيد من التفصيل التغييرات التي يمكن إجراؤها على وكيل Automate لتحصينه بعدة طرق ضد هذه الثغرات.
ونظرًا لأن بعض هذه التغييرات لا تزال قيد الدراسة من قبل ConnectWise، فقد تمت إزالة هذا القسم من هذا الإفصاح العام.
وكيل ConnectWise Automate للمراقبة والإدارة عن بُعد (RMM) (تم اختباره على أحدث إصدار اعتبارًا من أغسطس 2025، نص الإصدار 250.252) معرّض لثغرة تنفيذ التعليمات البرمجية عن بُعد عبر الشبكة في تهيئات معينة. إذا تم تكوين الوكيل لاستخدام ناقل HTTP غير مشفر (إما بشكل أساسي أو كخيار احتياطي) لعنوان Server Address الخاص به، وتمكن المهاجم من تنفيذ هجوم الوسيط (AiTM)، فيمكنه تنفيذ الأكواد عن بُعد بصلاحيات SYSTEM. وقد لوحظت هذه التهيئة في البيئات الحقيقية لدى العديد من مزوّدي الخدمات المُدارة (MSPs).
الاستغلال ممكن أيضًا إذا حصل المهاجم على وصول مادي إلى الجهاز كمستخدم غير مسؤول أو تمكن بطريقة أخرى من توصيل الجهاز بشبكة يتحكم فيها المهاجم (أي يمكن استخدام الثغرة كتصعيد صلاحيات محلي). على الرغم من أن Automate يستخدم نظام تشفير لتشفير والتحقق من معظم أوامر RMM، فإن نظام الإضافات لديه يفتقر إلى الحماية الكافية ويظل عرضة لتنفيذ التعليمات البرمجية عن بُعد.
من خلال تنفيذ خادم مخصص يحاكي خادم التحكم في Automate، يمكن إجبار وكيل Automate على تنزيل إضافة خبيثة وتنفيذها.
يمكن للوكيل المخترق أيضًا أن يكون شكلاً جذابًا من أشكال الاستمرارية. باستخدام RCE لاستخراج مفاتيح التشفير المتماثل للوكيل، يمكن للخادم المخصص إرسال أوامر عشوائية إلى الوكيل عبر قناة RMM القياسية. في سيناريو AiTM، يتيح ذلك للمهاجم تنفيذ أوامر RMM تعسفية، بما في ذلك استخراج الملفات، وتفريغ بيانات الاعتماد، وتنفيذ الأوامر، وتغيير الإعدادات. يمكن للمهاجم أيضًا تعديل Server Address الخاص بـ RMM إلى خادم المهاجم، محققًا استمرارية خفية حتى بعد انتهاء هجوم AiTM. بدلاً من ذلك، يمكن استغلال RCE لتشغيل أوامر على مستوى النظام مباشرة.
Server Address يتضمن نقطة نهاية http://. لوحظت تهيئات قابلة للاستغلال من اثنين من مزوّدي الخدمات المُدارة المختلفة (مع استبدال نطاقات وعناوين IP الفعلية لمزوّدي الخدمة):
https://automate.msp-one.com|http://automate.msp-one.comhttps://msp.msp-two.com|http://msp.msp-two.com|http://12.346.6.78http:// كخيار احتياطي إذا فشل اتصال https://، لكن يمكن للمهاجم محاكاة ذلك عن طريق حظر https.يمكن تكوين وكيل Automate لاستخدام عنوان URL http:// كعنوان الخادم. من المحتمل أن يكون هذا الإعداد مضبوطًا بواسطة برنامج/حزمة التثبيت، ولكن يمكن التحقق منه عبر فحص مفتاح التسجيل HKLM\SOFTWARE\LabTech\Service\Server Address.

استخدام كل من نقطتي نهاية HTTPS وHTTP مفصولتين بشريط pipe | يضمن نظريًا أنه إذا واجه اتصال HTTPS مشكلة، فإن وكيل Automate سيعود إلى اتصال HTTP.
إذا تمكن المهاجم من الوصول إلى حركة المرور بين وكيل Automate والخادم بصفته وسيطًا (AiTM)، فيمكنه تعطيل اتصال HTTPS عمدًا، مما يؤدي إلى العودة إلى HTTP. يتيح ذلك للمهاجم اعتراض ومراقبة وتعديل حركة المرور المتبادلة بين الوكيل والخادم. يمكن للمهاجم بعد ذلك استخدام بروكسي عكسي لحركة المرور إلى https://automate.msp-one.com، مما يؤدي إلى "تشغيل قياسي" للوكيل، ولكن مع قدرة المهاجم على التنصت على البيانات. بالإضافة إلى ذلك، قد يحقن المهاجم الاستجابات أو يعدّلها، أو حتى ينشئ خادم Automate مزيفًا بالكامل يستجيب لطلبات وكيل Automate.
تم تحقيق ذلك عن طريق إعداد نقطة وصول Wi‑Fi "مارقة" (hostapd، dnsmasq، إعادة توجيه IP + NAT) واستخدام قواعد iptables لإعادة توجيه حركة المرور ونص برمجي لـ mitmproxy من أجل البروكسي العكسي.

بيانات أخرى أكثر حساسية، بما في ذلك البرامج قيد التشغيل، وتكوين الشبكة الكامل، ومسارات المستندات، لوحظت أحيانًا في استجابات وكيل Automate.
iptables -t nat -A PREROUTING -i wlx90916440139a -p tcp --dport 80 -j REDIRECT --to-port 8080 iptables -A FORWARD -i wlx90916440139a -p tcp --dport 443 -j DROP
#### سكربت mitmproxy:```python
# run with AiTMweb --mode transparent@8080 -s automate_AiTM.py
def request(flow: http.HTTPFlow):
if flow.request.pretty_host == 'automate.msp-one.com':
flow.request.url = 'https://automate.msp-one.com' + flow.request.path
يمكن لحلول ZTNA أن تعقّد هذا الاعتراض إلى حدٍّ ما، لكن تم تجاوزها بشكل موثوق بواسطة سكربتات mitmproxy إضافية تعمل على كشف ZTNA وحظره بشكل شرطي، مما يؤدي إلى الرجوع إلى HTTP بدون نفق.
يستخدم وكيل Automate بروتوكولًا مخصصًا يعمل فوق HTTP للتواصل مع الخادم.
يرسل وكيل RMM على الجهاز طلبات HTTP(S) بشكل دوري إلى نقطة النهاية /LabTech/agent.aspx الخاصة بالخادم. أنواع الطلبات ذات الصلة هي:
لاحظ أن عدم اتساق حالة الأحرف في المسارات ليس خطأً مطبعيًا؛ فهكذا يرسل وكيل Automate هذه الطلبات. جميع مسارات نقاط النهاية معروضة داخل علامات كود (backticks) للتوضيح.
/LabTech/Agent.aspx?DEPS ويتلقى استجابة XML تحتوي على قائمة بملفات التبعيات وأرقام إصداراتها ومجاميعها الاختبارية./LabTech/Agent.Aspx?DepCheck=1&DependancyId=<id> ويتلقى ملفًا ثنائيًا معتمًا يحتوي على التبعية، متنكرًا في هيئة ملف صورة (يُفترض أن التعتيم يهدف إلى منع مرشحات المحتوى من حظر التنزيل)./LabTech/agent.aspx?<id>?c<CMD id>&<arg count> ويتلقى استجابة معبأة بشكل مخصص تحتوي على بيانات خاصة بأمر معيّن.InitialCommandRetrieve)، وإرجاع نتائج الأوامر، وإجراء الدردشة.غالبًا ما يتم تشفير "الأوامر البعيدة" الحساسة باستخدام مخطط تشفير قائم على DES3 مع اشتقاق مخصص للمفتاح من system password وcomputer password المحددتين مسبقًا. بدون كلمات المرور الصحيحة، لا يمكن للمهاجم الاطلاع على الأوامر المشروعة المرسلة إلى الوكيل أو حقنها أو تعديلها؛ ومع ذلك، فإن استجابات الأوامر غير مشفرة، وقد لوحظ أنها تتضمن بشكل متكرر بيانات حساسة كنص واضح، بما في ذلك الملفات المفتوحة والمسارات وأسماء المستخدمين والبرامج المثبتة، وما إلى ذلك.
فحص التبعيات (/LabTech/Agent.aspx?DEPS) والتنزيلات (/LabTech/Agent.Aspx?DepCheck=1&DependancyId=<id>) غير مشفرة وغير موقعة، مما يعني أن المهاجم يمكنه تعديل الاستجابة لتضمين تبعيات خبيثة سيتم تنزيلها وتحميلها بواسطة وكيل RMM. إذا تم تزوير فحص التبعيات ليتضمن مجموعًا اختباريًا مختلفًا، فسيقوم وكيل RMM بإجراء تنزيل جديد لملف التبعية غير المتطابق وتحميله (شريطة أن يطابق الملف الذي تم تنزيله حديثًا المجموع الاختباري المزوّر). الإضافات هي تجميعات .NET تطبّق واجهة محددة، وسيقوم وكيل Automate بتحميل أي تجميع .NET يطابق واجهة الإضافة المتوقعة ثم يستدعي واجهة الإضافة، مما يؤدي إلى تنفيذ تعليمات برمجية.
يوجد مستوى ثانٍ من التحقق لتبعيات الإضافات التي يتم تنزيلها، حيث يرسل الوكيل أمر cmdGetPlugins ويتحقق أيضًا من تطابق المجموع الاختباري هنا، لكن هذا الأمر لا يستخدم مخطط التشفير.
باستخدام dnSpy، كان من الممكن حقن تعليمات برمجية خبيثة في ملف ScreenConnectRemotePlugin.dll الشرعي الذي يستخدمه الوكيل. تم إنشاء خادم Automate مخصص يحمل وظائف أوامر DEPS وDepCheck وcmdGetPlugins. قام الخادم المزوّر بتكرار الإضافات والتبعيات المتوقعة، لكنه عدّل التجزئة الخاصة بملف ScreenConnectRemotePlugin.dll إلى تجزئة محسوبة للإضافة المعدلة بشكل خبيث. كما وفّر الخادم المزوّر ملف ScreenConnectRemotePlugin.dll المعدل بشكل خبيث استجابةً لطلب DepCheck (بتنسيق الصورة المزوّرة المعتم) ونفّذ cmdGetPlugins أيضًا بالتجزئة المتلاعب بها. أخيرًا، تم تحديث سكربت mitmproxy لتوجيه وكيل Automate إلى الخادم المزوّر بدلاً من الخادم الشرعي (HTTPS).
عند الاتصال، يتم تنزيل الإضافة الخبيثة وتحميلها بواسطة الوكيل. تقوم التعليمات البرمجية المحقونة بتسريب كلمتي مرور "system" و"computer" إلى الخادم المزوّر. يتم تخزين كلمتي مرور system وcomputer في السجل (registry) لكن يتم فك تشفيرهما بواسطة مكتبة C# ومكتبة أصلية معتمتين بشدة. بدلاً من استخراج قيم السجل، تستخدم الإضافة المصححة الانعكاس (reflection) للحصول على القيم المفكوكة، مما يوفر عناء إجراء هندسة عكسية للتعتيم. بدلاً من ذلك، يمكن تسريب المحتويات الكاملة لمفتاح السجل HKLM\SOFTWARE\LabTech\Service واستخدامها مع نسخة من وكيل RMM في بيئة مُتحكم بها لاستخراج كلمات المرور أثناء التشغيل باستخدام مصحح أخطاء .NET.


بدلاً من ذلك، يمكن استخدام الإضافة لتنفيذ أوامر على مستوى النظام مباشرة؛ ومع ذلك، فإن استخراج الأسرار مكّن من استخدام وكيل RMM نفسه كقناة تحكم وأوامر (command-and-control) ويعني أن القناة الدائمة ظلت غير مكتشفة بواسطة EDR. يمكن الحصول على الثبات (persistence) عن طريق تحديث Server Address إلى خادم يتحكم فيه المهاجم، والذي يمكنه اختياريًا إعادة توجيه الأوامر إلى الخادم الشرعي لتجنب ظهور الجهاز كمفقود. انظر 3. الاستيلاء على التحكم والأوامر عبر RMM لمزيد من التفاصيل.
من المتوقع أنه حتى لو جاءت الإعدادات الافتراضية دون تثبيت أي إضافات، كان يمكن تجميع إضافة فارغة (تطابق واجهات C# المطلوبة للإضافات) وإدراجها في استجابتي DEPS وcmdGetPlugins لتحقيق التأثير نفسه.
كما لوحظ أن أمرًا "بعيدًا" يُسمى UpdatePlugins يمكن أن يُرجَع من الخادم، مما يدفع الوكيل إلى بدء تحديث للإضافات. نظرًا لأن الأوامر لا تتضمن حماية من إعادة الإرسال، فإذا تمكن المهاجم من مراقبة الأمر المُرسَل من خادم شرعي، يمكنه إعادة إرساله إلى أي وكلاء آخرين لبدء التحديث. وهذا يتيح استغلال ثغرة RCE في سيناريوهات إضافية، مما يزيد من تأثير هذه الثغرة.
كما لوحظ أن التحديث الذاتي غير مشفر وغير موقّع. لم يتم تقديم عرض عملي لتنفيذ التعليمات البرمجية عن بُعد عبر التحديث الذاتي، لكن يُعتقد أنه عرضة للثغرات بالمثل. سيكون التعديل الخبيث للتحديث الذاتي أكثر صعوبة في التنفيذ بشكل متخفٍ وينطوي على مخاطر أكبر لكسر وكيل Automate؛ ومع ذلك، فمن المرجح أن أسلوبًا مشابهًا لحقن تعليمات .NET البرمجية في الملفات التنفيذية/مكتبات DLL سينجح. لم يتم استكشاف عملية التحديث الذاتي بشكل أعمق لأن ثغرة RCE عبر الإضافات كانت كافية وتُعتبر أكثر موثوقية.
من الممكن أيضًا أن يكون استغلال عملية التحديث الذاتي حلاً قابلاً للتطبيق للقيد الذي يجعل الثغرة قابلة للاستغلال فقط عند إعادة التشغيل (على سبيل المثال، إذا كان يمكن حقن استجابة أو إعادة إرسالها لبدء تحديث ذاتي).
باستخدام الأسلوب الموضح في 2.1 لاستخراج system password وcomputer password، كان من الممكن إنشاء حمولات واستجابات عشوائية لأوامر "بعيدة". بدلاً من إجراء هندسة عكسية كاملة وإعادة تنفيذ مخطط اشتقاق المفتاح، كان من الممكن ببساطة استيراد LabTechCommonBase.dll واستخدام Utilities.LabTechHash.ComputeHash لتوليد مفتاح DES3 من "computer password". وباستخدام مفتاح DES المحسوب وقيمة IV الثابتة (hardcoded) المستخرجة من ملف DLL، أصبح من الممكن بعد ذلك الاستجابة بأوامر عشوائية لوكيل RMM.```python
# IV extracted from decompiled LabTechSecurity.cs:
# this._initializationVector = new byte[] { 240, 3, 45, 29, 0, 76, 173, 59 };
iv = [240, 3, 45, 29, 0, 76, 173, 59]
# Helper functions for pythonnet, clr_loader, clr to load LabTechCommonBase.dll into python
labtech_net.setup_paths_and_references(str((Path(__file__).parent.parent / 'LTSvc').resolve()))
from LabTechCommonBase import Utilities
labtech_hash = Utilities.LabTechHash()
labtech_hash.ComputeHash(computer_password.encode('ascii')) # Use the exfiltrated computer password
byts = bytes(labtech_hash.GetDigestBytes())
cipher = DES3.new(byts, DES3.MODE_CBC, bytes(iv))
padded_data = pad(data.encode('utf-8'), DES3.block_size)
encrypted_data = cipher.encrypt(padded_data)
return base64.b64encode(encrypted_data).decode('utf-8')
تم تنفيذ معالجات لمجموعة متنوعة من أنواع "أوامر الوكيل" في خادم Automate الوهمي، مما يسمح له بإرسال "أوامر عن بُعد" مرة أخرى إلى الوكيل. يمكن استخدام هذه الأوامر لتشغيل كود عشوائي على الجهاز، مثل تنزيل حمولة وتنفيذها، أو إنشاء أنفاق شبكة إلى الجهاز (على سبيل المثال، إعداد بروكسي SOCKS يمكن استخدامه للتنقل عبر وصول ZTNA الخاص بالجهاز).

للتنظيف الفوري من 2.1، يمكن للخادم إرسال أمر `UpdatePlugins` المشفَّر وتقديم الإضافة الأصلية الشرعية لتجاوز الإضافة المعدلة بشكل خبيث. لا يزال بإمكان المهاجم التفاعل مع الوكيل (بافتراض استخراج كلمات المرور) ويمكنه الحفاظ على الاستمرارية عن طريق تحديث `Server Address` إلى خادم تحت سيطرة المهاجم.
كما تم إثبات التنفيذ العشوائي للأوامر باستخدام أمر `Execute` لتشغيل ping، والذي تم تنفيذه بنجاح على الجهاز في سياق مسؤول. يمكن تقديم هذا كأمر `InitialCommandRetrieve` أو إرجاعه استجابةً لأوامر الوكيل الأخرى/تسجيلات الوصول.```python
# Extract the RemoteCommandIDs enum from LabTechCommonBase.Constants using pythonnet
REMOTE_CMD_IDS = get_RemoteCommandIDs()
REMOTE_CMD_IDS_r = {str(v): k for k, v in REMOTE_CMD_IDS.items()}
# `register_cmd_handler` registers a command handler for the `/LabTech/agent.aspx?c<id>` endpoint.
# The string 'InitialCommandRetrieve' is mapped back to ID `36`.
# The full set of "Agent Command" and their IDs can be extracted from `LabTechCommonBase.Constants.modEnums.AgentCommandIDs`
@register_cmd_handler('InitialCommandRetrieve')
async def initial_command_retrieve(_req: dict) -> str:
cmd = '*!*'.join([
'202706506',
str(REMOTE_CMD_IDS_r['Execute']),
'!!!'.join([
'CMD.exe',
'/c ping -t -l 1337 192.168.20.2'
])
])
encrypted_cmd = encrypt(cmd)
return '|||'.join([
len_b64_gzip( # Simple helper to return '{len(data)}-{base64(gzip(data))}'
encrypted_cmd
),
# Generate common [latest-version, FILETIME(), queued command(s), MD5 hashes] encoding string expected in "agent command" responses
make_p2(),
])

استخدام -l 1337 يوجّه ping لاستخدام حجم حمولة قدره 1337 بايت، وهو ما يُلاحَظ في لقطة الشاشة الثانية (1337 بايت حمولة + 42 بايت ترويسة = 1379 بايت إجمالاً) كـ"كناري".
تمت إزالة هذا القسم من الإفصاح العام.