从DSFA框架应用测试看漏洞的深入利用

、前言

作为乙方安全公司的一名安全测试人员不仅仅要学会现有测试工具方法的使用安全问题的基础知识以外,还应懂得对发现的问题进行进一步的挖掘,结合项目过程中的实际情况,研究发现新方法、新思路,以期展现某个问题延伸出来的新安全问题。

本文将以DSFA框架为例引导读者从发现一个漏洞开始逐步去发现更多的安全问题,尽可能扩大自己的工作成果为客户的业务把好安全关

什么是DSFA框架

DSFA框架并不是一个正式的名称,在我们曾经测试过的项目中,我们发现某项目团队以此作为核心框架的工程名,因此得名。

DSFA是一个伸缩性较强、易于配置的工作流处理框架。通常,基于工作流的框架通常应用在各种内部业务系统中,承担业务流程处理的相关工作。对于DSFA来说,它是应用开发商设计用于其所开发系统中业务流程处理的通用框架,它定义了15种业务行为,包括文件读写、数据库查询、循环、选择Java模块调用等方面,已经基本覆盖了大部分的业务行为。因此具有一定的普适性,这也是我们为大家介绍的原因。由于该框架并不是开源分发的,所以我们只能通过反编译其核心库文件来了解框架的大概工作原理:

 

从上面的示意图可以看出,用户传入的请求被名为DoPostServlet接收后,会提取请求中的业务流程描述文件及参数,然后传递给业务流程解析器来处理对应的业务流程

 

2.1 请求格式

首先来看看DoPost这个Servlet的实现代码:

 

可以看到第47行首先对请求中的数据块进行了Base64解码操作然后使用XML解析器获取Request节点作为73RequestObject的参数,传入业务流程解析器。根据分析,用户提交的请求必需符合XML格式规范,根节点为Request或者RequestGroup(可包含多个Request),Request节点需要包含如下子节点或属性:

名称

类型

数据类型

action

属性

字符串型,指向业务流程定义文件

request

属性

请求数据的格式,分为JSONXML两种格式

response

属性

响应数据的格式,分为JSONXMLFORMAT三种格式

Data

子节点

根据request的定义来定,通常使用JSON格式

