
Signal-Server v20261007.0.0 - Alta - Remoto - Privilegio residual - admin de Dropwizard sin autenticación :8081
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · signal-server-dropwizard-admin
Clase: Privilegio residual Alcance: Remoto
Signal-Server v20261007.0.0 (a15d5cd) - Signal Messenger, LLC
Dropwizard 5.0.2 DefaultServerFactory incluye un conector de administración HTTP en el puerto 8081 con bindHost sin establecer (todas las interfaces) y sin autenticación de administración. Signal-Server nunca lo sobrescribe. service/config/sample.yml no tiene bloque server:. Un YAML que solo lista applicationConnectors TLS igualmente hereda el 8081 en texto plano sobre 0.0.0.0. server más los tres workers de ServerCommand lo inician. ExternalRequestFilter está solo en el contexto de la aplicación.
HTTP sin autenticación a :8081 es el plano de administración operativo. No es RCE. No es toma de control de cuentas. No es lectura de mensajes sellados.
| ID | aún sin CVE |
| Clase | Privilegio residual (administración Dropwizard sin autenticación) |
| Alcance | Remoto (:8081 en todas las interfaces, sin autenticación) |
| 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 |
| Producto | Signal-Server |
| Afectado | v20261007.0.0 (a15d5cd) Dropwizard 5.0.2. Ejemplo en el árbol / adminConnectors omitido. |
| Autenticación | ninguna en el conector de administración |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
Cualquiera que pueda abrir TCP al puerto de administración (por defecto 0.0.0.0:8081, sin configuración adicional, sin cabecera Authorization) obtiene todos los servlets de administración estándar de Dropwizard 5 más la tarea extra de Signal. Ese es el conjunto completo de privilegios. Nada en esta lista es RCE, ATO ni una lectura de cuerpos de mensajes sellados.
| Método | Ruta | Privilegio |
|---|---|---|
| GET | /ping | Confirmar que el listener de administración está activo. El cuerpo es pong. |
| GET | /metrics | Leer el registro completo de Codahale como JSON: heap y non-heap de la JVM, conteos de GC, conteos de hilos, medidores del conector Jetty, gauges 4xx/5xx, timers. Úsalo para hacer fingerprint del proceso, estimar la carga y observar el efecto de tareas posteriores. |
| GET | /threads | Volcado completo de hilos de la JVM: nombre de cada hilo, id, estado y marcos de pila. En el laboratorio esto mostró dw-admin-* más marcos nio de java.base. En un nodo Signal en producción el mismo volcado puede incluir nombres de clases, nombres de loggers y cualquier cadena que esté en una pila (rutas de archivos, hostnames, toString de argumentos en vuelo). No es un volcado de heap y no es un volcado de cola de mensajes. |
| GET | /healthcheck | Ejecutar las comprobaciones de salud registradas. Este árbol nunca registra extras, así que el cuerpo es la comprobación de deadlock por defecto (deadlocks.healthy). Un 200 frente a un 500 te dice si la JVM cree que está en deadlock. |
| GET | /tasks | Listar las tareas de administración. En este pin: gc, log-level, set-request-logging-enabled. |
| Método | Ruta | Privilegio |
|---|---|---|
| POST | /tasks/log-level?logger=<name>&level=<LEVEL> | Establecer cualquier logger de Logback a TRACE, DEBUG, INFO, WARN, ERROR u OFF. TRACE puede hacer que los loggers de la aplicación impriman más (incluidos valores que un desarrollador registró). OFF sobre un logger de seguridad o de acceso lo deja a oscuras. El atacante no recibe el flujo de logs por este HTTP. Cambian lo que el proceso escribe en disco o stdout. Oráculo del laboratorio: nombre de logger SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS a TRACE. |
| POST | /tasks/gc | Llamar a System.gc(). La respuesta es Running GC... / Done!. Eso es un empujón stop-the-world, no la muerte del proceso. |
| POST | /tasks/set-request-logging-enabled?enabled=true | Tarea exclusiva de Signal registrada en WhisperServerService.run. Habilita el filtro de log de acceso de peticiones (RequestLogManager). Después de eso, el HTTP al conector de aplicación puede escribir método, URI y cabeceras (incluida Authorization Basic) en el log de acceso en disco. El cliente de administración no recibe esas líneas de vuelta. En los workers message-persister-service / APN / idle-job el puerto de aplicación no tiene recursos Jersey de Signal, así que esta tarea importa en server. enabled=false la vuelve a desactivar. |
ProcessBuilder, ni Runtime.exec.GET /heapdump es 404.sample.yml ni de las direcciones de bind.Un contenedor hermano en la misma red Docker alcanzó http://vuln:8081/ping (200 pong) y no pudo alcanzar http://patched:8081/ping cuando bindHost era 127.0.0.1. Esa es la mitad Remota.
Fijé signalapp/Signal-Server v20261007.0.0. Dieciocho búsquedas en el código fuente. Chat, claves, mensajes, copias de seguridad, donaciones, llamadas, MFA, el ómnibus gRPC y el HTTP saliente volvieron vacíos en Critical/High. La búsqueda de workers/administración no. Dropwizard 5.0.2 HttpConnectorFactory.admin() sigue usando el puerto 8081 y un bind host nulo. Signal nunca establece adminConnectors. La administración por defecto de Caddy es localhost. Esta no.
Camino equivocado: intentar arrancar el Signal-Server completo. sample.yml pasa check y aún necesita FoundationDB, Dynamo, Redis y un paquete de secretos para run. El residuo es el conector del framework que ServerCommand inicia antes de todo eso. El laboratorio es Dropwizard 5.0.2 con el mismo YAML con server: vacío y el nombre de la tarea extra de Signal.
cd lab
./run.sh
Loopback 127.0.0.1:19010. Proyecto de Compose signal-server-dropwizard-admin. Witness SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS. El YAML del gadget no tiene bloque server:. El YAML negativo establece bindHost: 127.0.0.1. Última línea:
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