
Signal-Server v20261007.0.0 - उच्च - रिमोट - विशेषाधिकार शेष - unauth Dropwizard admin :8081
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · signal-server-dropwizard-admin
Class: Privilege leftover Reach: Remote
Signal-Server v20261007.0.0 (a15d5cd) - Signal Messenger, LLC
Dropwizard 5.0.2 DefaultServerFactory पोर्ट 8081 पर एक HTTP admin connector के साथ आता है, जिसमें bindHost unset (सभी interfaces) है और कोई admin authentication नहीं है। Signal-Server इसे कभी override नहीं करता। service/config/sample.yml में कोई server: block नहीं है। एक YAML जो केवल TLS applicationConnectors को सूचीबद्ध करता है, वह अभी भी 0.0.0.0 पर plaintext 8081 को inherit करता है। server और तीन ServerCommand workers इसे शुरू करते हैं। ExternalRequestFilter केवल application context पर है।
:8081 पर unauth HTTP ही operational admin plane है। RCE नहीं। Account takeover नहीं। Sealed-message read नहीं।
| ID | अभी तक कोई CVE नहीं |
| Class | Privilege leftover (unauthenticated Dropwizard admin) |
| Reach | Remote (all-interfaces :8081, कोई auth नहीं) |
| CWE | CWE-306, CWE-1188 |
| CVSS | High: 7.3 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L |
| Product | Signal-Server |
| Affected | v20261007.0.0 (a15d5cd) Dropwizard 5.0.2. In-tree sample / छोड़ा गया adminConnectors. |
| Auth | admin connector पर कोई नहीं |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1 |
कोई भी व्यक्ति जो admin port (default 0.0.0.0:8081, कोई अतिरिक्त config नहीं, कोई Authorization header नहीं) पर TCP खोल सकता है, उसे हर stock Dropwizard 5 admin servlet के साथ-साथ Signal का अतिरिक्त task भी मिलता है। यही पूरा privilege set है। इस सूची में कुछ भी RCE, ATO, या sealed message bodies का read नहीं है।
| Method | Path | Privilege |
|---|---|---|
| GET | /ping | पुष्टि करें कि admin listener चालू है। Body pong है। |
| GET | /metrics | पूरी Codahale registry को JSON के रूप में पढ़ें: JVM heap और non-heap, GC counts, thread counts, Jetty connector meters, 4xx/5xx gauges, timers। इसका उपयोग process को fingerprint करने, load का अनुमान लगाने, और बाद के tasks के प्रभाव को देखने के लिए करें। |
| GET | /threads | पूरा JVM thread dump: हर thread का नाम, id, state, और stack frames। Lab में इसने dw-admin-* के साथ-साथ java.base nio frames दिखाए। एक live Signal node पर वही dump class names, logger names, और कोई भी string जो संयोग से stack पर पड़ी हो (file paths, hostnames, in-flight argument toString) शामिल कर सकता है। यह heap dump नहीं है और यह message-queue dump नहीं है। |
| GET | /healthcheck | पंजीकृत health checks चलाएँ। यह tree कभी extras register नहीं करता, इसलिए body default deadlock check (deadlocks.healthy) है। 200 बनाम 500 आपको बताता है कि JVM को लगता है कि वह deadlocked है या नहीं। |
| GET | /tasks | Admin tasks की सूची बनाएँ। इस pin पर: gc, log-level, set-request-logging-enabled। |
| Method | Path | Privilege |
|---|---|---|
| POST | /tasks/log-level?logger=<name>&level=<LEVEL> | किसी भी Logback logger को TRACE, DEBUG, INFO, WARN, ERROR, या OFF पर सेट करें। TRACE application loggers को अधिक प्रिंट करा सकता है (जिसमें developer द्वारा log किए गए values भी शामिल हैं)। किसी security या access logger पर OFF उसे अंधकारमय कर देता है। Attacker को इस HTTP के माध्यम से log stream नहीं मिलता। वे बदलते हैं कि process disk या stdout पर क्या लिखता है। Lab oracle: logger name SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS से TRACE। |
| POST | /tasks/gc | System.gc() को कॉल करें। Response Running GC... / Done! है। यह एक stop-the-world nudge है, process death नहीं। |
| POST | /tasks/set-request-logging-enabled?enabled=true | WhisperServerService.run में पंजीकृत Signal-only task। Request access-log filter (RequestLogManager) को सक्षम करता है। उसके बाद, application connector पर HTTP method, URI, और headers (जिसमें Authorization Basic भी शामिल है) को disk पर access log में लिख सकता है। Admin client को वे lines वापस नहीं मिलतीं। message-persister-service / APN / idle-job workers पर application port में कोई Signal Jersey resources नहीं हैं, इसलिए यह task server पर मायने रखता है। enabled=false इसे फिर से बंद कर देता है। |
ProcessBuilder नहीं, कोई Runtime.exec नहीं।GET /heapdump 404 है।sample.yml या bind addresses में कोई बदलाव नहीं।उसी Docker network पर एक sibling container ने http://vuln:8081/ping (200 pong) तक पहुँच बनाई और जब bindHost 127.0.0.1 था तो http://patched:8081/ping तक नहीं पहुँच सका। यही Remote वाला आधा हिस्सा है।
मैंने signalapp/Signal-Server v20261007.0.0 को pin किया। अठारह source hunts। Chat, keys, messages, backups, donations, calling, MFA, gRPC omnibus, और outbound HTTP Critical/High पर खाली लौटे। Workers/admin hunt नहीं लौटा। Dropwizard 5.0.2 HttpConnectorFactory.admin() अभी भी port 8081 और null bind host का उपयोग करता है। Signal कभी adminConnectors सेट नहीं करता। Caddy का default admin localhost है। यह नहीं है।
गलत मोड़: पूरा Signal-Server boot करने की कोशिश। sample.yml check पास करता है और run करने के लिए अभी भी FoundationDB, Dynamo, Redis, और एक secrets bundle की आवश्यकता होती है। Leftover वह framework connector है जिसे ServerCommand इन सबसे पहले शुरू करता है। Lab Dropwizard 5.0.2 है जिसमें वही खाली server: YAML और Signal का अतिरिक्त task name है।
cd lab
./run.sh
Loopback 127.0.0.1:19010। Compose project signal-server-dropwizard-admin। Witness SIGNAL-SERVER-DROPWIZARD-ADMIN-WITNESS। Gadget YAML में कोई server: block नहीं है। 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
Admin को 127.0.0.1 पर bind करें, adminConnectors: [] सेट करें, या admin context पर authentication / mTLS लगाएँ। ऐसा YAML ship न करें जो केवल application connectors को सूचीबद्ध करता हो और मान ले कि 8081 बंद रहा।
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]