假设服务器端存在user/getUserInfo.xml这个业务流定义用于获取指定用户(通过uid的个人信息则我们可以构造出如下示例请求

<Request action=”user/getUserInfo.xml” request=”JSON” response=”JSON”>

<Data>{“uid”:1}</Data>

</Request>

经过Base64编码后就可以通过DoPost请求来发送给服务器了

 

2.2 业务流程定义

当请求格式被正确解析后,请求被分为业务流程定义和请求参数两部分传给业务流程解析器,加载业务流程:

 

然后,就是从START(代码中对应StartAction)行为(Action)开始执行按流程描述文件执行业务流程:

 

我们找到的一个定义好的业务流程文件展示了基本的数据库查询业务流程就是这样的:

 

每个业务流程都有一个类型为STARTEND的行为,类型为START的行为标志着一个流程的开始,开发者可以在这里连接数据库,类型为END的行为标志着一个流程的结束,每个动作可以通过特定的标识符来接收客户端或上一个行为传入的参数(在请求参数名前添加@修饰符),供当前行为使用。

DSFA框架为开发者定义了各种常见的行为,在应用开发过程中,可以通过组合这些行为模块,实现自己的业务处理过程。主要的行为定义如下

行为名

功能

START

开始

END

结束

FILE_READ

读取文件

FILE_SAVE

保存文件

SERVER_OBJECT

会话、应用参数设置

SQL_QUERY

执行SQL语句,获取查询到的数据

SQL_EXECUTE

执行SQL语句

JAVA_METHOD

通过反射执行java方法

下面的实例演示了调用数据库查询获得某个组中用户列表的业务流程定义:

 

针对上面的业务流程,我们可以构造如下请求数据:

<Request action=”user/getUsers.xml” request=”JSON” response=”JSON”>

<Data>{“gid”:1}</Data>

</Request>

注:user/getUsers.xml就是上图中的业务流程文件。

 

DSFA框架漏洞利用

上面讲解了DSFA框架的基本原理下面我们从渗透测试的角度来考虑如何渗透一个业务系统如前面所述,DSFA框架最常用的业务场景为内部业务系统,内部业务系统通常仅对外开放一个登录入口,除非你有可用的用户名密码,否则较难了解应用的细节;如果目标不存在任何常见应用的特征,你可能会一筹莫展。

这个时候,有经验的测试人员可能会说,为什么不用爬虫爬一下应用的页面呢,页面中可能会包含敏感信息哟!如果你这么做了,在DSFA框架下你将会收获一份惊喜!

3.1 牛刀小试

DSFA框架在初始化的时候会从服务端拉取一个配置文件通过代理工具我们可以捕获这个配置文件的内容

 

此时可以看到上图中请求的数据部分为编码的字符串使用base64解码后结果如下

 

从这里可以看到,DSFA框架通过解析getJSONOfXmlFile.xml这个业务流程描述文件实现了下载config/dsf.xml文件的功能

接下来我们可以通过修改请求报文尝试下载其它文件比如下载已知路径的getJSONOfXmlFile.xml流程描述文件

<Request  action=”admin_client/office/xml/module/getJSONOfXmlFile.xml” request=”JSON” response=”JSON” ><Data>{“path”:”admin_client/office/xml/module/getJSONOfXmlFile.xml”}</Data></Request>

下载的文件被转换为JSON格式,虽然与原始格式不一样,但基本能理解其功能:

 

从返回内容可以看出此项业务的流程如下:

 

从流程中使用的Java方法来看,此流程中只能处理xml格式的文件,并将xml文件的内容以JSON格式输出,很显然,其它类型的文件暂时无法利用其读取。

再次回到登录页面,通过浏览页面源代码,我们可以发现页面引用的scripts/common.js脚本中调用了一个getServerXML函数此函数同样具备获取文件内容的功能,而它使用的是另外一个流程描述文件:

 

利用这个流程描述文件构造请求尝试下载文件,构造的请求如下:

<Request  action=”admin_client/office/xml/module/getXmlContent.xml” request=”JSON” response=”FORMAT” ><Data>{“path”:”admin_client/office/xml/module/getJSONOfXmlFile.xml”}</Data></Request>

使用base64编码后提交请求获取的结果如下

 

在结果中,可以看到大段的base64编码字符串。提取其中的字符串使用base64解码后结果如下

 

到此我们已经发现了两个任意文件下载漏洞虽然其中一个有一定的限制但对于xml这种常用于配置的文件还是很有用的

3.2 遭遇坎坷

既然能够下载文件了,那么我们就可以大展拳脚的。是不是想到了什么?….

,业务流程描述文件能下载程序文件同样应该能够下载。在前面的章节中我们接触到了一个名为dsfa.fun.FileHelper的类那我们是不是可以试试下载这个类的class文件呢答案是肯定的。按照请求格式构造如下请求:

<Request  action=”admin_client/office/xml/module/getXmlContent.xml” request=”JSON” response=”FORMAT” ><Data>{“path”:”WEB-INF/classes/dsfa/fun/FileHelper.class”}</Data></Request>

:.class文件是Java应用的源代码经过编译之后形成的中间字节码文件,通常存放在应用目录下的WEB-INF/classes目录下按命名空间分目录存放

编码后提交请求,成功获得文件内容的base64编码字串由于是二进制文件我们可以将内容存到一个文件文件然后使用Python脚本进行转换

 

通过转换,成功获得FileHelper.class文件,然后,尝试使用XJadJava反编译工具)打开它,但遗憾的是并不能正确打开,通过对比此文件的头部与本地编译的.class文件头部,发现两个文件存在很大的差异:

 

笔者在此问题上纠结很久,最后总结原因为:由于服务器端采用的是文本文件读取的方式来读取文件内容的,导致二进制文件中很多不可见字符被转换,因此客户端收到的文件已经与服务端的不同了。

下载的.class文件无法反编译,这就使得我们无法更进一步了解应用功能,挖掘更有价值的漏洞了,测试工作一度停滞不前。

3.3 柳暗花明

Java Web应用的主要配置文件web.xml是我们在安全测试中经常要遇到的一个文件这个文件描述了应用的入口那这个DSFA框架会不会也存在多个入口呢

