
प्रोमेथियस v3.15.0 - उच्च - रिमोट - SSRF - http_sd __unix_socket__ अनसैनिटाइज़्ड डायल UDS स्क्रैप का अवशेष
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · prometheus-unix-socket-dial
वर्ग: SSRF पहुँच: रिमोट
Prometheus v3.15.0 (5241a27) - CNCF / Prometheus
v3.15.0 में Unix Domain Socket स्क्रैप (#12024 / #18091) जोड़ा गया। यह पथ एक टारगेट लेबल __unix_socket__ है, ऑपरेटर allowlist नहीं। http_sd और file_sd उस लेबल को ज्यों का त्यों कॉपी कर देते हैं। PopulateLabels इसे कभी मान्य नहीं करता। फिर newUnixSocketScrapeClient बिना किसी filepath.Clean, बिना allowlist, और ../ या Linux abstract @ नामों को अस्वीकार किए DialContext(ctx, "unix", socketPath) कॉल करता है।
TCP स्क्रैप ऐसा नहीं कर सकता। CheckTargetAddress अभी भी उन __address__ मानों को हटा देता है जिनमें / होता है, इसलिए unix:///var/run/docker.sock को पते के रूप में अस्वीकार कर दिया जाता है। नया लेबल ही छेद है।
स्टॉक कॉन्फ़िग लेबल सेट नहीं करता। Prometheus पर अनऑथ HTTP से जॉब्स नहीं जोड़े जा सकते। यह SD-गेटेड है।
| ID | अभी कोई CVE नहीं |
| वर्ग | SSRF (SD लेबल्स से अनसैनिटाइज़्ड unix Dial) |
| पहुँच | रिमोट (SD-गेटेड: http_sd / file_sd का लेखक) |
| CWE | CWE-918, CWE-22 |
| CVSS | High: 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| उत्पाद | Prometheus |
| प्रभावित | v3.15.0 (5241a27fe3c6983549fccc32f6e65917408c63cd), इमेज prom/prometheus:v3.15.0 |
| प्रमाणीकरण | SD-गेटेड: http_sd / file_sd लेबल्स का लेखक (या एक relabel जो अविश्वसनीय मेटा को __unix_socket__ में कॉपी करता है) |
| लाइसेंस | GNU Affero GPL v3.0 |
| लैब | केवल 127.0.0.1 |
http_sd JSON (या लिखने योग्य file_sd) पर नियंत्रण ही काफी है। SD URL ऑपरेटर कॉन्फ़िग है। बचा हुआ हिस्सा यह है कि ग्रुप labels __unix_socket__ सेट कर सकता है और Prometheus उसे Dial करेगा।
| विशेषाधिकार | विधि / सिंक | लैब-प्रमाणित या अनुमानित |
|---|---|---|
| उस होस्ट unix सॉकेट से कनेक्ट करें जिसे Prometheus UID खोल सकता है | __unix_socket__ से clientForTarget -> DialContext(ctx, "unix", socketPath) | लैब-प्रमाणित। http_sd से पथ /sockets/jail/../oracle.sock; स्क्रैप हेल्थ up |
उस पथ में ../ का अनुसरण करें | कोई filepath.Clean नहीं / कोई .. अस्वीकृति नहीं | लैब-प्रमाणित। कर्नेल ने traversal को /sockets/oracle.sock तक हल किया |
| Linux abstract सॉकेट को Dial करें | @name का वही Dial | लैब-प्रमाणित। __unix_socket__=@prom-lab-oracle; स्क्रैप हेल्थ up |
| उस सॉकेट पर Prometheus UID के रूप में HTTP GET करें | स्क्रैप GET है; __metrics_path__ अनुरोध पथ है | लैब-प्रमाणित। GET /fs-traversal और /abstract; User-Agent Prometheus/; lab_witness इनजेस्ट हुआ |
| उन सॉकेट्स तक पहुँचें जिन्हें TCP स्क्रैप नाम नहीं दे सकता | CheckTargetAddress __address__ में / अस्वीकार करता है | लैब-प्रमाणित। __address__ के रूप में unix:///var/run/docker.sock ने is not a valid hostname लॉग किया; सक्रिय टारगेट नहीं; prometheus_target_sync_failed_total=1 |
| यदि वे सॉकेट्स दायरे में हों तो Docker Engine / kubelet HTTP APIs पर GET करें | __unix_socket__=/var/run/docker.sock के साथ एक Docker API पथ | अनुमानित। वही अनसैनिटाइज़्ड Dial। यह लैब वास्तविक engine सॉकेट माउंट नहीं करता। JSON APIs आमतौर पर exposition parse में विफल होते हैं, इसलिए High कनेक्ट/GET है, Docker JSON का TSDB exfil नहीं |
| Docker को बदलें (कंटेनर बनाएँ, लिखें) | स्क्रैप क्रियाएँ | बंद। स्क्रैप केवल GET है |
| अनऑथ Prometheus HTTP पर स्क्रैप जॉब्स जोड़ें | /-/reload, admin API | बंद। दोनों फ्लैग डिफ़ॉल्ट रूप से बंद; reload में कोई बॉडी नहीं |
| इसे डिफ़ॉल्ट उदाहरण कॉन्फ़िग पर उपयोग करें | __unix_socket__ अनसेट; उदाहरण localhost:9090 को TCP पर स्क्रैप करता है | बंद। इन-ट्री k8s/consul/docker SD केवल __meta_* उत्सर्जित करते हैं; relabel के बाद वे प्रीफ़िक्स हटा दिए जाते हैं |
विक्रेता का सुरक्षा मॉडल पहले से ही SD को TCP स्क्रैप टारगेट चुनने देता है। नया प्रिमिटिव होस्ट IPC है जिसे __address__ नाम नहीं दे सकता था।
UDS स्क्रैप के 3.15 FEATURE लाइन के बाद मैंने prometheus/prometheus v3.15.0 पिन किया। इस पिन पर डिफ़ॉल्ट OSS में admin API, lifecycle HTTP, remote-write receiver, और OTLP receiver बंद हैं। PopulateDiscoveredLabels हर http_sd ग्रुप लेबल कॉपी करता है। __unix_socket__ __meta_* नहीं है, इसलिए यह मेटा वाइप से बच जाता है। PopulateLabels केवल __address__ जाँचता है।
func (sp *scrapePool) clientForTarget(t *Target) *http.Client {
socketPath := t.labels.Get(UnixSocketLabel)
if socketPath == "" {
return sp.client
}
client, err := newUnixSocketScrapeClient(socketPath, ...)
func newUnixSocketScrapeClient(socketPath string, ...) (*http.Client, error) {
optFuncs = append([]config_util.HTTPClientOption{config_util.WithDialContextFunc(
func(ctx context.Context, _, _ string) (net.Conn, error) {
return (&net.Dialer{}).DialContext(ctx, "unix", socketPath)
},
)}, optFuncs...)
CheckTargetAddress अभी भी address में / अस्वीकार करता है। URL() __scheme__ / __address__ / __metrics_path__ से scheme/host/path रखता है; सॉकेट केवल dial-only है।
पहले से दर्ज गलत मोड़: इसे इन-मॉडल NONE के रूप में स्कोर करना क्योंकि SD पहले से TCP टारगेट चुनता है (नया प्रिमिटिव होस्ट IPC है); unix:///var/run/docker.sock को __address__ के रूप में छेद मानना (यह अस्वीकृत है); डिफ़ॉल्ट उदाहरण कॉन्फ़िग को यह leftover बताना। नाटक: एक रिवर्स शेल। ओरेकल उन सॉकेट्स पर स्क्रैप हेल्थ up है जिन्हें SD JSON ने नाम दिया।
python3 prometheus-unix-socket-dial-Abraxas-Labs.py
या
cd lab
./run.sh
prom/prometheus:v3.15.0 एक Python साइडकार के साथ netns साझा करता है। साइडकार 127.0.0.1:8080/targets.json पर http_sd और दो unix HTTP ओरेकल परोसता है: फ़ाइलसिस्टम /sockets/oracle.sock और abstract @prom-lab-oracle। Prometheus 127.0.0.1:19390 पर प्रकाशित है। Admin API और lifecycle बंद रहते हैं।
SUCCESS prometheus-unix-socket-dial sd=http_sd fs-traversal=yes abstract=yes tcp-slash-rejected=yes how=sd-labels PROMETHEUS-UNIX-SOCKET-DIAL-WITNESS
IOC: scrapeUrl=http://localhost:1/fs-traversal और /abstract, दोनों हेल्थ up। TCP slash कभी सक्रिय टारगेट नहीं बना।
SD से __unix_socket__ को Dial न करें जब तक कि यह एक सैनिटाइज़्ड निरपेक्ष फ़ाइलसिस्टम पथ न हो। खाली मान, NUL, Linux abstract @ नाम, सापेक्ष पथ, और filepath.Clean के बाद कोई भी .. अस्वीकार करें। scrape YAML से प्रीफ़िक्स की allowlist अधिक मजबूत है। PopulateDiscoveredLabels से लेबल हटाना जब तक कि यह ऑपरेटर कॉन्फ़िग से न आया हो, SD इंजेक्शन को भी बंद कर देता है।
5241a27fe3c6983549fccc32f6e65917408c63cd)scrape/scrape.go · scrape/target.go · config/config.go