
Signal-Server v20261007.0.0 - Alta - Remoto - Privilegio residuo - admin Dropwizard non autenticato :8081
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · signal-server-dropwizard-admin
Classe: Privilegio residuo Portata: Remota
Signal-Server v20261007.0.0 (a15d5cd) - Signal Messenger, LLC
Dropwizard 5.0.2 DefaultServerFactory espone un connettore admin HTTP sulla porta 8081 con bindHost non impostato (tutte le interfacce) e senza autenticazione admin. Signal-Server non lo sovrascrive mai. service/config/sample.yml non ha alcun blocco server:. Un YAML che elenca solo applicationConnectors TLS eredita comunque la 8081 in chiaro su 0.0.0.0. server insieme ai tre worker ServerCommand lo avvia. ExternalRequestFilter è solo sul contesto dell'applicazione.
HTTP non autenticato verso :8081 è il piano admin operativo. Non è RCE. Non è account takeover. Non è lettura di messaggi sigillati.
| ID | nessuna CVE al momento |
| Classe | Privilegio residuo (admin Dropwizard non autenticato) |
| Portata | Remota (:8081 su tutte le interfacce, senza auth) |
| CWE | CWE-306, CWE-1188 |
| CVSS | Alto: 7.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L |
| Prodotto | Signal-Server |
| Affetto | v20261007.0.0 (a15d5cd) Dropwizard 5.0.2. Sample in-tree / adminConnectors omesso. |
| Auth | nessuna sul connettore admin |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Chiunque possa aprire una TCP verso la porta admin (default 0.0.0.0:8081, nessuna configurazione aggiuntiva, nessun header Authorization) ottiene ogni servlet admin standard di Dropwizard 5 più il task extra di Signal. Questo è l'intero insieme di privilegi. Nulla in questa lista è RCE, ATO o lettura di corpi di messaggi sigillati.
| Metodo | Path | Privilegio |
|---|---|---|
| GET | /ping | Conferma che il listener admin è attivo. Il body è pong. |
| GET | /metrics | Legge l'intero registry Codahale come JSON: heap e non-heap della JVM, conteggi GC, conteggi thread, meter dei connettori Jetty, gauge 4xx/5xx, timer. Usalo per fare fingerprint del processo, stimare il carico e osservare l'effetto dei task successivi. |
| GET | /threads | Thread dump completo della JVM: nome di ogni thread, id, stato e stack frame. Nel lab questo mostrava dw-admin-* più frame nio di java.base. Su un nodo Signal in produzione lo stesso dump può includere nomi di classi, nomi di logger e qualsiasi stringa che si trovi sullo stack (path di file, hostname, toString di argomenti in transito). Non è un heap dump e non è un dump della coda dei messaggi. |
| GET | /healthcheck | Esegue gli health check registrati. Questo albero non registra extra, quindi il body è il controllo deadlock di default (deadlocks.healthy). Un 200 vs 500 ti dice se la JVM ritiene di essere in deadlock. |
| GET | /tasks | Elenca i task admin. Su questo pin: gc, log-level, set-request-logging-enabled. |
| Metodo | Path | Privilegio |
|---|---|---|
| POST | /tasks/log-level?logger=<name>&level=<LEVEL> | Imposta qualsiasi logger Logback a TRACE, DEBUG, INFO, WARN, ERROR o OFF. TRACE può far stampare di più ai logger dell'applicazione (inclusi valori che uno sviluppatore ha loggato). OFF su un logger di sicurezza o di accesso lo rende cieco. L'attaccante non riceve lo stream dei log tramite questo HTTP. Cambia ciò che il processo scrive su disco o su stdout. Oracle del lab: nome logger SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS a TRACE. |
| POST | /tasks/gc | Chiama System.gc(). La risposta è Running GC... / Done!. È una spinta stop-the-world, non la morte del processo. |
| POST | /tasks/set-request-logging-enabled?enabled=true | Task solo di Signal registrato in WhisperServerService.run. Abilita il filtro di access-log delle richieste (RequestLogManager). Dopo di che, l'HTTP verso il connettore applicativo può scrivere metodo, URI e header (incluso Authorization Basic) nell'access log su disco. Il client admin non riceve indietro quelle righe. Sui worker message-persister-service / APN / idle-job la porta applicativa non ha risorse Signal Jersey, quindi questo task conta su server. enabled=false lo disattiva di nuovo. |
ProcessBuilder, nessun Runtime.exec.GET /heapdump è 404.sample.yml o agli indirizzi di bind.Un container sibling sulla stessa rete Docker raggiungeva http://vuln:8081/ping (200 pong) e non riusciva a raggiungere http://patched:8081/ping quando bindHost era 127.0.0.1. Questa è la metà Remota.
Ho fissato signalapp/Signal-Server v20261007.0.0. Diciotto ricerche nel sorgente. Chat, chiavi, messaggi, backup, donazioni, chiamate, MFA, omnibus gRPC e HTTP in uscita sono risultati vuoti a livello Critical/High. La ricerca su worker/admin no. Dropwizard 5.0.2 HttpConnectorFactory.admin() usa ancora la porta 8081 e un bind host nullo. Signal non imposta mai adminConnectors. L'admin di default di Caddy è su localhost. Questo no.
Falsa pista: provare ad avviare l'intero Signal-Server. sample.yml passa check e richiede comunque FoundationDB, Dynamo, Redis e un bundle di segreti per run. Il residuo è il connettore del framework che ServerCommand avvia prima di tutto ciò. Il lab è Dropwizard 5.0.2 con lo stesso YAML server: vuoto e il nome del task extra di Signal.
cd lab
./run.sh
Loopback 127.0.0.1:19010. Progetto Compose signal-server-dropwizard-admin. Witness SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS. Lo YAML gadget non ha alcun blocco server:. Lo YAML negativo imposta bindHost: 127.0.0.1. Ultima riga:
SUCCESS signal-server-dropwizard-admin how=unauth-admin-8081 ping=200 metrics=200 threads=200 healthcheck=200 tasks=200 log-level=TRACE gc=200 set-log=enabled bind=* remote-vuln=200 remote-patched=fail SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS
Fai il bind dell'admin su 127.0.0.1, imposta adminConnectors: [], oppure metti autenticazione / mTLS sul contesto admin. Non distribuire uno YAML che elenca solo i connettori applicativi e dare per scontato che la 8081 sia rimasta spenta.
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]