尝试采用上面的文件下载方法下载了一个web.xml,幸运的是居然在web.xml中发现了多个文件下载方法的定义,而且是独立于doPost这个Servlet之外的,这不可不说是意外之喜了!

 

根据Servlet的命名来看,DownLoadHtmlServlet似乎是用于下载html静态页面,我们暂时略过。先来看看DownLoadServlet是如何使用的,根据配置了解到访问路径为/DownLoadServlet,但我们并不知道应该传什么参数给服务器,怎么办呢?这里可以采用一个比较巧妙的办法来找到参数名。

利用前面介绍的下载漏洞下载一个无法正常反编译的DownLoadServlet.class文件,用记事本打开,寻找近似参数的字符串

 

经过分析,我们锁定了上图所示的三个关键词,然后分别使用这三个关键词作为参数名来进行下载尝试,很快我们就定位到真正的参数为filePath,最终,确定调用该方法的完整请求路径如下:

http://www.xxxx.com/xxx/DownLoadServlet?filePath=/WEB-INF/classes/dsfa/script/ DownLoadServlet.class

使用上面的URL下载的.class文件就能用XJAD正确打开了:

 

到达这个阶段,服务器上的文件已经可以任意下载了,那么接下来我们就可以下载一些跟DSFA框架相关的东西,来一窥其究竟。访问下面的路径就可以下载DSAF框架的核心库文件:

http://www.xxxx.com/xxx/DownLoadServlet?filePath=/WEB-INF/lib/dsf.jar

别问我们是怎么知道路径的细心的测试人员通过一些简单的测试验证就能基本确定文件的位置,但加上一定的文件名猜测也就八九不离十了

 

3.4 收获成果

前面的步骤中,我们一直在围绕着文件下载这个话题述说测试过程中踩过的坑,路途虽然坎坷,但总算是看到曙光!对于一次针对业务系统的安全测试来说,我们的目标是要拿到能证明所发现的问题足够威胁到业务安全的证据,最简单粗暴的方法就是上传Webshell,拿下服务器的控制权。

通过前面我们对DSFA框架的核心代码的了解,我们知道如果要想通过业务流程来上传文件,其先决条件是必须知道一个能够实现文件上传功能的业务流程描述文件,但茫茫文件之海,让我去那里找呢,所以这条路似乎不是首选。

继续研究web.xml一个新的目标进入了我们的视线它就是/DownLoadHtmlServlet,在前面的文章里我们也提到过它,下载这个Servlet对应的类文件,可以看到它的实现代码如下:

 

通过代码,可以清晰地看到htmlContent参数传入的内容被直接写入到filePath参数指定的文件中,而且路径就在Web应用目录下,那么后面的事情就简单了,只要构造如下请求就能在服务器上创建一个Webshell,拿下服务器的控制权:

 

然后,通过浏览器访问上传的Webshell

 

至于拿到Webshell之后的工作,相信大多数安全测试人员都知道应该怎么做了,这里就不继续赘述。

后记

我们看到在整个测试过程中,DSFA框架的漏洞发挥了至关重要的作用甚至于如果最后一步只能上传普通的HTML页面也还是可以再次利用DSFA框架来上传Webshell 有兴趣的朋友可以思考一下,另外DSFA框架中的多个活动(如SQL查询、Java方法调用)是不是都可以利用一下呢!

最后,我们想对有兴趣读到这里的朋友说一声:看了这么久,辛苦啦!另外,也想再次阐述一下文章想要表达的意图:虽然本文有很大篇幅都扯上了DSFA框架”这个大旗,但我们并不希望你去研究什么DSFA框架,世上框架千千万,不可能都让你研究透了再去做安全测试。我们期望的是在测试的过程中,测试人员可以抓住一些细节,深入挖掘,抱着不放弃的精神取得更大的成果。

 

附录

文中所用工具的下载地址:

Fiddler

https://www.telerik.com/fiddler

XJAD

http://dl.pconline.com.cn/download/376697.html

JD-GUI

http://jd.benow.ca/

Hackbar

https://addons.mozilla.org/en-US/firefox/addon/hackbar/

Win-Tool之编码转换工具

http://download.enet.com.cn/html/030212005122802.html

 

2人评论了“从DSFA框架应用测试看漏洞的深入利用”

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注