28 апреля 2026 года cPanel выпустила экстренный патч для CVE-2026-41940 - обход аутентификации с CVSS 9.3 (Critical, CVSS 4.0). Через два дня CISA закинула её в каталог Known Exploited Vulnerabilities с дедлайном 72 часа и пометкой «ransomware use: known». По данным watchTowr Labs, эксплуатация в дикой природе шла как минимум с конца февраля - два месяца zero-day на панели, через которую, по Shodan-телеметрии (упомянутой Rapid7), доступно порядка 1.5 миллиона интернет-инстансов. EPSS - 0.8437, Top 1% по вероятности эксплуатации.
Четыре HTTP-запроса. Ноль валидных паролей. Полный root WHM. Даже не buffer overflow - логическая ошибка, которую эксплуатируют curl'ом. Ниже - разбор механики CVE-2026-41940, цепочка эксплуатации, детектирование и hardening-чеклист.
Место CVE-2026-41940 в цепочке атаки
CVE-2026-41940 - чистый initial access. Атакующий получает root-сессию WHM без единого валидного пароля. CISA SSVC подтверждает:exploitation: active, automatable: yes, technical impact: total. На MITRE ATT&CK это ложится так:- Initial Access - Exploit Public-Facing Application (T1190). Эксплуатация на интернет-доступных портах cPanel/WHM: 2082/2083 (cPanel UI), 2086/2087 (WHM). Все порты обслуживает один демон
cpsrvd, и все уязвимы. - Credential Access - Exploitation for Credential Access (T1212) + Web Cookies (T1606.001). CRLF-инъекция в сессионный файл создаёт поддельную root-сессию. Credential bypass без брутфорса - атакующий «подделывает» аутентификационные флаги прямо на диске.
- Privilege Escalation (T1068). Preauth-сессия промоутится до полноценной root-сессии WHM через штатный механизм перечитывания кэша. Красиво, если подумать - система сама себя обманывает.
- Persistence - Web Shell (T1505.003). Через WHM API атакующий деплоит webshell, создаёт backdoor-аккаунты, внедряет SSH-ключи. Стандартная post-exploitation на хостинг-панели.
- Lateral Movement - Web Session Cookie (T1550.004). Root-доступ к WHM даёт контроль над каждым cPanel-аккаунтом на сервере. На shared-хостинге один сервер - десятки-сотни клиентских сайтов. Один root - и весь сервер твой.
Три слабости - одна цепочка: корневая причина уязвимости cPanel
По NVD классификация - CWE-306 (Missing Authentication for Critical Function). В advisory самого cPanel фигурирует CWE-93 (Improper Neutralization of CRLF Sequences), а аналитики Hadrian считают, что точнее CWE-117 (Improper Output Neutralization for Logs/Files) - CRLF приземляется не в HTTP-заголовок, а в файл на диске. Три отдельных дефекта, выстроившихся в цепочку. Каждый по отдельности мог быть смягчён - вместе они дают pre-auth remote root.Санитайзер, который забыли вызвать
В кодовой базе cPanel уже была функцияfilter_sessiondata(), удаляющая \r, \n, = и , из значений сессии - стандартная защита от CRLF. Проблема архитектурная: вызов санитайзера лежал на каждом caller'е. Большинство путей кода делали это корректно. Один - обработчик HTTP Basic-аутентификации в cpsrvd - не вызывал filter_sessiondata() перед записью.Классический «defense at the source instead of the sink». Пока санитизация opt-in - рано или поздно кто-то забудет. И кто-то забыл. Патч переносит вызов
filter_sessiondata() внутрь самой функции saveSession(), закрывая дыру на уровне записи. По данным watchTowr Labs, модифицированы три файла: Cpanel/Session.pm, Cpanel/Session/Load.pm, Cpanel/Session/Encoder.pm.Шифрование, которое атакующий выключает
Сессионный cookie cPanel имеет формат:session_name,ob_hex - ob_hex (32 hex-символа) используется Cpanel::Session::Encoder для симметричного шифрования поля pass при записи на диск. Если атакующий отправляет cookie без части после запятой (:session_name без ob-сегмента), переменная ob остаётся пустой. Уязвимый код в этом случае просто пропускал шифрование - pass записывался на диск открытым текстом. А раз санитайзер не вызывается, CRLF-символы в «пароле» попадают в файл как есть.По сути, атакующий сам решает - шифровать или нет. Угадайте, что он выбирает.
Патч вводит ветку
no-ob: с hex-кодированием даже при пустом секрете. Шифрование больше нельзя «выключить» манипуляцией cookie - второй эшелон защиты.Два файла - два мира: расхождение session cache
Сессии cPanel живут в двух представлениях на диске. Raw text file в/var/cpanel/sessions/raw/<session> хранит данные построчно: key=value\n. JSON cache - бинарный кэш для быстрого чтения. В JSON встроенные \n - безобидные escape-последовательности внутри строки. В raw-файле \n - разделитель записей. Одни и те же байты означают разное в зависимости от формата. Два мира, два формата, одна дыра.Ключевой момент: когда запрос проваливает проверку URL-bound security token, обработчик
do_token_denied() вызывает Cpanel::Session::Modify::new($session, nocache => 1) - принудительное перечитывание raw-файла. CRLF-строки из поля pass «всплывают» как отдельные ключи верхнего уровня. Modify::save() перезаписывает JSON-кэш - инжектированные ключи промотируются, и на следующем запросе cpsrvd считает сессию полностью аутентифицированной. По анализу Picus Security, финальная проверка в docheckpass_whostmgrd short-circuits на «AUTH OK» при наличии поля successful_internal_auth_with_timestamp - флаг, который означает «доверяй, проверка уже пройдена». Без криптографической привязки. Просто строка в файле.Цепочка эксплуатации CVE-2026-41940: четыре запроса от анонима до root WHM
Требования к окружению
| Параметр | Значение |
|---|---|
| Целевая система | cPanel & WHM версий после 11.40, до патчей: 11.110.0.97 / 11.118.0.63 / 11.126.0.54 / 11.132.0.29 / 11.134.0.20 / 11.136.0.5 |
| Также уязвимы | WP Squared (WordPress-хостинг на базе cPanel) |
| Сетевой доступ | TCP к порту 2087 (WHM) или 2083 (cPanel) |
| Инструменты | curl / Python 3.x + requests, Burp Suite для отладки |
| Привилегии | Не требуются (pre-auth) |
| Взаимодействие пользователя | Не требуется |
Контекст:
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Что видит защита и где слепые зоны при session hijacking
Файловая система и логи
По рекомендациям Picus Security, ключевые IOC - аномалии в сессионных файлах. Команды для triage на cPanel-сервере (нужен SSH с root):
Bash:
# Сессии с привилегированными ключами, невозможными для preauth
grep -lE '^(hasroot|tfa_verified|successful_internal_auth_with_timestamp)=1' \
/var/cpanel/sessions/raw/* 2>/dev/null
# pass= значения с \r - признак CRLF-инъекции
grep -lP 'pass=.*\r' /var/cpanel/sessions/raw/* 2>/dev/null
origin_as_string=...method=badpass в комбинации с hasroot=1. Эта комбинация означает «сессия создана неудачным логином и затем повышена» - в легитимном сценарии такого не бывает. Если grep нашёл совпадения - дело плохо.В access-логах cPanel ищите: последовательность 307 redirect на
/cpsessXXXXXXXXXX/ без предшествующего успешного POST на /login/; cookie формата whostmgrsession=:<name> без ,<32-hex> хвоста в запросах с Authorization: Basic - это сигнатура no-encryption пути.WAF и сетевые фильтры
Cloudflare выпустила экстренное managed WAF-правило 30 апреля 2026 года. Trend Micro опубликовала IPS-правило 1012556 (Vision One), DV Filter 47364 (TippingPoint), DDI-правило 5792. Если SOC использует эти стеки - проверьте наличие актуальных сигнатур. ProjectDiscovery добавили шаблонCVE-2026-41940.yaml в nuclei-templates - самый быстрый способ массовой проверки: nuclei -t http/cves/2026/CVE-2026-41940.yaml -l targets.txt.Ограничения эксплуатации
| Фактор | Влияние |
|---|---|
| cPanel пропатчен (версии ≥ указанных) | Эксплуатация невозможна |
| Порты 2083/2087 закрыты файрволом | Нет сетевого доступа - нет атаки |
| Cloudflare managed ruleset включён | Частичная защита (WAF-правило от 30.04.2026) |
| IP allowlisting на WHM | Блокирует доступ с неизвестных IP |
| cPHulk Brute Force Protection | Частичное ограничение некоторых паттернов |
С точки зрения пентестера: крупные провайдеры (Namecheap, KnownHost, HostPapa, InMotion, hosting.com) заблокировали порты на сетевом уровне в первые часы после раскрытия. Но мелкие провайдеры, self-hosted инстансы, legacy-серверы с отключённым автообновлением и version pinning - в зоне риска. И таких много. По данным IBM X-Force, среднее время от публикации CVE до устранения в организации - 29 месяцев. Двадцать девять. Месяцев.
Патч и hardening cPanel: чеклист для пентестера и администратора
- Проверить версию -
/usr/local/cpanel/cpanel -Vпо SSH или через WHM GUI. Пропатченные: 11.110.0.97, 11.118.0.63, 11.126.0.54, 11.132.0.29, 11.134.0.20, 11.136.0.5. - Принудительное обновление -
/scripts/upcp --force, затем/scripts/restartsrv_cpsrvd. - Аудит сессий за окно уязвимости - проверить
/var/cpanel/sessions/raw/на IOC (grep-команды выше). Период: с 23 февраля 2026 (начало in-the-wild эксплуатации по данным KnownHost) до момента патча. - Ротация credentials - при обнаружении следов компрометации сменить root-пароль, SSH-ключи, пароли всех cPanel-аккаунтов, API-токены. Всё. Без исключений.
- IP allowlisting - ограничить доступ к портам 2082, 2083, 2086, 2087, 2095, 2096 - стандартный hardening, снижающий attack surface при любых будущих уязвимостях.
- Серверы с version pinning - проверить отдельно, они не патчатся автоматически. Это те самые серверы, про которые «забыли» и которые ломают первыми.
filter_sessiondata() была написана и работала. Одна забытая точка вызова - и модель рушится.Четыре HTTP-запроса без единого пароля - и root WHM. Не buffer overflow, не race condition, не kernel exploit. Логическая ошибка в сессионной модели, которую эксплуатируют curl'ом. EPSS 0.8437 и ransomware-связка в CISA KEV - не теоретический risk score, а отражение тривиальности воспроизведения.
Если проводите аудиты shared-хостинг инфраструктуры - ищите не только эту конкретную CVE. Ищите архитектурный паттерн: где ещё в
cpsrvd пути кода пишут в сессионные файлы без вызова санитайзера? Патч закрыл конкретный баг - saveSession теперь вызывает filter_sessiondata внутри себя. Но opt-in санитизация - рецидивирующая проблема, и cPanel далеко не единственная платформа, которая на этом горит. Каждый раз, когда вижу filter_* функцию, которую caller «должен вызвать сам», - проверяю все call paths. И каждый раз нахожу пропущенный.