GeoServerjsonArrayContains未授权RCE:一个jsonb_path_exists引入的SQL注入0day"

admin 2026-10-18 04:01:59 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

cover_image

GeoServer jsonArrayContains 未授权RCE:一个jsonb\_path\_exists引入的SQL注入0day

零日手记
零日手记

随笔漫记安全路

2026年8月16日 09:35
北京

在小说阅读器读本章

去阅读

8月13日,安全研究员秋风在X上公开了一个GeoServer的0day——通过jsonArrayContains函数未授权SQL注入,数据库高权限下直接RCE。CVSS 9.8,国内暴露资产5320个。官方已合并修复PR但尚未发布修复版本。

GeoServer是什么

GeoServer是OSGeo维护的开源地理空间数据服务器,实现了WMS、WFS、WCS等OGC标准服务。说白了就是个地图服务器,政府、企业、科研机构用得很多。底层依赖GeoTools做JDBC数据访问和CQL/ECQL过滤器到SQL的转换。漏洞就出在这个转换环节。

CVSS 3.1评分9.8。PoC、EXP、技术细节均已公开。暂无CVE编号。


漏洞原理

GeoTools的GEOT-7589给PostgreSQL 12+引入了jsonb\_path\_exists优化。引入前,jsonArrayContains走旧版jsonb @>编码逻辑,对应值会做转义。引入后,第三参数expected直接字符串拼接进SQL,没有转义、没有参数化。

代码层面的sink长这样:

Object value = ((LiteralExpressionImpl) expected).getValue();
return \"(@.%s == \\\"%s\\\")\".formatted(jsonPath[lastIndex], value);

这个value没有经过JSONPath转义,没有经过SQL literal encoder,也没有进入JDBC bind参数,被同时嵌套在JSONPath双引号、SQL单引号和jsonb\_path\_exists()调用中。

正常输入生成:

