
Detection, mitigation, and reverse-engineering tooling for CVE-2026-41940 (SessionScribe): the cPanel/WHM unauthenticated session-forgery vulnerability disclosed 2026-04-28. Defense-in-depth active mitigation shim, ModSec rule pack, remote probe, on-host IOC scanner, and per-tier RE snapshot collector. GPL v2.
RCE crítica não autenticada no cPanel & WHM. Quatro requisições HTTP forjam uma sessão root via injeção CRLF no campo de senha de uma sessão de pré-autenticação. Sem autenticação, sem pré-condições, todos os tiers suportados afetados. Divulgado em 2026-04-28 por Sina Kheirkhah / watchTowr Labs.
Início rápido · ioc-scan · mitigate · remote-probe · Versões afetadas · Ordem de prioridade
[!IMPORTANT] Os tiers 112, 114, 116, 120, 122, 128 não possuem patch do fornecedor. Toda build nesses tiers é vulnerável; atualizar ou migrar é a única correção durável. Até lá: bloqueie TCP/2082, 2083, 2086, 2087, 2095, 2096 para CIDRs de gerenciamento (
mitigate.sh --applyfaz isso) e proteja a superfície restante com o pacote de regras ModSec.
Três one-liners, em ordem de prioridade do 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
Os códigos de saída são projetados para automação de frota: `ioc-scan` sai com `4` em COMPROMETIDO, `1` em VULNERÁVEL; `mitigate` sai com `0` limpo / `1` aplicado / `2` manual / `3` erro de ferramenta; `remote-probe` sai com `2` se algum alvo estiver VULN.
---
## Ferramentas
Em ordem de prioridade operacional. Cada artefato emite saída estruturada (`--json` / `--jsonl` / `--csv`) indexada por `host`, `os`, `cpanel_version`, `ts` para agregação de frota.
| Ferramenta | Função | Onde é executado |
|---|---|---|
| **[`sessionscribe-ioc-scan.sh`](#sessionscribe-ioc-scansh---ioc-ladder--kill-chain)** | Triagem de primeira classe. Escada de IOC, vereditos de estado de código + estado do host, reconstrução da cadeia de eliminação, pacote de IR. | no host cPanel |
| **[`sessionscribe-mitigate.sh`](#sessionscribe-mitigatesh---mitigation-orchestrator)** | Fechar a janela. Mitigação em fases: verificação de patches, firewall, proxysub, ModSec. | no host cPanel |
| **[`sessionscribe-remote-probe.sh`](#sessionscribe-remote-probesh---non-destructive-fleet-probe)** | Colateral de suporte. Sonda não destrutiva de 4 estágios → VULN/SAFE por host. | em qualquer lugar com `curl` |
| [`modsec-sessionscribe.conf`](#supporting-collateral) | Pacote de regras ModSec implantado por `mitigate`. | front-end Apache |
| [`sessionscribe-revsnap.sh`](#supporting-collateral) | Coletor de snapshots RE por camada para diffing binário. | no host cPanel, por volta de `upcp` |
GPL v2. Todos os artefatos prontos para `curl` via URLs brutas acima.
---
## `sessionscribe-ioc-scan.sh` - Escada de IOC + cadeia de eliminação
**Execute isto primeiro.** Apenas detecção por padrão (rápido, amigável para frotas); adicione `--full` para executar as fases forenses inline (linha do tempo de defesa, ingestão de ofensiva, reconciliar, renderizador de cadeia de eliminação, pacote 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
Dois eixos reportam-se independentemente. code_verdict (PATCHED /
VULNERABLE / INCONCLUSIVE) provém da versão, padrões de código-fonte Perl
e da impressão digital do binário cpsrvd. host_verdict (CLEAN /
SUSPICIOUS / COMPROMISED) provém da escada de IOCs de ficheiros de sessão,
da análise dos logs de acesso e das sondas de destruição dos Padrões A–G. Um
host com patch pode ainda sair com 4 se uma exploração anterior deixou IOCs
em disco.
Sessões marcadas com nxesec_canary_<nonce> (deixadas pela sonda remota)
são classificadas como PROBE_ARTIFACT e não escalam para COMPROMISED.
--full agrupa todos os IOCs contra ativações de defesa e classifica
cada um como PRÉ-DEFESA, PÓS-DEFESA, PÓS-PARCIAL ou
SEM DEFESA, e depois resume com veredito + título de atraso de defesa.
PRÉ-DEFESA = o host estava aberto à exploração quando o indicador aterrou;
PÓS-DEFESA = ruído colateral ou pré-mitigação.```
+-- 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>Referência de verificações + fases forenses + estrutura do pacote</b> (clique para expandir)</summary>
| Verificação | O que faz |
|---|---|
| `version` | `cpanel -V` vs a lista de builds corrigidos publicada - orienta `code_verdict` |
| `static-pattern` | Pesquisa em `Cpanel/Session/*.pm` por padrões sentinela pós-correção (branch decode `no-ob:`) |
| `cpsrvd-fingerprint` | Inspeção binária do cpsrvd contra assinaturas de builds corrigidos |
| `access-log` | Logs Apache + cpsrvd para padrões de tráfego de exploração (`--no-logs` para pular) |
| `session-store` | Varredura de `/var/cpanel/sessions/raw/`: IOCs do fornecedor + co-ocorrência de 4 vias + heurística de timestamp forjado (`--no-sessions` para pular) |
| `destruction` | Sondagens dos padrões A–G: criptografador `/root/sshd`, mysql-wipe, índice BTC, `nuclear.x86`, revendedor `sptadm`, coletor `__S_MARK__`, chaves SSH suspeitas (`--no-destruction-iocs` para pular) |
| `probe` (opt-in) | GET de marcador único para `127.0.0.1:2087` - confirma que o cpsrvd está responsivo. **Não** tenta o bypass |
**Fases forenses `--full`** (executadas inline após detecção):
| Fase | O que faz |
|---|---|
| `defense` | Registra timestamps de cada camada de defesa aplicada: patch do cpanel, restart do cpsrvd pós-patch, execuções de mitigate, regras ModSec, fechamento de portas CSF/APF, proxysub, resumo do `upcp` |
| `offense` | Registra timestamps de cada indicador de comprometimento observado (Padrões A–G + cadeia de bypass CRLF do Padrão X) |
| `reconcile` | Por indicador: a defesa relevante estava ativa quando ele apareceu pela primeira vez? PRÉ-DEFESA / PÓS-DEFESA / PÓS-PARCIAL / SEM DEFESA + delta de tempo |
| `bundle` | Tarball de artefatos brutos em `/root/.ic5790-forensic/<TS>-<RUN_ID>/`, modo `0700` |
**Estrutura do pacote** (`/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)
Pacote típico em um host ocupado com janela de 90 dias: ~250 MB – 2 GB compactados.
Limite de 2 GB por tarball (--max-bundle-mb) descarta candidatos acima do tamanho individualmente.
Um registro de execução é escrito em /var/cpanel/sessionscribe-ioc/ por padrão
(--no-ledger para desativar). --chain-forensic / --chain-on-critical /
--chain-upload são preservados como aliases de retrocompatibilidade v1.x.
Substituições de teste de snapshot para perícia offline em tarballs extraídos:
--root DIR, --version-string S, --cpsrvd-path P. Consulte --help para
a lista completa de flags.
sessionscribe-mitigate.sh - orquestrador de mitigaçãoSomente leitura por padrão (--check). Adicione --apply para alterar o estado.
Idempotente: reexecutar em um host saudável não faz nada. As mutações escrevem
backups com carimbo de data/hora em /var/cpanel/sessionscribe-mitigation/
antes de tocar em qualquer arquivo.```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 | O que faz |
|---|---|
| `patch` | `cpanel -V` vs a lista publicada de builds corrigidas (incluindo EL6 11.86.0.41, EL6/CL6 110.0.103, tier 124, WP² 136.1.7) |
| `preflight` | Remove `/etc/yum.repos.d/threatdown.repo`; garante `epel-release`; desativa repositórios não‑base quebrados para que o `upcp` não morra durante a execução |
| `upcp` | Se não corrigido, inicia `/scripts/upcp --force --bg` |
| `proxysub` | Habilita `proxysubdomains` + variante de nova conta; reconstrói a configuração do httpd |
| `csf` / `apf` / `runfw` | Remove as portas do cpsrvd (2082/2083/2086/2087/2095/2096) de `TCP_IN`/`TCP6_IN`/`IG_TCP_CPORTS`; verifica a cadeia INPUT do iptables ao vivo |
| `apache` | `httpd` rodando + `security2_module` carregado |
| `modsec` | `modsec2.user.conf` contém as regras `1500030` + `1500031`; implementa se ausente (backup com timestamp, validação `httpd -t`, recarga graciosa) |
| `probe` (opt‑in) | Executa `sessionscribe-remote-probe.sh` contra `127.0.0.1` para confirmar negações na prática |
Os repositórios CentOS / Alma / Rocky base/appstream/extras/updates/powertools **nunca** são desativados pelo `preflight`, mesmo que atualmente inacessíveis.
### Códigos de saída
| Saída | Significado |
|---|---|
| 0 | limpo – corrigido + postura ok, nenhuma ação necessária |
| 1 | remediação aplicada com sucesso (`--apply` fez alterações) |
| 2 | intervenção manual necessária (avisa no `--check`, falha no `--apply`) |
| 3 | erro de ferramenta (argumentos incorretos, dependências ausentes, não root para `--apply`) |
Seleção de fase: `--only LIST`, `--no-PHASE`, `--no-fw` (abreviação para
`--no-csf --no-apf --no-runfw`). Saída: `--json` / `--jsonl` / `--csv`,
`-o FILE`. Veja `--help` para a lista completa de flags.
### Verificação rápida de sessenta 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
O orquestrador detecta um host não-cPanel e sai limpo — provando idempotência sem necessidade de um laboratório.
sessionscribe-remote-probe.sh - sonda de frota não destrutivaMaterial de apoio. Executa a cadeia de quatro estágios de forma não
destrutiva contra um alvo: mint preauth → CRLF inject → propagate
raw→cache → verificar via /json-api/version, em seguida, faz logout
ativamente. O sinal determinante do veredito é o código HTTP no
estágio 4: 200 ou 5xx com corpo de licença é VULN; 401 ou
403 é SAFE.
Cada sessão de teste é marcada com um atributo
nxesec_canary_<nonce> para limpeza forense, e nenhuma chamada de
API que altere o estado é feita. Sessões forjadas são equivalentes a
root por ~1–3s entre o estágio 3 e o logout do estágio 5 — veja o
cabeçalho do script para o modelo de segurança 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 saída: pretty (padrão), `-q`/`--quiet`, `--oneline`, `--csv`,
`--json`. Códigos de saída: `0` nenhuma VULN encontrada, `1` apenas inconclusivo, `2`
uma ou mais VULN. Consulte `--help` para a lista completa de opções, incluindo
`--auto-host-discover`, `--all`, `--fingerprint-only` semânticas, e
o modo `--no-verify` apenas do estágio 2 (legado, produz FPs em hosts
corrigidos).
---
## Material de apoio
### `modsec-sessionscribe.conf` - Pacote de regras ModSecurity
Implantado automaticamente por `mitigate.sh --apply --only modsec`. Manual
instalação:```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
Faixa de ID reservada: 1500000–1500099. As regras de token WHM usam @ipMatch
contra uma lista de confiança definida pelo operador — edite os CIDRs no topo do
arquivo antes de implantar.
[!IMPORTANT] Estas regras são executadas dentro do Apache.
cpsrvdescuta diretamente nas portas 2082/2083/2086/2087/2095/2096 e pode ser acessado independentemente do Apache. Emparelhe o pacote de regras com o firewall de porta cpsrvd para os CIDRs de gerenciamento.
sessionscribe-revsnap.sh - Coletor de snapshots RECaptura um tarball por camada (binários, strings, dynsym, disasm, módulos
Perl, layout de tempo de execução) para diffing binário em atualizações do cPanel.
Construído em torno do upcp para capturar pares pré/pós-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
Generaliza além do SessionScribe: cada futuro CVE do cpsrvd cairá aproximadamente na mesma superfície, e um par de tarballs para a build pré-patch e pós-patch é a diferença entre horas e dias de análise.
Consulte o [artigo de pesquisa](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940) para a análise completa de RE.
---
## Uso em frota
> [!TIP]
> Cada artefato emite saída estruturada (`--json`, `--jsonl`, `--csv`) com `host`, `os`, `cpanel_version`, `ts` em cada registro. Projetado para agregação via `pdsh | jq` ou `ansible -m script` em centenas de hosts em uma única passagem.
Mesmo primitivo curl-piped-bash — deixe cada host buscar e executar o script mais recente diretamente:```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
A sonda é independentemente segura para frotas (sessões marcadas com canário, logout ativo, nenhuma chamada de API que altere estado). Os scripts no host respeitam as flags --quiet e structured-output, para que o stdout fique limpo para parser.
Quatro requisições HTTP, sem autenticação, sem pré-condições:```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
O veredito é o código HTTP na requisição 4. O arquivo de sessão em disco em
`/var/cpanel/sessions/raw/<sessname>` é o único artefato forense post-hoc.
A primitiva completa (as duas assimetrias componentes —
`filter_sessiondata` não em todos os caminhos de escrita, o codificador faz curto-circuito
na falta de `ob_part`) e o argumento arquitetural para a imposição de proxy-endpoint
estão no
[artigo de pesquisa](https://rfxn.com/research/cpanel-sessionscribe-cve-2026-41940).
---
## Indicadores de comprometimento
Forma de arquivo de sessão forjado (`/var/cpanel/sessions/raw/<sessname>` após
exploração):```
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
Uma sessão preauth normal nunca contém pass=, hasroot=1, user=root, tfa_verified=1 ou successful_internal_auth_with_timestamp=. Qualquer um desses combinado com origin_as_string=…method=badpass é diagnóstico. Um valor de timestamp falsificado além de now+365d (por exemplo, 9999999999) é independentemente 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
Sinal de log de acesso: respostas `200`/`302`/`307` bem-sucedidas nos
caminhos `/json-api/`, `/execute/` ou `/scripts2/` de IPs de origem não basais
sem um `/login/` 200 precedente na mesma janela de sessão.
---
## Compilações afetadas```
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
Camadas excluídas da lista de patches do fornecedor não têm correção local: 112, 114, 116, 120, 122, 128. Hosts nessas camadas devem ser atualizados para uma série principal corrigida, migrados, ou ter seus listeners cpsrvd protegidos por firewall até que estejam.
11.86.0.41 (EL6/CL7) foi adicionado na revisão de aviso de 29/04; 11.130
foi atualizado de .18 para .19 na mesma revisão. Uma revisão
subsequente adicionou 11.124.0.35 (fechando a lacuna anterior na camada 124) e
110.0.103 como um alvo de atualização direta para hosts EL6/CL6 ainda na
v110.0.50.
Imediato
sessionscribe-ioc-scan.sh em toda a frota. Um host corrigido ainda
pode estar comprometido.Futuro
modsec-sessionscribe.conf em modsec2.user.conf com a
lista de confiança @ipMatch configurada.O caso arquitetônico para a aplicação de proxy-endpoint é o terço final do artigo de pesquisa.
cpsrvd, cpsrvd.so, ou
Cpanel/Session/*.pm. O backport emitido pelo cPanel para sua camada é
a correção real.proxysub + firewall do orquestrador, juntamente com o pacote de regras
ModSec, reduzem o raio de explosão; atualização ou migração é a única
resposta durável.nxesec_canary_<nonce> para limpeza e faz logout ativamente.ioc-scan encontra artefatos de
exploração anterior; não os corrige. Trate seu veredito COMPROMISED
como um gatilho para IR completo, não uma conclusão.[!TIP] Encontrou um bug, IOC perdido, falso positivo ou tem feedback operacional? Abra uma issue no GitHub - relatos de bugs, variantes de IOC vistas em campo, falhas de detecção em hosts corrigidos/não corrigidos, falsos positivos de regras ModSec e feedback geral de operadores são bem-vindos.
Divulgações sensíveis (evidências de exploração ativa, dados de clientes, cadeias de exploração inéditas ainda não públicas) devem ser enviadas via Keybase ou email, não por Issues do GH.
GPL v2. Veja os cabeçalhos dos arquivos individuais.
Forjado durante a resposta ao incidente SessionScribe - Ryan MacDonald, R-fx Networks.
| Saída | Estado-código | Estado-host | Ação de triagem |
|---|
| 0 | CLEAN/PATCHED | CLEAN | nenhuma |
| 1 | VULNERABLE | (qualquer) | aplicar patch no cpsrvd |
| 2 | INCONCLUSIVE | (qualquer) | revisão manual do estado do código (também: erro da ferramenta) |
| 3 | (qualquer) | SUSPICIOUS | revisar logs de sessão/acesso |
| 4 | (qualquer) | COMPROMISED | IR completo; agrupar + enviar |
| Regra | Superfície | Ação |
|---|
1500030 | CRLF dentro do payload decodificado Authorization: Basic | negar, todas as origens, todos os caminhos |
1500031 | Cookie whostmgrsession sem sufixo válido ,OBHEX | negar (defesa em profundidade) |
1500010 | Authorization: WHM em /json-api/, /execute/, /acctxfer*/ | negar quando a origem não estiver na lista de confiança |
1500020 | Authorization: WHM na família de despacho WebSocket | negar quando a origem não estiver na lista de confiança |
1500021 | Authorization: WHM no caminho de despacho SSE | negar quando a origem não estiver na lista de confiança |