
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
Informe: https://abraxaslabs.tech/research/signal-server-dropwizard-admin
Clase: Privilegio residual Alcance: Remoto
Signal-Server v20261007.0.0 (a15d5cd) - Signal Messenger, LLC
DefaultServerFactory de Dropwizard 5.0.2 incluye un conector HTTP de administración 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 un bloque server:. Un YAML que solo enumera applicationConnectors TLS sigue heredando el 8081 en texto plano en 0.0.0.0. server junto con 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 de 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. Muestra 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 adicional 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 | Confirma que el listener de administración está activo. El cuerpo es pong. |
| GET | /metrics | Lee el registro Codahale completo como JSON: heap y non-heap de la JVM, recuentos de GC, recuentos de hilos, medidores del conector Jetty, gauges 4xx/5xx, temporizadores. Úsalo para identificar el proceso, estimar la carga y observar el efecto de tareas posteriores. |
| GET | /threads | Volcado completo de hilos de la JVM: nombre, id, estado y marcos de pila de cada hilo. 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 se encuentre en una pila (rutas de archivos, nombres de host, toString de argumentos en curso). No es un volcado de heap y no es un volcado de cola de mensajes. |
| GET | /healthcheck | Ejecuta las comprobaciones de estado registradas. Este árbol nunca registra extras, así que el cuerpo es la comprobación de interbloqueo por defecto (deadlocks.healthy). Un 200 frente a un 500 te indica si la JVM cree que está en interbloqueo. |
| GET | /tasks | Lista las tareas de administración. En esta versión: gc, log-level, set-request-logging-enabled. |
| Método | Ruta | Privilegio |
|---|---|---|
| POST | /tasks/log-level?logger=<name>&level=<LEVEL> | Establece cualquier logger de Logback en 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 en un logger de seguridad o de acceso lo deja a oscuras. El atacante no recibe el flujo de logs a través de este HTTP. Cambian lo que el proceso escribe en disco o en stdout. Oráculo de laboratorio: nombre de logger SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS a TRACE. |
| POST | /tasks/gc | Llama a System.gc(). La respuesta es Running GC... / Done!. Eso es un empujón de stop-the-world, no la muerte del proceso. |
| POST | /tasks/set-request-logging-enabled?enabled=true | Tarea de solo señal registrada en WhisperServerService.run. Habilita el filtro de log de acceso a peticiones (RequestLogManager). Después de eso, el HTTP al conector de la aplicación puede escribir el método, la URI y las cabeceras (incluida Authorization Basic) en el log de acceso en disco. El cliente de administración no recibe esas líneas de vuelta. En message-persister-service / APN / workers de trabajos inactivos el puerto de la aplicación no tiene recursos de Signal Jersey, por lo que esta tarea importa en server. enabled=false lo desactiva de nuevo. |
ProcessBuilder, sin Runtime.exec.GET /heapdump es 404.sample.yml ni en las direcciones de enlace.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, gRPC omnibus y HTTP saliente volvieron vacíos en Crítico/Alto. La búsqueda de workers/admin no. Dropwizard 5.0.2 HttpConnectorFactory.admin() sigue usando el puerto 8081 y un host de enlace nulo. Signal nunca establece adminConnectors. El admin predeterminado de Caddy es localhost. Este no lo es.
Giro equivocado: intentar arrancar el Signal-Server completo. sample.yml pasa check y aun así necesita FoundationDB, Dynamo, Redis y un paquete de secretos para run. El remanente es el conector del framework que ServerCommand inicia antes de todo eso. El laboratorio es Dropwizard 5.0.2 con el mismo YAML server: vacío y el nombre de tarea extra de Signal.
cd lab
./run.sh
Loopback 127.0.0.1:19010. Proyecto de Compose signal-server-dropwizard-admin. Testigo 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: