
Herramientas de detección, mitigación e ingeniería inversa para CVE-2026-41940 (SessionScribe): la vulnerabilidad de falsificación de sesión no autenticada en cPanel/WHM divulgada el 2026-04-28. Shim de mitigación activa de defensa en profundidad, paquete de reglas ModSec, sonda remota, escáner de IOC en el host y recopilador de instantáneas RE por nivel. GPL v2.
RCE crítico no autenticado en cPanel & WHM. Cuatro solicitudes HTTP forjan una sesión root mediante inyección CRLF en el campo de contraseña de una sesión de preautenticación. Sin autenticación, sin precondiciones, todos los niveles compatibles afectados. Divulgado el 2026-04-28 por Sina Kheirkhah / watchTowr Labs.
Inicio rápido · ioc-scan · mitigate · remote-probe · Compilaciones afectadas · Orden de prioridad
[!IMPORTANT] Los niveles 112, 114, 116, 120, 122, 128 no tienen parche del proveedor. Toda compilación en esos niveles es vulnerable; la actualización o la migración es la única solución duradera. Hasta entonces: restrinja por firewall TCP/2082, 2083, 2086, 2087, 2095, 2096 a las CIDR de administración (
mitigate.sh --applyhace esto) y proteja la superficie restante con el paquete de reglas ModSec.
Tres comandos de una línea, en orden de prioridad del operador:```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
Los códigos de salida están diseñados para la automatización de flotas: `ioc-scan` sale con `4` en
COMPROMISED, `1` en VULNERABLE; `mitigate` sale con `0` limpio / `1` aplicado
/ `2` manual / `3` error de herramienta; `remote-probe` sale con `2` si algún objetivo está
VULN.
---
## Herramientas
En orden de prioridad operativa. Cada artefacto emite salida estructurada
(`--json` / `--jsonl` / `--csv`) con claves `host`, `os`, `cpanel_version`,
`ts` para la consolidación de flota.
| Herramienta | Rol | Dónde se ejecuta |
|---|---|---|
| **[`sessionscribe-ioc-scan.sh`](#sessionscribe-ioc-scansh---ioc-ladder--kill-chain)** | Triage de primera clase. Escalera de IOC, veredictos de estado de código + estado de host, reconstrucción de la cadena de ataque, paquete de IR. | en el host de cPanel |
| **[`sessionscribe-mitigate.sh`](#sessionscribe-mitigatesh---mitigation-orchestrator)** | Cerrar la ventana. Mitigación por fases: comprobación de parches, firewall, proxysub, ModSec. | en el host de cPanel |
| **[`sessionscribe-remote-probe.sh`](#sessionscribe-remote-probesh---non-destructive-fleet-probe)** | Colateral de soporte. Sonda no destructiva de 4 fases → VULN/SAFE por host. | en cualquier lugar con `curl` |
| [`modsec-sessionscribe.conf`](#supporting-collateral) | Paquete de reglas ModSec desplegado por `mitigate`. | front-end de Apache |
| [`sessionscribe-revsnap.sh`](#supporting-collateral) | Recopilador de instantáneas RE por nivel para comparación de binarios. | en el host de cPanel, alrededor de `upcp` |
GPL v2. Todos los artefactos están listos para `curl` mediante las URLs raw anteriores.
---
## `sessionscribe-ioc-scan.sh` - Escalera de IOC + cadena de ataque
**Ejecútalo primero.** Solo detección por defecto (rápido y apto para flotas);
añade `--full` para ejecutar las fases forenses en línea (línea de tiempo de defensa, ingesta
de ofensiva, conciliación, renderizador de cadena de ataque, paquete de 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
Los dos ejes informan de forma independiente. code_verdict (PATCHED /
VULNERABLE / INCONCLUSIVE) proviene de la versión, los patrones de código fuente Perl
y la huella binaria de cpsrvd. host_verdict (CLEAN /
SUSPICIOUS / COMPROMISED) proviene de la escalera de IOCs del archivo de sesión,
el análisis de registros de acceso y las sondas de destrucción de los Patrones A–G. Un host parcheado
puede seguir saliendo con 4 si una explotación previa dejó IOCs en el disco.
Las sesiones etiquetadas con nxesec_canary_<nonce> (dejadas por la sonda remota)
se agrupan como PROBE_ARTIFACT y no escalan a COMPROMISED.
--full recopila cada IOC contra las activaciones de defensa y clasifica
cada uno como PRE-DEFENSE, POST-DEFENSE, POST-PARTIAL o
UNDEFENDED, y luego resume con un titular de veredicto + retraso de defensa.
PRE-DEFENSE = el host estaba abierto al exploit cuando el indicador aterrizó;
POST-DEFENSE = ruido colateral o previo a la mitigación.```
+-- 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>Referencia de comprobaciones + fases forenses + estructura del bundle</b> (haz clic para expandir)</summary>
| Comprobación | Qué hace |
|---|---|
| `version` | `cpanel -V` frente a la lista publicada de builds parcheadas: determina `code_verdict` |
| `static-pattern` | Busca en `Cpanel/Session/*.pm` los patrones centinela posteriores al parche (rama de decodificación `no-ob:`) |
| `cpsrvd-fingerprint` | Inspección del binario cpsrvd frente a firmas de builds parcheadas |
| `access-log` | Registros de Apache + cpsrvd para detectar formas de tráfico de explotación (`--no-logs` para omitir) |
| `session-store` | Recorrido de `/var/cpanel/sessions/raw/`: IOCs del proveedor + co-ocurrencia de 4 vías + heurística de marcas de tiempo falsificadas (`--no-sessions` para omitir) |
| `destruction` | Sondas de patrones A–G: cifrador `/root/sshd`, limpieza de mysql, índice BTC, `nuclear.x86`, `sptadm` revendedor, recolector `__S_MARK__`, claves SSH sospechosas (`--no-destruction-iocs` para omitir) |
| `probe` (opt-in) | GET de un solo marcador a `127.0.0.1:2087`: confirma que cpsrvd responde. **No** intenta el bypass |
**Fases forenses de `--full`** (se ejecutan en línea tras la detección):
| Fase | Qué hace |
|---|---|
| `defense` | Registra con marca de tiempo cada capa de defensa aplicada: parche de cpanel, reinicio de cpsrvd tras el parche, ejecuciones de mitigate, reglas de ModSec, cierres de puertos CSF/APF, proxysub, resumen de `upcp` |
| `offense` | Registra con marca de tiempo todos los indicadores de compromiso observados (Patrones A–G + cadena de bypass CRLF del Patrón X) |
| `reconcile` | Por indicador: ¿estaba activa la defensa correspondiente cuando apareció por primera vez? PRE-DEFENSE / POST-DEFENSE / POST-PARTIAL / UNDEFENDED + delta de tiempo |
| `bundle` | Tarball de los artefactos sin procesar en `/root/.ic5790-forensic/<TS>-<RUN_ID>/`, modo `0700` |
**Estructura del bundle** (`/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)
Paquete típico en un host ocupado con la ventana de 90 días: ~250 MB – 2 GB comprimidos.
Límite de 2 GB por tarball (--max-bundle-mb) descarta individualmente los candidatos que superan el tamaño.
Un registro de ejecución se escribe en /var/cpanel/sessionscribe-ioc/ de forma predeterminada
(--no-ledger para deshabilitarlo). --chain-forensic / --chain-on-critical /
--chain-upload se conservan como alias de retrocompatibilidad v1.x.
Anulaciones de pruebas de instantánea para el análisis forense sin conexión en tarballs extraídos:
--root DIR, --version-string S, --cpsrvd-path P. Consulte --help para
la lista completa de opciones.
sessionscribe-mitigate.sh - orquestador de mitigaciónDe solo lectura de forma predeterminada (--check). Añade --apply para modificar el estado.
Idempotente: volver a ejecutarlo en un host en buen estado no tiene efecto. Las mutaciones escriben
copias de seguridad con marca de tiempo en /var/cpanel/sessionscribe-mitigation/
antes de tocar cualquier archivo.```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
| Fase | Qué hace |
|---|---|
| `patch` | `cpanel -V` contra la lista publicada de compilaciones parcheadas (incluyendo EL6 11.86.0.41, EL6/CL6 110.0.103, tier 124, WP² 136.1.7) |
| `preflight` | Elimina `/etc/yum.repos.d/threatdown.repo`; asegura `epel-release`; desactiva los repos no base rotos para que `upcp` no falle a mitad de ejecución |
| `upcp` | Si no está parcheado, inicia `/scripts/upcp --force --bg` |
| `proxysub` | Habilita `proxysubdomains` + la variante de nueva cuenta; reconstruye la conf de httpd |
| `csf` / `apf` / `runfw` | Elimina los puertos de cpsrvd (2082/2083/2086/2087/2095/2096) de `TCP_IN`/`TCP6_IN`/`IG_TCP_CPORTS`; verifica la cadena INPUT de iptables en vivo |
| `apache` | `httpd` en ejecución + `security2_module` cargado |
| `modsec` | `modsec2.user.conf` contiene las reglas `1500030` + `1500031`; se implementa si faltan (copia de seguridad con marca de tiempo, validación con `httpd -t`, recarga sin interrupción) |
| `probe` (opt-in) | Ejecuta `sessionscribe-remote-probe.sh` contra `127.0.0.1` para confirmar las denegaciones en la práctica |
Los repos base/appstream/extras/updates/powertools de CentOS / Alma / Rocky **nunca** son desactivados por `preflight`, incluso si actualmente no están accesibles.
### Códigos de salida
| Código | Significado |
|---|---|
| 0 | limpio - parcheado + postura correcta, no se requiere acción |
| 1 | remediación aplicada correctamente (`--apply` realizó cambios) |
| 2 | se requiere intervención manual (advierte en `--check`, falla en `--apply`) |
| 3 | error de herramienta (argumentos incorrectos, dependencias faltantes, no ser root para `--apply`) |
Selección de fases: `--only LIST`, `--no-PHASE`, `--no-fw` (abreviatura de
`--no-csf --no-apf --no-runfw`). Salida: `--json` / `--jsonl` / `--csv`,
`-o FILE`. Consulta `--help` para la lista completa de opciones.
### Prueba de humo de sesenta segundos```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
El orquestador detecta un host que no es cPanel y sale limpiamente — lo que demuestra idempotencia sin necesidad de un laboratorio.
sessionscribe-remote-probe.sh - sonda no destructiva para flotasMaterial de apoyo. Ejecuta la cadena de cuatro etapas de forma no destructiva
contra un objetivo: generar preauth → inyectar CRLF → propagar raw→cache →
verificar mediante /json-api/version, y luego cierra la sesión activamente. La señal
determinante del veredicto es el código HTTP en la etapa 4: 200, o 5xx con un
cuerpo de licencia, es VULN; 401 o 403 es SAFE.
Cada sesión de prueba se etiqueta con un atributo nxesec_canary_<nonce>
para la limpieza forense, y no se realizan llamadas API que cambien el estado.
Las sesiones forjadas son equivalentes a root durante ~1–3s entre la etapa 3 y el
cierre de sesión de la etapa 5 — consulte el encabezado del script para ver el modelo de seguridad completo.```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
Modos de salida: pretty (predeterminado), `-q`/`--quiet`, `--oneline`, `--csv`,
`--json`. Códigos de salida: `0` sin VULN encontrado, `1` solo no concluyente, `2`
uno o más VULN. Consulta `--help` para la lista completa de banderas, incluida
la semántica de `--auto-host-discover`, `--all`, `--fingerprint-only`, y
el modo `--no-verify` solo de etapa 2 (heredado, produce falsos positivos en hosts
parcheados).
---
## Material de soporte
### `modsec-sessionscribe.conf` - Paquete de reglas de ModSecurity
Se implementa automáticamente mediante `mitigate.sh --apply --only modsec`. Instalación
manual:```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
Rango de ID reservado: 1500000–1500099. Las reglas de token WHM usan @ipMatch
contra una lista de confianza definida por el operador — edite los CIDR en la parte superior
del archivo antes de implementar.
[!IMPORTANT] Estas reglas se ejecutan dentro de Apache.
cpsrvdescucha directamente en 2082/2083/2086/2087/2095/2096 y es accesible independientemente de Apache. Combine el paquete de reglas con el firewall de puertos cpsrvd para los CIDR de administración.
sessionscribe-revsnap.sh - Recopilador de instantáneas RECaptura un tarball por nivel (binarios, strings, dynsym, disasm, módulos
Perl, disposición en tiempo de ejecución) para la comparación binaria entre
actualizaciones de cPanel. Construido en torno a upcp para capturar pares pre/post-parche.```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
Se generaliza más allá de SessionScribe: cada futuro CVE de cpsrvd aterrizará en
aproximadamente la misma superficie, y un par de tarballs para la compilación
previa al parche y la parcheada es la diferencia entre horas y días de análisis.
Consulta el [artículo de investigación](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940)
para el recorrido completo de RE.
---
## Uso en flotas
> [!TIP]
> Cada artefacto emite salida estructurada (`--json`, `--jsonl`, `--csv`)
> con `host`, `os`, `cpanel_version`, `ts` en cada registro. Diseñado
> para la agregación con `pdsh | jq` o `ansible -m script` en cientos de
> hosts en una sola pasada.
La misma primitiva curl-piped-bash — deja que cada host obtenga y ejecute directamente
el último script:```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
La sonda es independientemente segura para flotas (sesiones etiquetadas como canary, cierre de sesión activo, sin llamadas API que cambien el estado). Los scripts en el host respetan las banderas --quiet + de salida estructurada para que stdout esté limpio para el parser.
Cuatro solicitudes HTTP, sin autenticación, sin condiciones previas:```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
Verdict es el código HTTP en la solicitud 4. El archivo de sesión en disco en
`/var/cpanel/sessions/raw/<sessname>` es el único artefacto forense
posterior al hecho. La primitiva completa (las dos asimetrías que la componen —
`filter_sessiondata` no en todas las rutas de escritura, el codificador hace
cortocircuito cuando falta `ob_part`) y el argumento arquitectónico para la
aplicación en el extremo del proxy están en el
[artículo de investigación](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940).
---
## Indicadores de compromiso
Forma del archivo de sesión falsificado (`/var/cpanel/sessions/raw/<sessname>` tras
la explotación):```
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
Una sesión preauth normal nunca contiene pass=, hasroot=1,
user=root, tfa_verified=1, o
successful_internal_auth_with_timestamp=. Cualquiera de esos combinado con
origin_as_string=…method=badpass es diagnóstico. Un valor de marca de tiempo falsificado
más allá de now+365d (p. ej. 9999999999) es independientemente diagnóstico.```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
Señal en el registro de acceso: respuestas exitosas `200`/`302`/`307` en
las rutas `/json-api/`, `/execute/` o `/scripts2/` desde IPs de origen
fuera de la línea base sin un `/login/` 200 previo en la misma
ventana de sesión.
---
## Compilaciones afectadas```
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
Los niveles excluidos de la lista de parches del proveedor no tienen corrección in situ: 112, 114, 116, 120, 122, 128. Los hosts en esos niveles deben actualizarse a una serie mayor parcheada, migrarse, o tener sus listeners de cpsrvd protegidos por firewall hasta que lo hagan.
11.86.0.41 (EL6/CL7) se añadió en la revisión del aviso del 04/29; 11.130
se actualizó de .18 a .19 en la misma revisión. Una revisión
posterior añadió 11.124.0.35 (cerrando la brecha anterior en el nivel 124) y
110.0.103 como objetivo de actualización directa para hosts EL6/CL6 que aún están en
v110.0.50.
Inmediato
sessionscribe-ioc-scan.sh en toda la flota. Un host parcheado aún puede
estar comprometido.A futuro
modsec-sessionscribe.conf en modsec2.user.conf con la
lista de confianza @ipMatch configurada.El argumento arquitectónico para la aplicación de endpoint proxy es el tercio final del artículo de investigación.
cpsrvd, cpsrvd.so ni
Cpanel/Session/*.pm. El back-port emitido por cPanel para su nivel es
la corrección real.proxysub + firewall del orquestador junto con el
paquete de reglas de ModSec reducen el radio de explosión; la actualización o migración es la única
respuesta duradera.nxesec_canary_<nonce>
para su limpieza y cierra sesión activamente.ioc-scan encuentra artefactos de explotación
previa; no los remedia. Trate su veredicto COMPROMISED
como un desencadenante para una IR completa, no como una conclusión.[!TIP] ¿Encontró un error, un IOC omitido, un falso positivo o tiene comentarios operativos? Abra un issue en GitHub - informes de errores, variantes de IOC observadas en el mundo real, fallos de detección en hosts parcheados/no parcheados, falsos positivos de reglas de ModSec y comentarios generales de operadores son bienvenidos.
Las divulgaciones sensibles (evidencia de explotación en vivo, datos de clientes, cadenas de explotación novedosas aún no públicas) deben enviarse a través de Keybase o correo electrónico, no por GitHub Issues.
GPL v2. Consulte los encabezados de cada archivo.
Redactado durante la respuesta al incidente SessionScribe - Ryan MacDonald, R-fx Networks.
| Salida | Estado del código | Estado del host | Acción de triaje |
|---|
| 0 | CLEAN/PATCHED | CLEAN | ninguna |
| 1 | VULNERABLE | (cualquiera) | parchear cpsrvd |
| 2 | INCONCLUSIVE | (cualquiera) | revisión manual del estado del código (también: error de herramienta) |
| 3 | (cualquiera) | SUSPICIOUS | revisar registros de sesión/acceso |
| 4 | (cualquiera) | COMPROMISED | IR completo; empaquetar + subir |
| Regla | Superficie | Acción |
|---|
1500030 | CRLF dentro de la carga útil decodificada de Authorization: Basic | denegar, todos los orígenes, todas las rutas |
1500031 | cookie whostmgrsession sin sufijo ,OBHEX válido | denegar (defensa en profundidad) |
1500010 | Authorization: WHM en /json-api/, /execute/, /acctxfer*/ | denegar cuando el origen no esté en la lista de confianza |
1500020 | Authorization: WHM en la familia de despacho WebSocket | denegar cuando el origen no esté en la lista de confianza |
1500021 | Authorization: WHM en la ruta de despacho SSE | denegar cuando el origen no esté en la lista de confianza |