jsonb_path_exists(\"json_column\"::jsonb, '$ ? (@.key == \"expected\")')

攻击者控制expected,就能依次退出JSONPath字符串、SQL字符串和外层SQL表达式,改变后续SQL语法结构。标准SQL注入。


攻击链路

匿名GetFeature + CQL_FILTER
  → ECQL parser
  → JsonArrayContainsFunction(column, path, expected)
  → JDBCFeatureSource.getCountInternal()
  → FilterToSqlHelper.encodeJsonArrayContains()
  → constructEquality()  [原始拼接sink]
  → Statement.executeQuery(countSql)
  → PostgreSQL

通过WFS GetFeature的CQL\_FILTER参数注入恶意SQL,先能做数据泄露和篡改。数据库连接用户是超级用户或持有pg\_execute\_server\_program权限时,通过PostgreSQL的COPY...TO PROGRAM执行系统命令:

COPY (SELECT 1) TO PROGRAM '<command>'

命令以数据库OS用户身份在/bin/sh中执行,可以反弹shell、写webshell、横向移动。

注入需要穿越三层结构:JSONPath双引号 → SQL单引号 → jsonb\_path\_exists外层表达式。闭合后用分号开始新语句,用SQL注释吞掉尾部。注意WFS和WMS查询形状不同,payload不能互换。


利用条件

不是随便一个GeoServer就能RCE,需要同时满足:

  1. WFS服务未要求认证
  2. 后端使用PostgreSQL/PostGIS数据存储
  3. 存在能被当作JSON解析的属性
  4. PostgreSQL >= 12(12以下不走新分支)
  5. 实现RCE需数据库角色是superuser或有pg\_execute\_server\_program权限

没有PostgreSQL/PostGIS数据存储时根本不进入这个sink。普通权限角色只能SQL注入读写数据,不能执行命令。

容易被忽略的一点:GeoTools的preparedStatements=true和pgJDBC的preferQueryMode=extended都不能作为缓解措施。pgJDBC 42.7.11默认就是extended,但驱动仍会拆分复合查询依次执行。preparedStatements复用同一个FilterToSqlHelper,raw concat sink依然存在。


影响范围

受影响版本:

  • GeoServer 2.24.5 ~ 3.0.0(GeoTools 30.5 ~ 35.0),由GEOT-7589(2024年6月引入)回归
  • 已确认:GeoServer 2.26.0(GeoTools 32.0)
  • GeoTools 30.4/31.2及以下不含新分支,不受影响

资产暴露情况:

  • 国内5320个,关联IP 353个
  • 全球34038个,关联IP 1515个

PoC状态

GitHub已有完整研究仓库(mhtsec/GeoServer-jsonArrayContains-PG-RCE),含exploit.py、隔离复现环境、原理文档。还有社区补丁(ubitquity/UBITQUITY-GeoServer-Security-Patch)通过escapeLiteral()做转义缓解。

PoC使用:

# 基线检查
python3 exploit.py --url http://127.0.0.1:8085/geoserver --auto --check

# 离线预览(不发请求)
python3 exploit.py --url http://127.0.0.1:8085/geoserver \\
  --workspace jac_sqli --layer poi_info --column mp \\
  --cmd \"id > /tmp/marker.txt\"

# 实际执行(仅限授权环境)
python3 exploit.py --url http://127.0.0.1:8085/geoserver \\
  --auto --cmd \"id > /tmp/marker.txt\" --execute

利用是盲的——HTTP响应不返回命令输出。Multiple ResultSets只代表堆叠语句信号,不能证明命令执行成功,必须在数据库端核对marker文件和statement log。


修复建议

官方已合并修复PR(GeoTools #5829,GEOT-7958),对expected参数调用escapeJsonLiteral()转义。但截至发稿修复版本尚未发布,临时缓解:

  1. 限制或关闭WFS对外暴露,或强制认证
  2. 数据库连接用最小权限用户,撤销superuser和pg\_execute\_server\_program
  3. WAF拦截CQL\_FILTER中的jsonArrayContains、COPY、PROGRAM、pg\_sleep、pg\_read\_file等关键字
  4. 数据库置独立非特权环境,不挂载宿主敏感目录

根治必须消除expected参数的原始拼接,用jsonb\_path\_exists变量对象承载比较值,通过JDBC bind传入。黑名单和WAF关键字过滤不够可靠。


参考资料

[1] 原始披露 - https://x.com/q1uf3ng/status/2087490992723407096[1]

[2] PoC仓库 - https://github.com/mhtsec/GeoServer-jsonArrayContains-PG-RCE[2]

[3] 社区补丁 - https://github.com/ubitquity/UBITQUITY-GeoServer-Security-Patch[3]

[4] GeoTools修复PR #5829(GEOT-7958)- https://github.com/geotools/geotools/pull/5829[4]

[5] GeoTools GEOT-7589(漏洞引入)- https://github.com/geotools/geotools/pull/4805[5]

引用链接

[1]https://x.com/q1uf3ng/status/2087490992723407096

[2]https://github.com/mhtsec/GeoServer-jsonArrayContains-PG-RCE

[3]https://github.com/ubitquity/UBITQUITY-GeoServer-Security-Patch

[4]https://github.com/geotools/geotools/pull/5829

[5]https://github.com/geotools/geotools/pull/4805


GeoServerjsonArrayContains未授权RCE:一个jsonb_path_exists引入的SQL注入0day" 网络安全文章

GeoServerjsonArrayContains未授权RCE:一个jsonb_path_exists引入的SQL注入0day"

GeoServer存在一个由GeoTools引入的jsonArrayContains未授权SQL注入0day漏洞(CVSS9.8),攻击者可通过WFSGetFeature的CQL\\_FILTER参数注入恶意SQL,在数据库高权限下利用PostgreSQL的COPY…TOPROGRAM实现远程代码执行。国内暴露资产约5320个,官方已合并修复PR但未发布版本。建议立即限制WFS暴露、使用最小权限数据库用户并部署WAF拦截相关关键字。
PostgreSQL一次性修了20多个CVE:to_char堆溢出可RCE,14-18全系列中招" 网络安全文章

PostgreSQL一次性修了20多个CVE:to_char堆溢出可RCE,14-18全系列中招"

PostgreSQL于8月13日发布安全更新,修复20多个CVE,其中5个堆溢出漏洞可导致RCE。最值得关注的是CVE-2026-14669,to_char函数处理时区字符串时存在堆溢出,影响14至18全系列版本。其他关键漏洞涉及pg_dump、pg_stat_statements等组件。建议立即升级到最新小版本,并单独升级pg\\_dump工具,多租户环境需限制时区设置,同时关注衍生项目的补丁发布。
云原生未授权系列之etcd未授权:从读到Secret到接管集群" 网络安全文章

云原生未授权系列之etcd未授权:从读到Secret到接管集群"

本文分析了etcd未授权访问漏洞在Kubernetes集群中的危害与利用条件。etcd作为集群状态存储核心,若因运维错误关闭客户端证书认证并暴露2379端口,攻击者无需凭证即可读取全部Secret,包括高权限ServiceAccount的JWTToken。利用该Token可访问kube-apiserver创建特权Pod逃逸至宿主机,最终读取admin.conf接管集群。默认配置安全,漏洞源于错误配置叠加,纵深防御可阻断攻击链。
天狐工具箱框架V4.0-轻便版-二改介绍" 网络安全文章

天狐工具箱框架V4.0-轻便版-二改介绍"

本文介绍基于天狐渗透工具箱二次改造的轻便版框架。核心改动聚焦界面与交互优化,涵盖卡片缩放、双击启动、参数前后置分离及命令预览。同时增强拼音与模糊搜索排序,启动速度提升至一秒内。该框架不含运行环境,需自备依赖,适合需定制化管理的安全人员参考使用。
评论:0   参与:  0