
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żeli 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.exe uruchomione jako usługa (często port 27017) — ryzyko rośnie, gdy bind/listen jest „na świat” i gdy zlib pozostaje 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 iż logi/alerty spływają do Sentinel/MDE; sama podatność jest po stronie serwera MongoDB).
Ważne operacyjnie: MongoDB informował, iż 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żeli „efektem” jest wyciek informacji, a nie RCE).
Artefakty i logi (tabela — EID, CloudTrail events, K8s audit, M365 operations)
| 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 przez cały czas 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, iż 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.
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 - connectionsB) 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=20C) (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 - flowsKQL (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 descB) 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 descCloudTrail 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 zlib wyłączony.
- zlib jest domyślnie włączony → jeżeli 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 accepted bez 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. >N nowych IP w 10 minut lub >X połą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.
- Natychmiastowa mitigacja (jeśli nie możesz patchować „teraz”)
- Wyłącz zlib w kompresji sieciowej, ustawiając kompresory na snappy,zstd albo disabled.
- Przykład (wariant uruchomieniowy):mongod --networkMessageCompressors snappy,zstd # albo całkowicie: mongod --networkMessageCompressors disabled
- 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ł, iż w Atlas „nie ma dowodów” na wykorzystanie ani kompromitację danych i iż 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 przez cały czas pozwala na zlib
- Ponieważ pole hello.compression pojawia się tylko, gdy kompresja jest używana, wymuś po stronie klienta zlib i zobacz, czy serwer je negocjuje.
- Przykład:mongosh "mongodb://<host>:27017/?compressors=zlib" --eval 'db.hello()'
- Jeśli w wyniku pojawia się "compression": ["zlib"], to zlib jest aktywnie używane (czyli mitigacja nie została wdrożona).
- Weryfikacja domyślnej listy kompresorów (dla wiedzy operacyjnej)
- MongoDB domyślnie: snappy,zstd,zlib.
- Weryfikacja ustawień w pliku konfiguracyjnymsudo grep -n "compression" -n /etc/mongod.conf sudo grep -n "bindIp" -n /etc/mongod.conf
- K8s: sprawdź argumenty/ConfigMapkubectl -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,zstd albo disabled
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/mongos i ich wersje.
- Sprawdź ekspozycję 27017/27018 (Internet-facing = P1).
- Jeśli nie możesz patchować natychmiast: usuń zlib z kompresorów (snappy,zstd lub disabled).
- 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.




