
Co znajdziesz w tym artykule?
- 1 TL;DR
- 2 Krótka definicja techniczna (1 akapit)
- 3 Gdzie występuje / przykłady platform (Windows, AD, AWS, Azure, GCP, K8s, ESXi, M365)
- 4 Szczegółowy opis techniki (jak działa, cele, dlaczego jest skuteczna)
- 5 Artefakty i logi (tabela — EID, CloudTrail events, K8s audit, M365 operations)
- 6 Detekcja (praktyczne reguły)
- 7 Heurystyki / korelacje (co łączyć)
- 8 False positives / tuning
- 9 Playbook reagowania
- 10 Przykłady z kampanii / case studies
- 11 Lab (bezpieczne testy) — przykładowe komendy
- 12 Mapowania (Mitigations, Powiązane techniki)
- 13 Źródła / dalsza literatura
- 14 Checklisty dla SOC / CISO
TL;DR
CVE-2025-14847 to podatność w MongoDB Server związana z obsługą zlib w kompresji sieciowej protokołu MongoDB: niespójne pola długości w nagłówkach skompresowanych wiadomości mogą doprowadzić do zwrócenia fragmentów niezainicjalizowanej pamięci heap do klienta bez uwierzytelnienia.
Dla SOC oznacza to: jeśli instancja MongoDB jest wystawiona na Internet, atakujący może „wyciągać” z odpowiedzi wrażliwe fragmenty pamięci procesu (potencjalnie dane aplikacyjne/sekrety zależnie od tego, co akurat było w RAM). Priorytet: patch do wersji naprawionych lub czasowo usuń zlib z kompresorów.
Krótka definicja techniczna (1 akapit)
CVE-2025-14847 to błąd klasy CWE-130 polegający na niewłaściwej obsłudze niespójnych parametrów długości w zlib-compressed protocol headers MongoDB, co umożliwia zdalnemu, nieautoryzowanemu klientowi odczyt niezainicjalizowanej pamięci heap poprzez odpowiedzi serwera.
Gdzie występuje / przykłady platform (Windows, AD, AWS, Azure, GCP, K8s, ESXi, M365)
Windows (self-hosted):
mongod.exe/mongos.exeuruchomione jako usługa (często port 27017) — ryzyko rośnie, gdy bind/listen jest „na świat” i gdyzlibpozostaje włączony (domyślnie jest).
AD (Active Directory):
- Bezpośrednio „nie dotyczy” (to nie jest podatność AD), ale realnie MongoDB bywa konsumowane przez aplikacje domenowe; wyciek pamięci może pośrednio ujawnić np. tokeny/sekrety aplikacyjne trzymane w RAM.
AWS (EC2 / EKS / self-managed):
- EC2 z Security Group otwierającą 27017/27018 do 0.0.0.0/0 → klasyczny scenariusz T1190.
- EKS: MongoDB jako StatefulSet; ekspozycja przez
Service type=LoadBalancer/Ingress/NodePort zwiększa ryzyko.
Azure (VM / AKS):
- VM z publicznym IP + NSG pozwalający na 27017; AKS analogicznie jak EKS.
GCP (Compute Engine / GKE):
- Publiczny endpoint + reguły FW do 27017; w GKE ekspozycja przez Service LB.
Kubernetes (K8s):
- Szczególnie ryzykowne: publiczny LoadBalancer dla MongoDB lub brak NetworkPolicy dla namespace z bazą.
ESXi:
- Pośrednio: gdy MongoDB stoi na VM — liczą się zasady ekspozycji/segmentacji sieci, snapshoty do IR itp.
M365:
- Zwykle „nie dotyczy” (chyba że logi/alerty spływają do Sentinel/MDE; sama podatność jest po stronie serwera MongoDB).
Ważne operacyjnie: MongoDB informował, że Atlas fleet został spatchowany i „nie ma dowodów” na wykorzystanie ani kompromitację danych klientów; dotyczy to jednak usług zarządzanych — self-hosted musi być zaktualizowany osobno.
Szczegółowy opis techniki (jak działa, cele, dlaczego jest skuteczna)
Negocjacja kompresji i dlaczego zlib ma znaczenie
MongoDB wspiera kompresję ruchu między klientem a serwerem (OP_COMPRESSED). Domyślnie zarówno mongod, jak i mongos mają ustawione kompresory sieciowe na snappy,zstd,zlib (w tej kolejności).
CVE-2025-14847 dotyczy ścieżki obsługi zlib: spreparowane (niepoprawne) nagłówki skompresowanych wiadomości z niespójnymi długościami mogą doprowadzić do sytuacji, w której serwer zwraca w odpowiedzi fragmenty niezainicjalizowanej pamięci heap.
Co realnie wycieka z heap i jak to eskaluje ryzyko
Ponieważ mowa o pamięci procesu, w praktyce „to, co wycieknie”, zależy od:
- obciążenia bazy (zapytania/odpowiedzi, BSON, bufory),
- bibliotek i alokacji w danym buildzie,
- tego, co aplikacje trzymają w pamięci (np. fragmenty dokumentów, metadane sesji, czasem sekrety).
Oficjalny wektor CVSS od CNA wskazuje wysoki wpływ na poufność i brak wpływu na integralność/dostępność (C:H / I:N / A:N).
Dlaczego to pasuje do ATT&CK T1190
Jeżeli MongoDB jest publicznie wystawione (Internet-facing), to atakujący wykorzystuje błąd w usłudze nasłuchującej na gnieździe TCP — to klasyczny model Exploit Public-Facing Application (T1190) w taktyce Initial Access (nawet jeśli „efektem” jest wyciek informacji, a nie RCE).
Artefakty i logi (tabela — EID, CloudTrail events, K8s audit, M365 operations)
| Obszar obserwacji | Windows EID (przykłady) | CloudTrail (AWS) | K8s Audit | M365 operations | Co zbierać / na co patrzeć |
|---|---|---|---|---|---|
| Ekspozycja portu MongoDB (27017/27018) | Sysmon EID 3 (NetworkConnect), Windows Filtering Platform 5156 | AuthorizeSecurityGroupIngress, ModifySecurityGroupRules, RevokeSecurityGroupIngress | patch/create Service (LoadBalancer/NodePort), Ingress, NetworkPolicy | N/A | Skoki nowych źródeł łączących się do 27017; ruch z Internetu do DB zamiast z warstwy app |
| Start procesu MongoDB i parametry ryzyka | Sysmon EID 1 (ProcessCreate), Security 4688 | N/A | create/patch Deployment/StatefulSet (args/env/config) | N/A | Czy mongod/mongos startuje z --bind_ip_all / 0.0.0.0 oraz czy wymuszasz wyłączenie zlib |
| Zmiany konfiguracji kompresji | EID 1/4688 + (opcjonalnie) audyt plików mongod.conf | N/A | zmiany ConfigMap/Secret montowanych do poda | N/A | Czy net.compression.compressors nadal zawiera zlib (domyślnie zawiera) |
| „Skany” i bursty połączeń do MongoDB | Sysmon EID 3 + firewall | (opcjonalnie) GuardDuty/VPC Flow Logs poza CloudTrail | N/A | N/A | Wysoka liczba krótkich połączeń, nietypowe geolokacje/ASN, brak auth events (bo pre-auth) |
| Działania IR/patch | EID 1/4688 (restart usługi), systemd logs | StartInstances/StopInstances (jeśli robisz) | rollout restart, delete pod | N/A | Okno zmian + walidacja, że wersja/kompresja jest zgodna z polityką |
Detekcja (praktyczne reguły)
Sigma (gotowa reguła)
Cel: wykryć hosty, na których MongoDB jest uruchamiane w sposób zwiększający ekspozycję na CVE-2025-14847 (publiczny bind i/lub jawnie włączone
zlib).
Uwaga: to jest detekcja „posture / hardening”, nie sygnatura exploit payload.
title: MongoDB Server Risky Startup Options (CVE-2025-14847 / zlib / public bind)
id: 3f7f2c2e-5b5c-4a6c-9b5e-6b7f9e3a8a21
status: experimental
description: >
Detects mongod/mongos started with zlib network compression enabled and/or bound to all interfaces,
increasing exposure to CVE-2025-14847 (unauth heap memory read via zlib compressed protocol).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-14847
- https://jira.mongodb.org/browse/SERVER-115508
- https://www.mongodb.com/docs/manual/reference/configuration-options/
author: Badacz CVE
date: 2025/12/25
tags:
- attack.initial_access
- attack.t1190
logsource:
category: process_creation
product: windows
detection:
selection_image:
Image|endswith:
- '\mongod.exe'
- '\mongos.exe'
selection_public_bind:
CommandLine|contains:
- '--bind_ip_all'
- '--bind_ip 0.0.0.0'
- 'bindIpAll'
- 'bindIp: 0.0.0.0'
selection_zlib_cli:
CommandLine|contains|all:
- 'networkMessageCompressors'
- 'zlib'
selection_zlib_cfg_hint:
CommandLine|contains|all:
- 'net.compression.compressors'
- 'zlib'
condition: selection_image and (selection_public_bind or selection_zlib_cli or selection_zlib_cfg_hint)
fields:
- Image
- CommandLine
falsepositives:
- MongoDB za reverse-proxy / w prywatnej sieci, gdzie bind na 0.0.0.0 jest akceptowalny
- Środowiska, gdzie zlib jest wymagany (wydajność/kompatybilność), ale port nie jest publiczny
level: medium
Dlaczego to ma sens: zlib jest domyślnie włączony w mongod/mongos (snappy,zstd,zlib), więc realna mitigacja często polega na jego usunięciu/wyłączeniu.
Splunk (SPL)
A) Wykrywanie nieautoryzowanych źródeł łączących się do MongoDB (logi MongoDB):
index=mongodb sourcetype=mongodb:log ("connection accepted" OR "Connection accepted")
| rex field=_raw "from (?<src_ip>\d{1,3}(\.\d{1,3}){3}):(?<src_port>\d+)"
| stats count as connections dc(src_port) as uniq_src_ports by src_ip
| sort - connections
B) Bursty krótkich połączeń (sygnał skanowania / prób exploitacji pre-auth):
index=mongodb sourcetype=mongodb:log ("connection accepted" OR "end connection")
| rex field=_raw "connection accepted from (?<src_ip>\d{1,3}(\.\d{1,3}){3})"
| timechart span=5m count by src_ip limit=20
C) (Jeśli masz VPC/NSG/Firewall w Splunku) — inbound na 27017 z Internetu:
index=netflow (dest_port=27017 OR dest_port=27018) action=allowed
| stats sum(bytes) as bytes count as flows by src_ip dest_ip dest_port
| sort - flows
KQL (Azure / Microsoft Sentinel)
A) Azure Firewall (NetworkRule) — ruch do 27017/27018:
AzureDiagnostics
| where Category == "AzureFirewallNetworkRule"
| where msg_s has "Dport: 27017" or msg_s has "Dport: 27018"
| summarize flows=count() by SourceIP=src_ip_s, DestinationIP=dst_ip_s, bin(TimeGenerated, 5m)
| order by flows desc
B) Wykrywanie publicznej ekspozycji przez zmiany NSG (Activity Log):
AzureActivity
| where OperationNameValue has_any ("MICROSOFT.NETWORK/NETWORKSECURITYGROUPS/SECURITYRULES/WRITE",
"MICROSOFT.NETWORK/NETWORKSECURITYGROUPS/WRITE")
| where ActivityStatusValue == "Succeeded"
| where Properties has "27017" or Properties has "27018"
| project TimeGenerated, Caller, OperationNameValue, ResourceGroup, Resource, Properties
| order by TimeGenerated desc
CloudTrail query (AWS CLI/CloudWatch)
A) CloudTrail Lake (SQL) — kto otworzył MongoDB na świat:
SELECT eventTime, userIdentity.arn, sourceIPAddress, eventName, requestParameters
FROM <your_cloudtrail_lake_table>
WHERE eventName IN ('AuthorizeSecurityGroupIngress','ModifySecurityGroupRules','RevokeSecurityGroupIngress')
AND requestParameters LIKE '%27017%'
ORDER BY eventTime DESC;
B) AWS CLI (lookup-events) + filtr portów (przykład z jq):
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=AuthorizeSecurityGroupIngress \
--start-time 2025-12-01T00:00:00Z \
--end-time 2025-12-25T23:59:59Z \
--max-results 50 \
| jq -r '.Events[]
| select(.CloudTrailEvent | test("27017|27018"))
| [.EventTime, .Username, .EventName] | @tsv'
Elastic (EQL) przykłady
A) Inbound connections do MongoDB z adresów publicznych (Elastic Defend / endpoint network events):
network
where event.type == "start"
and destination.port in (27017, 27018)
and network.direction == "inbound"
and not cidrMatch(source.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
B) Start mongod/mongos z parametrami wysokiego ryzyka:
process
where event.type == "start"
and process.name in ("mongod", "mongos", "mongod.exe", "mongos.exe")
and (
process.command_line like "*bind_ip_all*" or
process.command_line like "*bind_ip 0.0.0.0*" or
process.command_line like "*networkMessageCompressors*" and process.command_line like "*zlib*"
)
Heurystyki / korelacje (co łączyć)
- Asset + posture: lista instancji MongoDB + wersja + czy port publiczny + czy
zlibwyłączony.zlibjest domyślnie włączony → jeśli nie zrobiłeś hardeningu, traktuj jak „włączone”.
- Netflow/VPC Flow Logs/NSG Flow Logs: wzrost liczby połączeń do 27017 z nietypowych ASN/geo + krótkie sesje.
- MongoDB logs: dużo
connection acceptedbez towarzyszących zdarzeń auth/audit (pre-auth). - Change management: korelacja w czasie z rolloutem poprawek (upgrade/konfig) i spadkiem prób połączeń.
False positives / tuning
Typowe FP:
- skanowanie wewnętrzne (CMDB, monitoring, VA tools),
- load balancer / NAT pokazuje jeden adres źródłowy,
- legalne aplikacje o wysokiej częstotliwości połączeń.
Tuning:
- allowlist znanych CIDR aplikacji/ETL/backup,
- alertuj tylko dla źródeł spoza prywatnych zakresów,
- progi: np.
>Nnowych IP w 10 minut lub>Xpołączeń/IP/5 min.
Playbook reagowania
- Triage ekspozycji
- Sprawdź, czy MongoDB jest Internet-facing (SG/NSG/Firewall/Ingress).
- Jeśli tak: priorytet P1 (T1190).
- Weryfikacja wersji
- Na hoście:
mongod --version mongos --version - Porównaj z wersjami naprawionymi: 8.2.3 / 8.0.17 / 7.0.28 / 6.0.27 / 5.0.32 / 4.4.30.
- Na hoście:
- Natychmiastowa mitigacja (jeśli nie możesz patchować „teraz”)
- Wyłącz
zlibw kompresji sieciowej, ustawiając kompresory nasnappy,zstdalbodisabled. - Przykład (wariant uruchomieniowy):
mongod --networkMessageCompressors snappy,zstd # albo całkowicie: mongod --networkMessageCompressors disabled
- Wyłącz
- Remediacja docelowa
- Upgrade do wersji naprawionej (jw.).
- Hunting / impact assessment
- Przejrzyj logi połączeń do 27017 (źródła, wolumeny, okna czasowe).
- Jeśli DB była publiczna: potraktuj to jak incydent „potential data exposure”.
- Rotacja sekretów (jeśli ekspozycja była realna)
- Rotuj hasła użytkowników DB, klucze aplikacyjne, tokeny (w zależności od tego, co mogło znaleźć się w pamięci procesu).
- Wymuś TLS + auth + segmentację sieci (minimalny blast radius).
Przykłady z kampanii / case studies
- Brak publicznie potwierdzonych kampanii APT/ransomware wykorzystujących CVE-2025-14847 „w dziczy” na moment publikacji źródeł; MongoDB wskazywał, że w Atlas „nie ma dowodów” na wykorzystanie ani kompromitację danych i że flota została spatchowana.
- Ten CVE jest jednak modelowym przykładem ryzyka T1190 dla baz danych (public-facing socket + bug w parserze/protokole).
Lab (bezpieczne testy) — przykładowe komendy
- Sprawdź, czy serwer nadal pozwala na
zlib- Ponieważ pole
hello.compressionpojawia się tylko, gdy kompresja jest używana, wymuś po stronie klientazlibi zobacz, czy serwer je negocjuje. - Przykład:
mongosh "mongodb://<host>:27017/?compressors=zlib" --eval 'db.hello()' - Jeśli w wyniku pojawia się
"compression": ["zlib"], tozlibjest aktywnie używane (czyli mitigacja nie została wdrożona).
- Ponieważ pole
- Weryfikacja domyślnej listy kompresorów (dla wiedzy operacyjnej)
- MongoDB domyślnie:
snappy,zstd,zlib.
- MongoDB domyślnie:
- Weryfikacja ustawień w pliku konfiguracyjnym
sudo grep -n "compression" -n /etc/mongod.conf sudo grep -n "bindIp" -n /etc/mongod.conf - K8s: sprawdź argumenty/ConfigMap
kubectl -n <ns> get sts <mongo-sts> -o yaml | grep -n "networkMessageCompressors" -n kubectl -n <ns> get cm -o yaml | grep -n "net.compression" -n
Mapowania (Mitigations, Powiązane techniki)
ATT&CK (główne):
- T1190 Exploit Public-Facing Application → TA0001 Initial Access
Dlaczego nie „RCE” w mapowaniu?
Opis CNA/NVD mówi o odczycie niezainicjalizowanej pamięci (information disclosure), a wektor CVSS v3.1 ma I:N/A:N — to nie jest opis skutku typu „arbitrary code execution”.
Mitigations (praktycznie):
- Patch management / szybka aktualizacja wersji naprawionych
- Ograniczenie ekspozycji (SG/NSG/Firewall/NetworkPolicy), zasada „DB nie jest publiczna”
- Wyłączenie
zlib(czasowo lub polityką) —snappy,zstdalbodisabled
Powiązane techniki (łańcuchowo, zależnie od tego co wycieknie):
- Potencjalnie: nadużycie ujawnionych sekretów → Valid Accounts (T1078) (jeśli wyciek umożliwi logowanie innymi kanałami).
(To zależne od środowiska; sam CVE nie gwarantuje przejęcia kont.)
Źródła / dalsza literatura
- NVD: opis, CVSS, wersje podatne, CWE-130 (NVD)
- MongoDB JIRA SERVER-115508: fix/upgrade + workaround (wyłączenie zlib) (MongoDB Jira)
- MongoDB Alerts (CVE-2025-14847): oficjalny wpis „Zlib … may allow memory read” + zakresy wersji (MongoDB)
- MongoDB Docs: domyślne
snappy,zstd,zlib(mongod/mongos) (MongoDB) - MongoDB Docs:
hello.compression(walidacja negocjacji kompresji) (MongoDB) - MITRE ATT&CK: T1190 (tactic Initial Access, last modified) (MITRE ATT&CK)
- MongoDB Community Hub: komunikat o spatchowaniu Atlas + brak dowodów exploitacji (wg MongoDB) (MongoDB)
Checklisty dla SOC / CISO
SOC (operacyjnie, dziś):
- Zidentyfikuj wszystkie
mongod/mongosi ich wersje. - Sprawdź ekspozycję 27017/27018 (Internet-facing = P1).
- Jeśli nie możesz patchować natychmiast: usuń
zlibz kompresorów (snappy,zstdlubdisabled). - Wdróż detekcje: bursty połączeń, nowe źródła, zmiany SG/NSG.
- Jeśli DB była publiczna: threat hunting + ocena ryzyka wycieku danych.
CISO / Risk:
- Wymuś politykę: „bazy danych nie mają publicznych endpointów”.
- SLA na patchowanie krytycznych/High dla usług publicznych.
- Segmentacja sieci + Zero Trust dla dostępu do DB.
- Standard hardening MongoDB: auth/TLS, ograniczenia kompresji, monitoring i centralne logowanie.