
Инструментарий для обнаружения, нейтрализации и реверс-инжиниринга CVE-2026-41940 (SessionScribe): уязвимость подделки сессии без аутентификации в cPanel/WHM, раскрытая 2026-04-28. Активный шим нейтрализации для эшелонированной защиты, пакет правил ModSec, удалённый зонд, сканер IOC на хосте и коллектор RE-снимков для каждого уровня. GPL v2.
Критическая RCE без аутентификации в cPanel и WHM. Четыре HTTP-запроса создают поддельную root-сессию через CRLF-инъекцию в поле пароля preauth-сессии. Без аутентификации, без предусловий — затронуты все поддерживаемые тиры. Раскрыто 2026-04-28: Sina Kheirkhah / watchTowr Labs.
Быстрый старт · ioc-scan · mitigate · remote-probe · Затронутые сборки ·
[!IMPORTANT] Тиры 112, 114, 116, 120, 122, 128 не имеют патча от вендора. Каждая сборка на этих тирах уязвима; обновление или миграция — единственное надёжное решение. А пока: ограничьте порты TCP/2082, 2083, 2086, 2087, 2095, 2096 до management CIDR (
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, вердикты о состоянии кода и хоста, реконструкция kill-chain, IR-пакет. | на хосте cPanel |
| **[`sessionscribe-mitigate.sh`](#sessionscribe-mitigatesh---mitigation-orchestrator)** | Закрывает окно атаки. Поэтапная митигация: проверка патчей, firewall, proxysub, 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 front-end |
| [`sessionscribe-revsnap.sh`](#supporting-collateral) | Сборщик RE-снимков по уровням для сравнения бинарных файлов. | на хосте cPanel, около `upcp` |
GPL v2. Все артефакты готовы к загрузке через `curl` по raw-URL, указанным выше.
---
## `sessionscribe-ioc-scan.sh` - IOC-лестница + kill-chain
**Запускайте первым.** По умолчанию — только детектирование (быстро, удобно для парка);
добавьте `--full`, чтобы запустить фазы форензики в одном потоке (таймлайн защиты, импорт
данных об атаке, сверка, рендерер kill-chain, IR-пакет).```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 в файлах сессий,
сканирования журналов доступа и зондов уничтожения Patterns A–G. Даже пропатченный хост
может завершиться с кодом 4, если прежняя эксплуатация оставила IOC на диске.
| Код выхода | Состояние кода | Состояние хоста | Действие при триаже |
|---|---|---|---|
| 0 | CLEAN/PATCHED | CLEAN | нет |
| 1 | VULNERABLE | (любое) | пропатчить cpsrvd |
| 2 | INCONCLUSIVE | (любое) | ручная проверка состояния кода (также: ошибка инструмента) |
| 3 | (любое) | SUSPICIOUS | просмотреть журналы сессий/доступа |
| 4 | (любое) | COMPROMISED | полный IR; комплект + загрузка |
Сеансы, помеченные 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/`: IOCs от вендора + анализ одновременного появления четырёх признаков + эвристика поддельных временных меток (для пропуска используйте `--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` | Тарбол с сырыми артефактами в `/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 MB – 2 GB в сжатом виде.
Ограничение 2 GB на один 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, чтобы изменять состояние.
Идемпотентен: повторный запуск на исправном хосте не выполняет никаких действий. Перед изменением
какого-либо файла создаются резервные копии с метками времени в
/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` (opt-in) | Запускает `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 и корректно завершает работу — что доказывает идемпотентность без необходимости в лабораторной среде.
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
Режимы вывода: pretty (по умолчанию), `-q`/`--quiet`, `--oneline`, `--csv`,
`--json`. Коды выхода: `0` — уязвимостей не найдено, `1` — только неопределённые результаты, `2`
— одна или несколько уязвимостей. См. `--help` для полного списка флагов, включая
семантику `--auto-host-discover`, `--all`, `--fingerprint-only`, а также
режим `--no-verify`, доступный только на этапе 2 (устаревший, даёт ложные срабатывания на пропатченных
хостах).
---
## Сопутствующие материалы
### `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
| Правило | Поверхность | Действие |
|---|---|---|
1500030 | CRLF внутри декодированной полезной нагрузки Authorization: Basic | запретить, все источники, все пути |
1500031 | cookie whostmgrsession без допустимого суффикса ,OBHEX | запретить (эшелонированная защита) |
1500010 | Authorization: WHM для /json-api/, /execute/, /acctxfer*/ | запретить, если источник не в списке доверия |
1500020 | Authorization: WHM для семейства диспетчеризации WebSocket | запретить, если источник не в списке доверия |
1500021 | Authorization: WHM на пути диспетчеризации SSE | запретить, если источник не в списке доверия |
Зарезервирован диапазон ID: 1500000–1500099. Правила WHM-токенов используют @ipMatch для проверки по определяемому оператором списку доверия — измените CIDR в верхней части файла перед развертыванием.
[!IMPORTANT] Эти правила работают внутри Apache.
cpsrvdпрослушивает напрямую порты 2082/2083/2086/2087/2095/2096 и доступен независимо от Apache. Сочетайте набор правил с межсетевым экранированием портов cpsrvd, ограниченным управляющими CIDR.
sessionscribe-revsnap.sh - сборщик RE-снимковЗахватывает поуровневый тарбол (бинарные файлы, строки, dynsym, дизассемблер, 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 будет затрагивать
примерно ту же поверхность, а пара тарболов для версии до исправления и
после — это разница между часами и днями анализа.
См. [исследовательскую статью](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-код, полученный в запросе 4. Файл сессии на диске в
`/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
Обычная сессия preauth никогда не содержит 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-адресов без предшествующего ответа 200 на `/login/` в том же окне
сеанса.
---
## Затронутые сборки```
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
Tiers, исключённые из списка патчей вендора, не имеют исправления на месте: 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 back-port для вашего тира — это
настоящее исправление.proxysub + firewall оркестратора плюс
набор правил ModSec уменьшают радиус поражения; обновление или миграция — единственный
долговременный ответ.nxesec_canary_<nonce>
для очистки и активно выполняет выход из сессии.ioc-scan находит артефакты предшествующей
эксплуатации; он не устраняет их. Воспринимайте его вердикт COMPROMISED
как триггер для полного разбора инцидента, а не как окончательный вывод.[!TIP] Нашли баг, пропущенный IOC, ложное срабатывание или есть пожелания по эксплуатации? Откройте issue на GitHub — сообщения об ошибках, варианты IOC, наблюдаемые в реальных условиях, пропуски обнаружения на пропатченных/непропатченных хостах, ложные срабатывания правил ModSec и общие отзывы операторов приветствуются.
Чувствительные раскрытия (доказательства активной эксплуатации, данные клиентов, новые цепочки эксплойтов, ещё не публичные) следует отправлять через Keybase или email, а не через GitHub Issues.
GPL v2. См. заголовки отдельных файлов.
Создано в ходе реагирования на инцидент SessionScribe — Райан Макдональд, R-fx Networks.