
Strumenti di rilevamento, mitigazione e reverse engineering per CVE-2026-41940 (SessionScribe): la vulnerabilità di falsificazione di sessione non autenticata di cPanel/WHM divulgata il 2026-04-28. Shim di mitigazione attiva di difesa in profondità, pacchetto di regole ModSec, sonda remota, scanner IOC sull'host e collettore di snapshot RE per livello. GPL v2.
RCE critico non autenticato in cPanel & WHM. Quattro richieste HTTP forgiano una sessione root tramite CRLF injection nel campo password di una sessione preauth. Nessuna autenticazione, nessuna precondizione, ogni tier supportato è affetto. Divulgato il 2026-04-28 da Sina Kheirkhah / watchTowr Labs.
Avvio rapido · ioc-scan · mitigate · remote-probe · Build interessati · Ordine di priorità
[!IMPORTANT] I tier 112, 114, 116, 120, 122, 128 non hanno patch del fornitore. Ogni build su quei tier è vulnerabile; l'aggiornamento o la migrazione è l'unica soluzione duratura. Fino ad allora: firewall TCP/2082, 2083, 2086, 2087, 2095, 2096 verso CIDR di gestione (
mitigate.sh --applyfa questo) e proteggere la superficie rimanente con il pacchetto di regole ModSec.
Tre oneliner, in ordine di priorità operativa:```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
I codici di uscita sono progettati per l'automazione della flotta: `ioc-scan` esce con `4` su COMPROMISED, `1` su VULNERABLE; `mitigate` esce con `0` pulito / `1` applicato / `2` manuale / `3` errore strumento; `remote-probe` esce con `2` se un qualsiasi target è VULN.
---
## Strumenti
In ordine di priorità operativa. Ogni artefatto emette output strutturato (`--json` / `--jsonl` / `--csv`) indicizzato su `host`, `os`, `cpanel_version`, `ts` per il roll-up della flotta.
| Strumento | Ruolo | Dove viene eseguito |
|---|---|---|
| **[`sessionscribe-ioc-scan.sh`](#sessionscribe-ioc-scansh---ioc-ladder--kill-chain)** | Triage di prima classe. Scala IOC, verdetti su stato del codice + stato dell'host, ricostruzione della kill-chain, bundle IR. | sul host cPanel |
| **[`sessionscribe-mitigate.sh`](#sessionscribe-mitigatesh---mitigation-orchestrator)** | Chiudi la finestra. Mitigazione a fasi: verifica patch, firewall, proxysub, ModSec. | sul host cPanel |
| **[`sessionscribe-remote-probe.sh`](#sessionscribe-remote-probesh---non-destructive-fleet-probe)** | Supporto collaterale. Sonda non distruttiva a 4 stadi → VULN/SAFE per host. | ovunque con `curl` |
| [`modsec-sessionscribe.conf`](#supporting-collateral) | Pacchetto di regole ModSec distribuito da `mitigate`. | Front-end Apache |
| [`sessionscribe-revsnap.sh`](#supporting-collateral) | Collettore di snapshot RE per livello per il binary diffing. | sul host cPanel, intorno a `upcp` |
GPL v2. Tutti gli artefatti pronti per `curl` tramite i URL raw sopra.
---
## `sessionscribe-ioc-scan.sh` - IOC ladder + kill-chain
**Esegui questo per primo.** Solo rilevamento di default (veloce, amichevole per la flotta); aggiungi `--full` per eseguire le fasi forensi inline (linea temporale della difesa, ingestione offensiva, riconciliazione, renderizzatore della kill-chain, bundle 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
Due assi riportano indipendentemente. code_verdict (PATCHED /
VULNERABLE / INCONCLUSIVE) proviene dalla versione, dai pattern di codice Perl e dall'impronta digitale binaria di cpsrvd. host_verdict (CLEAN /
SUSPICIOUS / COMPROMISED) proviene dalla scala IOC dei file di sessione, dalla scansione dei log di accesso e dalle sonde di distruzione dei Pattern A–G. Un host con patch può comunque uscire con codice 4 se uno sfruttamento precedente ha lasciato IOC sul disco.
| Uscita | Stato del codice | Stato dell'host | Azione di triage |
|---|---|---|---|
| 0 | CLEAN/PATCHED | CLEAN | nessuna |
| 1 | VULNERABLE | (qualsiasi) | applicare patch a cpsrvd |
| 2 | INCONCLUSIVE | (qualsiasi) | revisione manuale dello stato del codice (anche: errore dello strumento) |
| 3 | (qualsiasi) | SUSPICIOUS | esaminare i log di sessione/accesso |
| 4 | (qualsiasi) | COMPROMISED | IR completo; raggruppa + carica |
Le sessioni taggate con nxesec_canary_<nonce> (lasciate dalla sonda remota) vengono classificate come PROBE_ARTIFACT e non vengono portate a COMPROMISED.
--full confronta ogni IOC con le attivazioni difensive e classifica ciascuno come PRE-DEFENSE, POST-DEFENSE, POST-PARTIAL o UNDEFENDED, poi riassume con verdetto + headline del ritardo difensivo. PRE-DEFENSE = l'host era aperto allo sfruttamento quando l'indicatore è arrivato; POST-DEFENSE = rumore collaterale o pre-mitigazione.```
+-- 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>Riferimento ai controlli + fasi forensi + struttura del bundle</b> (clicca per espandere)</summary>
| Controllo | Cosa fa |
|---|---|
| `version` | `cpanel -V` rispetto alla lista ufficiale delle build patchate – guida `code_verdict` |
| `static-pattern` | Cerca con grep in `Cpanel/Session/*.pm` i pattern sentinella post-patch (ramo decode `no-ob:`) |
| `cpsrvd-fingerprint` | Ispezione del binario cpsrvd rispetto alle firme delle build patchate |
| `access-log` | Log di Apache e cpsrvd per pattern di traffico di exploit (`--no-logs` per saltare) |
| `session-store` | Esame di `/var/cpanel/sessions/raw/`: IOCs del vendor + co-occorrenza a 4 vie + euristica timbro falsificato (`--no-sessions` per saltare) |
| `destruction` | Sonde pattern A–G: encryptor `/root/sshd`, mysql-wipe, indice BTC, `nuclear.x86`, reseller `sptadm`, harvestor `__S_MARK__`, chiavi SSH sospette (`--no-destruction-iocs` per saltare) |
| `probe` (opt-in) | Singola GET marker a `127.0.0.1:2087` – conferma che cpsrvd è reattivo. Non **tenta** il bypass |
**Fasi forensi `--full`** (eseguite in linea dopo il rilevamento):
| Fase | Cosa fa |
|---|---|
| `defense` | Timestamp per ogni livello di difesa applicato: patch cpanel, riavvio cpsrvd dopo patch, esecuzioni mitigate, regole ModSec, chiusure porte CSF/APF, proxysub, riepilogo `upcp` |
| `offense` | Timestamp per ogni indicatore di compromissione osservato (Pattern A–G + catena bypass CRLF Pattern X) |
| `reconcile` | Per indicatore: la difesa pertinente era attiva al momento della prima comparsa? PRE-DEFENSE / POST-DEFENSE / POST-PARTIAL / UNDEFENDED + delta temporale |
| `bundle` | Tarball degli artefatti grezzi in `/root/.ic5790-forensic/<TS>-<RUN_ID>/`, modalità `0700` |
**Struttura 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)
Pacchetto tipico su un host occupato con la finestra di 90 giorni: ~250 MB – 2 GB compressi.
Limite di 2 GB per tarball (--max-bundle-mb) esclude singolarmente i candidati troppo grandi.
Un registro di esecuzione viene scritto in /var/cpanel/sessionscribe-ioc/ per impostazione predefinita (--no-ledger per disabilitare). --chain-forensic / --chain-on-critical / --chain-upload sono conservati come alias di retrocompatibilità v1.x.
Override per test di snapshot per analisi forensi offline su tarball estratti: --root DIR, --version-string S, --cpsrvd-path P. Vedi --help per l'elenco completo delle opzioni.
sessionscribe-mitigate.sh - orchestratore di mitigazioneSolo lettura per impostazione predefinita (--check). Aggiungi --apply per modificare lo stato. Idempotente: rieseguire su un host sano è un no-op. Le modifiche scrivono backup con timestamp in /var/cpanel/sessionscribe-mitigation/ prima di toccare qualsiasi file.```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 | Cosa fa |
|---|---|
| `patch` | `cpanel -V` rispetto all'elenco delle build patchate pubblicate (incluse EL6 11.86.0.41, EL6/CL6 110.0.103, tier 124, WP² 136.1.7) |
| `preflight` | Rimuove `/etc/yum.repos.d/threatdown.repo`; garantisce `epel-release`; disabilita i repo non-base rotti in modo che `upcp` non si blocchi a metà volo |
| `upcp` | Se non patchato, avvia `/scripts/upcp --force --bg` |
| `proxysub` | Abilita `proxysubdomains` + variante new-account; ricostruisce la configurazione di httpd |
| `csf` / `apf` / `runfw` | Rimuove le porte cpsrvd (2082/2083/2086/2087/2095/2096) da `TCP_IN`/`TCP6_IN`/`IG_TCP_CPORTS`; verifica la catena INPUT di iptables live |
| `apache` | `httpd` in esecuzione + `security2_module` caricato |
| `modsec` | `modsec2.user.conf` contiene le regole `1500030` + `1500031`; distribuisci se mancanti (backup con timestamp, validazione `httpd -t`, ricarica graceful) |
| `probe` (opt-in) | Esegue `sessionscribe-remote-probe.sh` contro `127.0.0.1` per confermare i denial nella pratica |
I repo CentOS / Alma / Rocky base/appstream/extras/updates/powertools **non** vengono mai disabilitati da `preflight`, anche se attualmente irraggiungibili.
### Codici di uscita
| Uscita | Significato |
|---|---|
| 0 | pulito – patchato + postura ok, nessuna azione necessaria |
| 1 | remediation applicata con successo (`--apply` ha fatto modifiche) |
| 2 | intervento manuale richiesto (avvisa in `--check`, fallisce in `--apply`) |
| 3 | errore dello strumento (argomenti errati, dipendenze mancanti, non root per `--apply`) |
Selezione delle fasi: `--only LIST`, `--no-PHASE`, `--no-fw` (abbreviazione per
`--no-csf --no-apf --no-runfw`). Output: `--json` / `--jsonl` / `--csv`,
`-o FILE`. Vedi `--help` per l'elenco completo dei flag.
### Controllo rapido di sessanta secondi```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
L'orchestrator rileva un host non-cPanel e termina pulitamente — dimostrando l'idempotenza senza necessità di un laboratorio.
sessionscribe-remote-probe.sh - sonda di flotta non distruttivaMateriale di supporto. Esegue la catena in quattro fasi in modo non distruttivo contro un target: mint preauth → CRLF inject → propagate raw→cache → verify via /json-api/version, quindi esegue il logout attivamente. Il segnale che determina il verdetto è il codice HTTP allo stadio 4: 200 o 5xx con un corpo di licenza, è VULN; 401 o 403 è SAFE.
Ogni sessione di test è contrassegnata con un attributo nxesec_canary_<nonce> per la pulizia forense, e non vengono effettuate chiamate API che modificano lo stato. Le sessioni falsificate sono equivalenti a root per ~1–3 secondi tra lo stadio 3 e il logout allo stadio 5 — consultare l'intestazione dello script per il modello di sicurezza 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
Output modes: pretty (default), `-q`/`--quiet`, `--oneline`, `--csv`,
`--json`. Exit codes: `0` no VULN found, `1` inconclusive only, `2`
one or more VULN. See `--help` for full flag list including
`--auto-host-discover`, `--all`, `--fingerprint-only` semantics, and
the stage-2-only `--no-verify` mode (legacy, produces FPs on patched
hosts).
---
## Materiale di supporto
### `modsec-sessionscribe.conf` - Pacchetto di regole ModSecurity
Distribuito automaticamente da `mitigate.sh --apply --only modsec`. Installazione
manuale:```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
| Regola | Superficie | Azione |
|---|---|---|
1500030 | CRLF all'interno del payload decodificato Authorization: Basic | nega, tutte le sorgenti, tutti i percorsi |
1500031 | cookie whostmgrsession mancante del suffisso ,OBHEX valido | nega (difesa in profondità) |
1500010 | Authorization: WHM su /json-api/, /execute/, /acctxfer*/ | nega quando la sorgente non è nell'elenco di fiducia |
1500020 | Authorization: WHM sulla famiglia di dispatch WebSocket | nega quando la sorgente non è nell'elenco di fiducia |
1500021 | Authorization: WHM sul percorso dispatch SSE | nega quando la sorgente non è nell'elenco di fiducia |
Intervallo ID riservato: 1500000–1500099. Le regole per i token WHM usano @ipMatch rispetto a un elenco di fiducia definito dall'operatore — modifica i CIDR all'inizio del file prima del deployment.
[!IMPORTANT] Queste regole vengono eseguite all'interno di Apache.
cpsrvdascolta direttamente sulle porte 2082/2083/2086/2087/2095/2096 ed è raggiungibile indipendentemente da Apache. Abbina il pacchetto di regole al firewall della porta cpsrvd verso i CIDR di gestione.
sessionscribe-revsnap.sh - Raccolta di snapshot di RECattura un archivio tar per ogni livello (binari, stringhe, dynsym, disasm, moduli Perl, layout runtime) per il diff binario tra gli aggiornamenti di cPanel. Costruito attorno a upcp per catturare coppie pre/post-patch.```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
Generalizza oltre SessionScribe: ogni futuro CVE di cpsrvd ricadrà più o meno sulla stessa superficie, e una coppia di tarball per la build pre-patch e patched è la differenza tra ore e giorni di analisi. Vedi l'[articolo di ricerca](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940) per la procedura RE completa.
---
## Utilizzo in flotta
> [!TIP]
> Ogni artefatto emette output strutturato (`--json`, `--jsonl`, `--csv`) con `host`, `os`, `cpanel_version`, `ts` su ogni record. Progettato per il roll-up `pdsh | jq` o `ansible -m script` attraverso centinaia di host in un unico passaggio.
Stessa primitiva curl-piped-bash — consenti a ogni host di recuperare ed eseguire direttamente l'ultimo 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
The probe is indipendentemente sicuro per la flotta (sessioni taggate canary, logout attivo, nessuna chiamata API che modifichi lo stato). Gli script sull'host rispettano i flag --quiet e structured-output, quindi stdout è pulito per il parsing.
Quattro richieste HTTP, nessuna autenticazione, nessuna precondizione:```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
Il verdetto è il codice HTTP alla richiesta 4. Il file di sessione su disco in
`/var/cpanel/sessions/raw/<sessname>` è l'unico artefatto forense post-hoc.
Il primitivo completo (le due asimmetrie componenti —
`filter_sessiondata` non su ogni percorso di scrittura, l'encoder si cortocircuita
su `ob_part` mancante) e l'argomento architetturale per l'applicazione degli endpoint proxy
si trovano nell'[articolo di ricerca](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940).
---
## Indicatori di compromissione
Forma del file di sessione contraffatto (`/var/cpanel/sessions/raw/<sessname>` dopo lo sfruttamento):```
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 normale sessione di preautenticazione non contiene mai pass=, hasroot=1,
user=root, tfa_verified=1, o
successful_internal_auth_with_timestamp=. Qualunque di questi combinato con
origin_as_string=…method=badpass è diagnostico. Un valore di timestamp falsificato
oltre now+365d (ad es. 9999999999) è indipendentemente diagnostico.```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
Access-log signal: risposte `200`/`302`/`307` riuscite sui percorsi `/json-api/`, `/execute/`, o `/scripts2/` da IP di origine non di base senza un precedente `/login/` 200 nella stessa finestra di sessione.
---
## Build interessate```
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
I tier esclusi dall'elenco delle patch del fornitore non hanno una correzione in loco: 112, 114, 116, 120, 122, 128. Gli host su quei tier devono essere aggiornati a una serie principale con patch, migrati, o avere i loro listener cpsrvd protetti da firewall fino a quando non lo saranno.
11.86.0.41 (EL6/CL7) è stata aggiunta nella revisione dell'avviso del 29/04; 11.130
è stato aumentato da .18 a .19 nella stessa revisione. Una revisione
successiva ha aggiunto 11.124.0.35 (chiudendo il precedente gap sul tier 124) e
110.0.103 come destinazione di aggiornamento diretta per host EL6/CL6 ancora
su v110.0.50.
Immediato
sessionscribe-ioc-scan.sh su tutta la flotta. Un host con patch può
ancora essere compromesso.In futuro
modsec-sessionscribe.conf in modsec2.user.conf con l'elenco di
fiducia @ipMatch impostato.Il caso architetturale per l'implementazione del proxy-endpoint è la terza parte conclusiva dell'articolo di ricerca.
cpsrvd, cpsrvd.so o
Cpanel/Session/*.pm. Il back-port rilasciato da cPanel per il proprio tier è
la correzione reale.proxysub + firewall dell'orchestratore insieme al
pacchetto di regole ModSec riducono il raggio d'esplosione; l'aggiornamento o la
migrazione è l'unica risposta duratura.nxesec_canary_<nonce> per la pulizia, e si disconnette attivamente.ioc-scan trova artefatti di sfruttamento precedente;
non li corregge. Tratta il suo verdetto COMPROMISED come un innesco per un IR
completo, non come una conclusione.[!TIP] Trovato un bug, IOC mancato, falso positivo, o hai feedback operativi? Apri un problema su GitHub - segnalazioni di bug, varianti IOC viste in natura, rilevamenti mancati su host con/senza patch, falsi positivi delle regole ModSec e feedback generali degli operatori sono tutti benvenuti.
Divulgazioni sensibili (prove di sfruttamento in corso, dati dei clienti, nuove catene di exploit non ancora pubbliche) dovrebbero essere inviate tramite Keybase o email, non su GitHub Issues.
GPL v2. Consultare le intestazioni dei singoli file.
Forgiato durante la risposta all'incidente SessionScribe - Ryan MacDonald, R-fx Networks.