
Signal-Server v20261007.0.0 - 높음 - 원격 - 권한 잔존 - 인증 없는 Dropwizard admin :8081
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · signal-server-dropwizard-admin
분석 문서: https://abraxaslabs.tech/research/signal-server-dropwizard-admin
분류: 권한 잔존 도달 범위: 원격
Signal-Server v20261007.0.0 (a15d5cd) - Signal Messenger, LLC
Dropwizard 5.0.2 DefaultServerFactory는 포트 8081에 HTTP 관리 커넥터를 제공하며, bindHost가 설정되지 않고(모든 인터페이스) 관리자 인증이 없습니다. Signal-Server는 이를 결코 재정의하지 않습니다. service/config/sample.yml에는 server: 블록이 없습니다. TLS applicationConnectors만 나열한 YAML도 0.0.0.0의 평문 8081을 그대로 상속합니다. server와 세 개의 ServerCommand 워커가 이를 시작합니다. ExternalRequestFilter는 애플리케이션 컨텍스트에만 적용됩니다.
:8081에 대한 인증 없는 HTTP가 운영 관리 평면입니다. RCE가 아닙니다. 계정 탈취가 아닙니다. 봉인된 메시지 열람이 아닙니다.
| ID | 아직 CVE 없음 |
| 분류 | 권한 잔존 (인증 없는 Dropwizard 관리자) |
| 도달 범위 | 원격 (모든 인터페이스 :8081, 인증 없음) |
| CWE | CWE-306, CWE-1188 |
| CVSS | 높음: 7.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L |
| 제품 | Signal-Server |
| 영향 받는 버전 | v20261007.0.0 (a15d5cd) Dropwizard 5.0.2. 저장소 내 샘플 / 생략된 adminConnectors. |
| 인증 | 관리 커넥터에 없음 |
| 라이선스 | GNU Affero GPL v3.0 |
| 실습 환경 | 127.0.0.1 전용 |
관리 포트(기본 0.0.0.0:8081, 추가 설정 없음, Authorization 헤더 없음)에 TCP 연결을 열 수 있는 사람은 누구나 모든 기본 Dropwizard 5 관리 서블릿과 Signal의 추가 태스크에 접근할 수 있습니다. 이것이 전체 권한 집합입니다. 이 목록의 어떤 항목도 RCE, ATO, 또는 봉인된 메시지 본문 열람이 아닙니다.
| 메서드 | 경로 | 권한 |
|---|---|---|
| GET | /ping | 관리 리스너가 작동 중인지 확인합니다. 본문은 pong입니다. |
| GET | /metrics | 전체 Codahale 레지스트리를 JSON으로 읽습니다: JVM 힙 및 비힙, GC 횟수, 스레드 수, Jetty 커넥터 미터, 4xx/5xx 게이지, 타이머. 이를 사용하여 프로세스를 핑거프린팅하고, 부하를 추정하며, 이후 태스크의 효과를 관찰합니다. |
| GET | /threads | 전체 JVM 스레드 덤프: 모든 스레드 이름, ID, 상태, 스택 프레임. 실습 환경에서는 dw-admin-*와 java.base nio 프레임이 표시되었습니다. 실제 Signal 노드에서는 동일한 덤프에 클래스 이름, 로거 이름, 그리고 스택에 우연히 존재하는 모든 문자열(파일 경로, 호스트 이름, 진행 중인 인자의 toString)이 포함될 수 있습니다. 이는 힙 덤프가 아니며 메시지 큐 덤프도 아닙니다. |
| GET | /healthcheck | 등록된 상태 검사를 실행합니다. 이 트리는 추가 항목을 등록하지 않으므로 본문은 기본 교착 상태 검사(deadlocks.healthy)입니다. 200 대 500은 JVM이 스스로 교착 상태라고 판단하는지 알려줍니다. |
| GET | /tasks | 관리 태스크를 나열합니다. 이 버전에서는: gc, log-level, set-request-logging-enabled. |
| 메서드 | 경로 | 권한 |
|---|---|---|
| POST | /tasks/log-level?logger=<name>&level=<LEVEL> | 모든 Logback 로거를 TRACE, DEBUG, INFO, WARN, ERROR 또는 OFF로 설정한다. TRACE는 애플리케이션 로거가 더 많은 내용(개발자가 기록한 값 포함)을 출력하게 만들 수 있다. 보안 또는 접근 로거에 OFF를 설정하면 로그가 꺼진다. 공격자는 이 HTTP를 통해 로그 스트림을 받지 않는다. 공격자는 프로세스가 디스크나 stdout에 기록하는 내용을 변경한다. 실습 오라클: 로거 이름 SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS를 TRACE로 설정. |
| POST | /tasks/gc | System.gc()를 호출한다. 응답은 Running GC... / Done!이다. 이는 stop-the-world를 유도하는 것이지 프로세스를 종료시키는 것이 아니다. |
| POST | /tasks/set-request-logging-enabled?enabled=true | WhisperServerService.run에 등록된 Signal 전용 태스크. 요청 접근 로그 필터(RequestLogManager)를 활성화한다. 그 후 애플리케이션 커넥터로의 HTTP는 메서드, URI, 헤더(Authorization Basic 포함)를 디스크의 접근 로그에 기록할 수 있다. 관리 클라이언트는 해당 줄을 돌려받지 못한다. message-persister-service / APN / idle-job 워커에서는 애플리케이션 포트에 Signal Jersey 리소스가 없으므로, 이 태스크는 server에서 중요하다. enabled=false는 다시 끈다. |
ProcessBuilder 없음, Runtime.exec 없음.GET /heapdump는 404이다.sample.yml 또는 바인드 주소 변경 없음.같은 Docker 네트워크의 형제 컨테이너는 http://vuln:8081/ping(200 pong)에 도달했고, bindHost가 127.0.0.1일 때 http://patched:8081/ping에는 도달할 수 없었다. 이것이 Remote 절반이다.
signalapp/Signal-Server v20261007.0.0을 고정했다. 열여덟 번의 소스 탐색. 채팅, 키, 메시지, 백업, 기부, 통화, MFA, gRPC 옴니버스, 아웃바운드 HTTP는 Critical/High에서 아무것도 나오지 않았다. 워커/관리자 탐색은 달랐다. Dropwizard 5.0.2 HttpConnectorFactory.admin()은 여전히 포트 8081과 null 바인드 호스트를 사용한다. Signal은 adminConnectors를 설정하지 않는다. Caddy의 기본 관리자는 localhost이다. 이것은 아니다.
잘못된 방향: 전체 Signal-Server를 부팅하려는 시도. sample.yml은 check를 통과하지만 run에는 여전히 FoundationDB, Dynamo, Redis, 시크릿 번들이 필요하다. 잔여물은 ServerCommand가 그 모든 것보다 먼저 시작하는 프레임워크 커넥터이다. 실습은 동일한 빈 server: YAML과 Signal의 추가 태스크 이름을 가진 Dropwizard 5.0.2이다.
cd lab
./run.sh
루프백 127.0.0.1:19010. Compose 프로젝트 signal-server-dropwizard-admin. Witness SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS. Gadget YAML에는 server: 블록이 없습니다. Negative YAML은 bindHost: 127.0.0.1을 설정합니다. 마지막 줄:
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
관리자를 127.0.0.1에 바인딩하고, adminConnectors: []를 설정하거나, 관리자 컨텍스트에 인증 / mTLS를 적용하세요. 애플리케이션 커넥터만 나열한 YAML을 배포하면서 8081이 꺼져 있을 것이라고 가정하지 마세요.
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]