
أدوات كشف وتخفيف وهندسة عكسية لثغرة CVE-2026-41940 (SessionScribe): ثغرة تزوير الجلسات غير المصادَق عليها في cPanel/WHM والتي أُفصِح عنها في 2026-04-28. تتضمن حاجز تخفيف نشط للدفاع المتعمق، وحزمة قواعد ModSec، ومسبارًا عن بُعد، وماسح مؤشرات الاختراق (IOC) على المضيف، ومجمّع لقطات الهندسة العكسية لكل طبقة. GPL v2.
ثغرة RCE حرجة غير مصادق عليها في cPanel وWHM. أربعة طلبات HTTP تزوّر جلسة جذر عبر حقن CRLF في حقل كلمة المرور لجلسة ما قبل المصادقة. لا مصادقة، لا شروط مسبقة، جميع الفئات المدعومة متأثرة. تم الإفصاح عنها في 2026-04-28 بواسطة Sina Kheirkhah / مختبرات watchTowr.
البدء السريع · ioc-scan · mitigate · remote-probe · الإصدارات المتأثرة · ترتيب الأولوية
[!IMPORTANT] الفئات 112، 114، 116، 120، 122، 128 لا يوجد لها تصحيح من المورّد. كل إصدار على هذه الفئات معرّض للخطر؛ الترقية أو الترحيل هو الإصلاح الوحيد الدائم. وإلى ذلك الحين: قيّد المنافذ TCP/2082, 2083, 2086, 2087, 2095, 2096 أمام نطاقات الإدارة المرخّصة (
mitigate.sh --applyيقوم بذلك) وقدّم بقية السطح بحزمة قواعد ModSec.
ثلاثة أسطر أوامر مفردة، حسب ترتيب أولوية المشغّل:```bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --apply
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh | bash -s -- --target HOST
رموز الخروج مصممة لأتمتة الأساطيل: يُخرج `ioc-scan` `4` عند
اختراق (COMPROMISED)، و`1` عند وجود ثغرة (VULNERABLE)؛ بينما يُخرج `mitigate` `0` نظيف / `1` مطبق
/ `2` يدوي / `3` خطأ في الأداة؛ ويُخرج `remote-probe` `2` إذا كان أي هدف
به ثغرة (VULN).
---
## الأدوات
مرتبة حسب الأولوية التشغيلية. كل أداة تُخرج مخرجات منظمة
(`--json` / `--jsonl` / `--csv`) مفتاحية على `host`, `os`, `cpanel_version`,
`ts` لتجميع الأسطول.
| الأداة | الدور | مكان التشغيل |
|---|---|---|
| **[`sessionscribe-ioc-scan.sh`](#sessionscribe-ioc-scansh---ioc-ladder--kill-chain)** | فرز من الدرجة الأولى. سلم مؤشرات الاختراق (IOC)، أحكام حالة الكود + حالة المضيف، إعادة بناء سلسلة القتل، حزمة الاستجابة للحوادث (IR). | على مضيف cPanel |
| **[`sessionscribe-mitigate.sh`](#sessionscribe-mitigatesh---mitigation-orchestrator)** | أغلق النافذة. تخفيف مرحلي: فحص التصحيح، جدار الحماية، استبدال الوكيل، ModSec. | على مضيف cPanel |
| **[`sessionscribe-remote-probe.sh`](#sessionscribe-remote-probesh---non-destructive-fleet-probe)** | دعم إضافي. فحص غير إتلافي من 4 مراحل → VULN/SAFE لكل مضيف. | في أي مكان يتوفر فيه `curl` |
| [`modsec-sessionscribe.conf`](#supporting-collateral) | حزمة قواعد ModSec التي ينشرها `mitigate`. | واجهة Apache الأمامية |
| [`sessionscribe-revsnap.sh`](#supporting-collateral) | جامع لقطات RE لكل طبقة لمقارنة ثنائيات. | على مضيف cPanel، حول `upcp` |
رخصة GPL v2. جميع الأدوات جاهزة للتنزيل عبر `curl` من روابط المصدر أعلاه.
---
## `sessionscribe-ioc-scan.sh` - سلم مؤشرات الاختراق + سلسلة القتل
**شغّل هذا أولًا.** الكشف فقط افتراضيًا (سريع ومناسب للأساطيل)؛
أضف `--full` لتشغيل مراحل الطب الشرعي مباشرة (الخط الزمني للدفاع، إدخال الهجوم،
المطابقة، عرض سلسلة القتل، حزمة الاستجابة للحوادث).```bash
# fast triage (detection only)
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash
# full kill-chain reconstruction inline
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash -s -- --full
# full + ship IR bundle to intake
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash -s -- --full --upload
# JSONL for SIEM ingest
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash -s -- --jsonl --quiet > host.jsonl
# host IOCs only - periodic post-patch sweep, last 7 days
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash -s -- --ioc-only --since 7
# replay forensic phases against a saved envelope (no re-scan)
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh | bash -s -- --replay /var/cpanel/sessionscribe-ioc/<run_id>.json
يُصدِر المحوران نتائجهما بشكل مستقل. تأتي code_verdict (PATCHED / VULNERABLE / INCONCLUSIVE) من الإصدار، وأنماط Perl المصدرية، وبصمة ثنائي cpsrvd. وتأتي host_verdict (CLEAN / SUSPICIOUS / COMPROMISED) من سُلَّم مؤشرات IOC في ملف الجلسة، وفحص سجل الوصول، واختبارات التدمير للأنماط A–G. يمكن لمضيف مُرقَّع أن يخرج برمز 4 إذا كان الاستغلال السابق قد ترك مؤشرات IOC على القرص.
الجلسات الموسومة بـ nxesec_canary_<nonce> (التي يتركها المسبار البعيد) تُصنَّف كـ PROBE_ARTIFACT ولا تُرقَّى إلى COMPROMISED.
يجمع --full كل مؤشر IOC مقابل عمليات تفعيل الدفاع ويصنّف كلًا منها كـ PRE-DEFENSE أو POST-DEFENSE أو POST-PARTIAL أو UNDEFENDED، ثم يلخّص ذلك بعنوان رئيسي يجمع الحكم وفارق زمن الدفاع.
PRE-DEFENSE = كان المضيف مفتوحًا للاستغلال عند وصول المؤشر؛ POST-DEFENSE = ضرر جانبي أو ضوضاء ما قبل التخفيف.```
+-- CVE-2026-41940 / IC-5790 --------------------------------------------
| host cpanel.example.com ()
| cpanel unknown os unknown
| verdict COMPROMISED score 315 ioc-scan v2.5.0
| defenses patch x absent modsec + up csf + clean mitigate + ran
+------------------------------------------------------------------------
| -- PRE-DEFENSE (32 events) -- | 2026-03-25T09:43:19Z ! pattern X ioc_attacker_ip_2xx_on_cpsess 57 hit(s) (last 90d) from IC-5790 IPs returned 2xx on /cpsess/ paths - real exploitation | 2026-04-28T14:35:56Z ! pattern X ioc_cve_2026_41940_crlf_access_chain 15 CRLF-bypass chain(s) — POST /login 401 then GET /cpsess 2xx as root within 2s | 2026-04-28T16:38:45Z ! pattern E ioc_pattern_e_websocket_shell_hits 45 external IP(s) reached /cpsess*/websocket/Shell with 2xx | 2026-04-29T08:41:22Z ! pattern F ioc_pattern_f_smark_envelope S_MARK/E_MARK harvester envelope in /root/.bash_history | 2026-04-29T16:41:24Z ! pattern A ioc_pattern_a_ransom_readme /home/user1/README.md | … (22 more Pattern A ransom_readme events across customer homedirs) | 2026-04-29T16:42:09Z ! pattern A ioc_pattern_a_sorry_files_present 608 .sorry-encrypted files present | 2026-04-29T17:52:58Z ! pattern D ioc_pattern_d_acctlog_encrypted /var/cpanel/accounting.log.sorry
| -- DEFENSES -- | 2026-04-29T23:48:21Z + DEFENSE mitigate_first sessionscribe-mitigate.sh first run | 2026-04-29T23:48:21Z + DEFENSE csf csf.conf cpsrvd ports stripped | 2026-04-29T23:48:46Z + DEFENSE modsec modsec rule 1500030 installed
| -- POST-PARTIAL (1 event) -- | 2026-04-30T12:23:42Z ! pattern E ioc_pattern_e_handoff_burst_present 3 distinct external IPs each minted cpsess + reached websocket Shell within 15-min window
| HEADLINE | verdict COMPROMISED (score 315) | defense lag 37d 9h LATE (first IOC 2026-03-25T09:43:19Z, defense up 37d 9h later)
<details>
<summary><b>مرجع الفحوصات + مراحل التحليل الجنائي + بنية الحزمة</b> (انقر للتوسيع)</summary>
| الفحص | ماذا يفعل |
|---|---|
| `version` | `cpanel -V` مقارنةً بقائمة الإصدارات المعدّلة المنشورة - يوجّه `code_verdict` |
| `static-pattern` | يبحث في `Cpanel/Session/*.pm` عن أنماط الحارس بعد التصحيح (فرع فك الترميز `no-ob:`) |
| `cpsrvd-fingerprint` | فحص ملف cpsrvd الثنائي مقابل توقيعات الإصدارات المعدّلة |
| `access-log` | سجلات Apache + cpsrvd لأنماط حركة مرور الاستغلال (`--no-logs` للتخطي) |
| `session-store` | اجتياز `/var/cpanel/sessions/raw/`: مؤشرات الاختراق الخاصة بالمورّد + الترافق الرباعي + استدلال الطابع الزمني المزوّر (`--no-sessions` للتخطي) |
| `destruction` | فحوصات الأنماط A–G: مشفّر `/root/sshd`، mysql-wipe، فهرس BTC، `nuclear.x86`، موزّع `sptadm`، حاصد `__S_MARK__`، مفاتيح SSH مشبوهة (`--no-destruction-iocs` للتخطي) |
| `probe` (اختياري) | طلب GET بعلامة واحدة إلى `127.0.0.1:2087` - يؤكد استجابة cpsrvd. **لا** يحاول تنفيذ التحايل |
**مراحل التحليل الجنائي `--full`** (تُنفَّذ مباشرةً بعد الكشف):
| المرحلة | ماذا يفعل |
|---|---|
| `defense` | يضع طابعًا زمنيًا على كل طبقة دفاعية تم تطبيقها: تصحيح cpanel، إعادة تشغيل cpsrvd بعد التصحيح، عمليات تشغيل mitigate، قواعد ModSec، إغلاق منافذ CSF/APF، proxysub، ملخص `upcp` |
| `offense` | يضع طابعًا زمنيًا على كل مؤشر اختراق تم رصده (الأنماط A–G + سلسلة تجاوز CRLF للنمط X) |
| `reconcile` | لكل مؤشر: هل كان الدفاع المعني نشطًا عند ظهوره لأول مرة؟ PRE-DEFENSE / POST-DEFENSE / POST-PARTIAL / UNDEFENDED + الفارق الزمني |
| `bundle` | أرشيف tar للأدلة الخام داخل `/root/.ic5790-forensic/<TS>-<RUN_ID>/`، بالصلاحية `0700` |
**بنية الحزمة** (`/root/.ic5790-forensic/<TS>-<RUN_ID>/`):```
manifest.txt host/uid/cpv/run_id/window/cap
sessions.tgz /var/cpanel/sessions/{raw,preauth} (filtered)
access-logs.tgz cpsrvd access + incoming_http_requests + error_log
+ global Apache access/error (NO domlogs)
system-logs.tgz /var/log/{secure,messages,audit/audit.log,auth.log}*
cpanel-state.tgz accounting.log + resellers + cpanel.config + api_tokens_v2
cpanel-users.tgz /var/cpanel/users/ (split out, per-account state)
persistence.tgz ssh keys + all cron tiers + systemd/init.d/profile.d
+ rc.local + root histories + passwd/group + sudoers
defense-state.tgz mitigate backups + csf/apf/modsec configs + updatelogs
ps.txt / connections.txt / iptables.txt
pattern-a-binary-metadata.txt only if /root/sshd present (metadata; binary NOT bundled)
user-histories/ per-user .bash_history (gated on --no-history)
الحزمة النموذجية على مضيف مزدحم ضمن نافذة الـ 90 يومًا: ~250 ميجابايت – 2 جيجابايت مضغوطة.
سقف 2 جيجابايت لكل tarball (--max-bundle-mb) يستبعد المرشّحين المتجاوزين للحد الأقصى للحجم بشكل فردي.
يُكتب سجلّ التشغيل إلى /var/cpanel/sessionscribe-ioc/ افتراضيًا
(--no-ledger لتعطيله). --chain-forensic / --chain-on-critical /
--chain-upload محفوظة كأسماء مستعارة للتوافق الخلفي مع الإصدار v1.x.
تجاوزات اختبار اللقطات للتحليل الجنائي دون اتصال على ملفات tarball المستخرجة:
--root DIR, --version-string S, --cpsrvd-path P. راجع --help للحصول على
القائمة الكاملة للخيارات.
sessionscribe-mitigate.sh - منسّق التخفيفللقراءة فقط افتراضيًا (--check). أضِف --apply لتعديل الحالة.
تطابقية (Idempotent): إعادة التشغيل على مضيف سليم لا تنفّذ أي عملية (no-op). تكتب عمليات التعديل
نسخًا احتياطية مختومة بطابع زمني تحت /var/cpanel/sessionscribe-mitigation/
قبل لمس أي ملف.```bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --apply
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --apply --only modsec --probe curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --only patch,preflight # pre-upcp gate
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --csv > host.csv curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --jsonl > host.jsonl
| المرحلة | الوظيفة |
|---|---|
| `patch` | `cpanel -V` مقابل قائمة الإصدارات المرقَّعة المنشورة (بما في ذلك EL6 11.86.0.41، EL6/CL6 110.0.103، tier 124، WP² 136.1.7) |
| `preflight` | يزيل `/etc/yum.repos.d/threatdown.repo`؛ يضمن `epel-release`؛ يعطّل المستودعات غير الأساسية المعطوبة حتى لا تتعطل `upcp` في منتصف التنفيذ |
| `upcp` | إذا لم يكن مرقَّعًا، يشغّل `/scripts/upcp --force --bg` |
| `proxysub` | يفعّل `proxysubdomains` + نسخة الحسابات الجديدة؛ يعيد بناء إعداد httpd |
| `csf` / `apf` / `runfw` | يزيل منافذ cpsrvd (2082/2083/2086/2087/2095/2096) من `TCP_IN`/`TCP6_IN`/`IG_TCP_CPORTS`؛ يتحقق من سلسلة INPUT الفعلية في iptables |
| `apache` | `httpd` قيد التشغيل + `security2_module` محمّل |
| `modsec` | `modsec2.user.conf` يحتوي على القاعدتين `1500030` + `1500031`؛ يتم نشرهما إذا كانتا مفقودتين (نسخة احتياطية بختم زمني، تحقق `httpd -t`، إعادة تحميل سلسة) |
| `probe` (اختياري) | يشغّل `sessionscribe-remote-probe.sh` على `127.0.0.1` لتأكيد الرفض عمليًا |
مستودعات CentOS / Alma / Rocky base/appstream/extras/updates/powertools
لا يتم تعطيلها **أبدًا** بواسطة `preflight`، حتى لو كانت غير قابلة للوصول حاليًا.
### رموز الخروج
| رمز الخروج | المعنى |
|---|---|
| 0 | سليم - مرقَّع + الوضعية جيدة، لا حاجة لأي إجراء |
| 1 | تم تطبيق الإصلاح بنجاح (`--apply` أحدث تغييرات) |
| 2 | تدخّل يدوي مطلوب (يحذّر في `--check`، ويفشل في `--apply`) |
| 3 | خطأ في الأداة (وسائط غير صحيحة، تبعيات مفقودة، عدم كونك root لـ `--apply`) |
اختيار المراحل: `--only LIST`, `--no-PHASE`, `--no-fw` (اختصار لـ
`--no-csf --no-apf --no-runfw`). الإخراج: `--json` / `--jsonl` / `--csv`,
`-o FILE`. انظر `--help` للقائمة الكاملة للخيارات.
### فحص سموك لمدة ستين ثانية```bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --list-phases # surface the phase API
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh | bash -s -- --check # safe read-only audit
echo "exit=$?" # 0 on a non-cPanel host
يكتشف المُنسِّق مضيفًا غير تابع لـ cPanel ويخرج بشكل نظيف — مما يُثبت خاصية idempotency دون الحاجة إلى مختبر.
sessionscribe-remote-probe.sh - استطلاع أسطول غير تدميريمواد داعمة. يشغّل سلسلة المراحل الأربع بشكل غير تدميري
ضد هدف: إنشاء جلسة preauth → حقن CRLF → نشر raw→cache →
التحقق عبر /json-api/version، ثم يسجّل الخروج بنشاط. الإشارة
المُحدِّدة للحكم هي رمز HTTP في المرحلة 4: 200، أو 5xx مع نص
ترخيص، تعني VULN؛ بينما 401 أو 403 تعني SAFE.
كل جلسة اختبار تُوسَم بسمة nxesec_canary_<nonce>
لأغراض التنظيف الجنائي، ولا يتم إجراء أي استدعاءات API تُغيّر الحالة.
الجلسات المزوّرة تعادل صلاحيات root لمدة ~1–3 ثوانٍ بين المرحلة 3
وتسجيل الخروج في المرحلة 5 — راجع رأس السكربت لنموذج الأمان الكامل.```bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh | bash -s -- --target 1.2.3.4
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh | bash -s -- --target 1.2.3.4 --proxy example.com
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh
| bash -s -- --csv $(awk '{print "--target "$1}' fleet.txt) > fleet.csv
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh | bash -s -- --target 1.2.3.4 --fingerprint-only
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh | bash -s -- --cleanup
Output modes: pretty (الافتراضي)، `-q`/`--quiet`، `--oneline`، `--csv`،
`--json`. رموز الخروج: `0` لا يوجد VULN، `1` غير حاسم فقط، `2`
واحد أو أكثر من VULN. انظر `--help` للحصول على القائمة الكاملة للخيارات بما في ذلك
دلالات `--auto-host-discover` و`--all` و`--fingerprint-only`، و
وضع `--no-verify` الخاص بالمرحلة الثانية فقط (قديم، يُنتج نتائج إيجابية خاطئة على المضيفات
المحدّثة).
---
## مواد مساندة
### `modsec-sessionscribe.conf` - حزمة قواعد ModSecurity
يتم نشرها تلقائيًا بواسطة `mitigate.sh --apply --only modsec`. التثبيت اليدوي:```bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/modsec-sessionscribe.conf \
| sudo tee /etc/apache2/conf.d/modsec/modsec2.user.conf >/dev/null
sudo apachectl -t && sudo /usr/local/cpanel/scripts/restartsrv_httpd
نطاق المعرّفات المحجوز: 1500000–1500099. تستخدم قواعد رمز WHM
@ipMatch مقابل قائمة ثقة يحددها المشغّل — عدّل نطاقات CIDR في أعلى
الملف قبل النشر.
[!IMPORTANT] تعمل هذه القواعد داخل Apache. يستمع
cpsrvdمباشرة على 2082/2083/2086/2087/2095/2096 ويمكن الوصول إليه بشكل مستقل عن Apache. اقرن حزمة القواعد بجدار حماية لمنافذ cpsrvd على نطاقات إدارة CIDR.
sessionscribe-revsnap.sh - مجمع لقطات REيلتقط أرشيف tarball لكل طبقة (الملفات الثنائية، السلاسل، dynsym،
disasm، وحدات Perl، تخطيط وقت التشغيل) لمقارنة ثنائية عبر ترقيات
cPanel. مبني حول upcp لالتقاط أزواج ما قبل/ما بعد التصحيح.```bash
curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-revsnap.sh | bash
/scripts/upcp --force curl -fsSL https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-revsnap.sh | bash
يعمّم ما يتجاوز SessionScribe: كل CVE مستقبلي في cpsrvd سيقع في نفس السطح تقريبًا، وزوج حزمة tarball للإصدار قبل التصحيح وبعده هو الفرق بين ساعات وأيام من التحليل.
انظر [مقالة البحث](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940) للشرح الكامل للهندسة العكسية (RE).
---
## استخدام الأسطول
> [!TIP]
> كل أداة تُصدر مخرجات منظمة (`--json`, `--jsonl`, `--csv`) مع `host`, `os`, `cpanel_version`, `ts` في كل سجل. صُمّمت للتجميع عبر `pdsh | jq` أو `ansible -m script` عبر مئات المضيفين في تمريرة واحدة.
نفس أسلوب curl-piped-bash الأساسي — دع كل مضيف يجلب وينفّذ أحدث سكربت مباشرة:```bash
IOC=https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-ioc-scan.sh
MIT=https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-mitigate.sh
PRB=https://raw.githubusercontent.com/rfxn/cpanel-sessionscribe/main/sessionscribe-remote-probe.sh
# IOC scan across fleet, JSONL to SIEM
for h in $(cat fleet.txt); do
ssh "$h" "curl -fsSL $IOC | bash -s -- --jsonl --quiet"
done | jq -c '.' > fleet-ioc.jsonl
# kill-chain reconciliation across fleet (no bundles on broad sweep)
ansible -i hosts cpanel -m shell \
-a "curl -fsSL $IOC | bash -s -- --full --no-bundle --jsonl" > fleet-forensic.jsonl
jq -r 'select(.phase=="summary" and .key=="verdict"
and .note=="COMPROMISED_PRE_DEFENSE") | .host' \
fleet-forensic.jsonl > pre-defense-hosts.txt
# bundle collection on the pre-defense subset
ansible -i pre-defense-hosts.txt all -m shell \
-a "curl -fsSL $IOC | bash -s -- --full --jsonl --bundle-dir /root/.ic5790-forensic"
# mitigation posture roll-up
pdsh -w cpanel-fleet "curl -fsSL $MIT | bash -s -- --jsonl --quiet" \
| jq -c 'select(.severity != "info")' > fleet-mitigate.jsonl
# remote probe sweep - exit 2 on any VULN (run from operator workstation)
curl -fsSL $PRB | bash -s -- --csv --quiet \
$(awk '{print "--target "$1}' fleet.txt) > fleet-probe.csv
المسبار آمن للأساطيل بشكل مستقل (جلسات موسومة بعلامة كناري، تسجيل خروج
نشط، لا مكالمات API تغيّر الحالة). النصوص البرمجية على المضيف تحترم
--quiet + علامات المخرجات المهيكلة بحيث يكون stdout نظيفًا للمحلل.
أربعة طلبات HTTP، بدون مصادقة، بدون شروط مسبقة:```mermaid sequenceDiagram autonumber actor A as attacker participant C as cpsrvd participant S as session file A->>C: POST /login/?login_only=1 with user=root, pass=wrong C-->>A: Set-Cookie · whostmgrsession=NAME,OBHEX A->>C: GET / · Authorization Basic b64(root:x + CRLF payload) · Cookie minus OBHEX C->>S: writes pass=x, user=root, hasroot=1, ... (CRLFs land verbatim) C-->>A: HTTP 307 · Location /cpsess[10digits]/ A->>C: GET /scripts2/listaccts · cookie only C->>S: propagate raw to cache · forged keys now readable C-->>A: 401 token denied (side-effect already done) A->>C: GET /cpsess[token]/json-api/version C-->>A: 200 OK means VULN · 403 means SAFE
النتيجة هي رمز HTTP عند الطلب الرابع. ملف الجلسة المخزَّن على القرص في `/var/cpanel/sessions/raw/<sessname>` هو الأثر الوحيد للفحص الجنائي بعد وقوع الاستغلال. الآلية الكاملة (عدمَي التماثل المكوّنين لها — عدم وجود `filter_sessiondata` في كل مسارات الكتابة، والمشفّر يختصر المسار عند غياب `ob_part`) والحجة المعمارية لفرض الرقابة عند نقطة نهاية الوكيل موجودة في [المقال البحثي](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940).
---
## مؤشرات الاختراق
شكل ملف الجلسة المزور (`/var/cpanel/sessions/raw/<sessname>` بعد الاستغلال):```
local_port=2087
hasroot=1
hulk_registered=1
pass=x
origin_as_string=address=127.0.0.1,app=whostmgrd,method=badpass
token_denied=1
local_ip_address=127.0.0.1
external_validation_token=cS9C19OfV0hCA4uD
cp_security_token=/cpsess6844364556
ip_address=127.0.0.1
user=root
tfa_verified=1
successful_internal_auth_with_timestamp=9999999999
port=39040
login_theme=cpanel
لا تحتوي جلسة ما قبل المصادقة العادية أبدًا على pass=، hasroot=1،
user=root، tfa_verified=1، أو
successful_internal_auth_with_timestamp=. أيٌّ من تلك القيم مجتمعة مع
origin_as_string=…method=badpass يُعد مؤشرًا تشخيصيًا. قيمة طابع زمني
مزوَّر تتجاوز now+365d (مثل 9999999999) تُعد مؤشرًا تشخيصيًا مستقلًا.```bash
for f in /var/cpanel/sessions/raw/*; do
[ -f "$f" ] || continue
if grep -q '^token_denied=' "$f"
&& grep -q '^cp_security_token=' "$f"
&& grep -q '^origin_as_string=.*method=badpass' "$f"; then
echo "IOC0 hit: $f"
fi
done
إشارة سجل الوصول: استجابات ناجحة `200`/`302`/`307` على
مسارات `/json-api/` أو `/execute/` أو `/scripts2/` من عناوين IP
مصدرية غير خط الأساس دون وجود استجابة `/login/` 200 سابقة
في نفس نافذة الجلسة.
---
## البنى المتأثرة```
11.86.0.41 (EL6/CL7) 11.110.0.97 11.118.0.63 11.124.0.35
11.126.0.54 11.130.0.19 11.132.0.29 11.134.0.20
11.136.0.5 110.0.103 (EL6/CL6 from .50)
WP Squared: 136.1.7
المستويات المستبعدة من قائمة تصحيحات البائع ليست لها إصلاح موضعي: 112، 114، 116، 120، 122، 128. يجب ترقية المضيفات على تلك المستويات إلى سلسلة رئيسية مصححة، أو ترحيلها، أو حظر مستمعي cpsrvd لديها بجدار ناري حتى يتم ذلك.
تمت إضافة 11.86.0.41 (EL6/CL7) في مراجعة نشرة 04/29؛ وتم رفع 11.130
من .18 إلى .19 في نفس المراجعة. أضافت مراجعة لاحقة
11.124.0.35 (لسدّ الفجوة السابقة على المستوى 124) و
110.0.103 كهدف ترقية مباشر لمضيفات EL6/CL6 التي لا تزال على
v110.0.50.
عاجل
sessionscribe-ioc-scan.sh على كامل الأسطول. يمكن أن يظل المضيف المصحح
مخترقًا.لاحقًا
modsec-sessionscribe.conf داخل modsec2.user.conf مع
ضبط قائمة الثقة @ipMatch.الحالة المعمارية لفرض نقطة النهاية عبر الوكيل هي الثلث الأخير من المقال البحثي.
cpsrvd أو cpsrvd.so أو
Cpanel/Session/*.pm. إن النقل الخلفي الصادر من cPanel لمستواك هو
الإصلاح الفعلي.proxysub + جدار الحماية في المنسّق إلى جانب
حزمة قواعد ModSec على تقليل نصف قطر الانفجار؛ الترقية أو الترحيل هو
الحل الوحيد الدائم.nxesec_canary_<nonce>
للتنظيف، ويقوم بتسجيل الخروج بنشاط.ioc-scan آثار الاستغلال
السابق؛ لكنه لا يعالجها. تعامل مع نتيجة COMPROMISED
كمحفز للاستجابة الكاملة للحوادث، وليست استنتاجًا نهائيًا.[!TIP] اكتشفت خللًا، أو IOC مفقودًا، أو إيجابية كاذبة، أو لديك ملاحظات تشغيلية؟ افتح مشكلة على GitHub - تقارير الأخطاء، واختلافات IOC التي شوهدت في البرية، وفشل الاكتشاف على المضيفات المصححة وغير المصححة، والإيجابيات الكاذبة لقواعد ModSec، وملاحظات المشغّلين العامة، كلها مرحب بها.
يجب إرسال الإفصاحات الحساسة (أدلة استغلال حية، بيانات عملاء، سلاسل استغلال جديدة غير معلنة بعد) عبر Keybase أو البريد الإلكتروني، وليس عبر GH Issues.
GPL v2. راجع ترويسات الملفات الفردية.
طُوّر أثناء الاستجابة لحادثة SessionScribe - ريان ماكدونالد، شبكات R-fx.
| رمز الخروج | حالة الكود | حالة المضيف | إجراء الفرز |
|---|
| 0 | CLEAN/PATCHED | CLEAN | لا شيء |
| 1 | VULNERABLE | (أي) | رقّع cpsrvd |
| 2 | INCONCLUSIVE | (أي) | مراجعة يدوية لحالة الكود (أيضًا: خطأ في الأداة) |
| 3 | (أي) | SUSPICIOUS | راجع سجلات الجلسة/الوصول |
| 4 | (أي) | COMPROMISED | تحقيق كامل في الحادث؛ حزّم وارفع |
| القاعدة | السطح | الإجراء |
|---|
1500030 | CRLF داخل حمولة Authorization: Basic المفكوكة | رفض، جميع المصادر، جميع المسارات |
1500031 | كعكة whostmgrsession تفتقد لاحقة ,OBHEX صالحة | رفض (دفاع متعمق) |
1500010 | Authorization: WHM على /json-api/ و /execute/ و /acctxfer*/ | رفض عندما لا يكون المصدر في قائمة الثقة |
1500020 | Authorization: WHM على عائلة توزيع WebSocket | رفض عندما لا يكون المصدر في قائمة الثقة |
1500021 | Authorization: WHM على مسار توزيع SSE | رفض عندما لا يكون المصدر في قائمة الثقة |