LoRexxar's Blog | 信息技术分享

LoRexxar's Blog

马上订阅 LoRexxar's Blog | 信息技术分享 RSS 更新: https://lorexxar.cn/atom.xml

Joern In RealWorld (3) - 致远OA A8 SSRF2RCE

2023年11月21日 17:09

致远OA是国内最有名的OA系统之一,这个OA封闭商业售卖再加上纷繁复杂的版本号加持下,致远OA拥有大量无法准确判断的版本。

这篇文章的漏洞源于下面这篇文章,文章中提到该漏洞影响A8, A8+, A6等多个版本,但很多版本我都找不到对应的源码,光A8就有一万个版本,下面我们尽可能的复现漏洞和探索Joern的可能性

漏洞原理

先花一点儿篇幅简单的描述一下漏洞的基础原理,其实漏洞分为好几个部分

  • 致远oa 前台XXE漏洞
  • 致远oa S1服务 后台jdbc注入
  • H2 jdbc注入导致RCE
  • 致远oa S1服务 后台用户密码重置导致的鉴权绕过

我们分开讨论这部分

致远oa前台xxe漏洞

首先我必须得说,这部分内容涉及到的代码我找了很多个版本的源码都没有找到,尝试搜索了一下原漏洞以及一些简单的分析文章其实大部分都没有提到这部分代码的来源。

我觉得最神奇的点在于,这个漏洞如果仅按照原文提及的部分,漏洞原理及其简单,而且是一个比较标准的xxe漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private List<Element> getNodes(String xmlString, String xpath) {
ArrayList tmpList = null;

try {
SAXReader saxReader = new SAXReader();
Reader xml_sr = new StringReader(xmlString);
saxReader.setEncoding("UTF-8");
Document document = saxReader.read(xml_sr);
if (document.getRootElement() == null) {
throw new KgException(new KgCommonsError("XmlParser Object hasn't RootElement.", KgCommonsError.SYSTEM_ERROR.getCode()));
} else {
List<?> contexts = document.selectNodes(xpath);
tmpList = new ArrayList();

for(int i = 0; i < contexts.size(); ++i) {
if (contexts.get(i) instanceof Element) {
tmpList.add((Element)contexts.get(i));
}
}

return tmpList;
}
}

可控参数 xmlValue,直接解base64然后就进xxe造成漏洞。

按理说这么简单的漏洞,应该早就被爆出来滥用了,但我搜索了一下相应的内容,上一次致远oa爆出来xxe漏洞原理比这个复杂多了,而且还是组件漏洞。

由于实在找不到源码,所以我猜测这个漏洞可能有两个可能性

  • 漏洞来自于某个部署时使用到的额外服务或者插件
  • 这个xxe漏洞是个第三方组件问题,需要其他条件入口,原文不想提到这个入口所以没有写

不管咋说我的确是没有办法获得答案了,不过这不是这篇文章的重心,先往后看。

致远oa S1服务 后台jdbc注入

在原文中,这部分来自于agent.jar,简单来说就是一个开放到内网的服务,我查了一下应该是指这套S1服务

在官网还可以查到这套系统,看上去应该是用于管理致远后台的平台,算是运维平台。这侧面也证明了这套系统是一套独立的系统。

com.seeyon.agent.sfu.server.apps.configuration.controller.ConfigurationController可以找到对应的testDBConnect方法

img

可以关注到相比原文当中的截图,现在加入了对h2数据库连接的限制

1
2
3
params.put("dbUrl", dbUrl);
if (dbUrl.startsWith("jdbc:h2"))
return JsonResult.success(StatusCodeEnum.FAILEDCODE.getKey(), ", null);

继续跟进到testDBConnect

img

从这里可以找到可以根据dburl前缀自由连接远程jdbc的方法,并允许自定义链接驱动类

H2 jdbc注入导致RCE

这部分内容其实不算是这篇文章的重点致远oa的问题,一般来说到jdbc注入之后就是利用方式的问题了,但这里还是顺带提一下。

关于jdbc的注入后利用方式其实之前已经有过不少次相关的文章以及议题,下面这篇就是一篇总结的比较全的文章

其实jdbc可控后续导致的二次利用方案相当复杂,由于这不是这篇文章的内容,所以我们直接跳到对应的位置来看看。

想要利用jdbc注入来调用H2进行进一步利用,其中有两个比较大的问题。

  • 需要相应的配置参数才能命令执行
  • 由于不支持多行语句,需要找到能在单行里执行命令的方法

H2的攻击利用的是Spring Boot H2 console的一个特性,通过控制h2数据库的连接url,我们可以迫使spring boot去...

剩余内容已隐藏

查看完整文章以阅读更多