致远 OA 代码执行漏洞分析

栏目: 编程工具 · 发布时间: 5年前

内容简介:作者:Longofo@知道创宇404实验室时间:2019年6月28日6月26日,有安全研究者预警并发布了关于致远OA系统的高危安全漏洞,攻击者可以通过某接口漏洞在未授权的情况下实现远程任意代码执行,最终控制整个系统权限。

作者:Longofo@知道创宇404实验室

时间:2019年6月28日

漏洞概述

6月26日,有安全研究者预警并发布了关于致远OA系统的高危安全漏洞,攻击者可以通过某接口漏洞在未授权的情况下实现远程任意代码执行,最终控制整个系统权限。

我对此漏洞进行了应急,随后对此漏洞进行了分析,下面记录下分析与查找过程。

漏洞分析

致远OA不是开源的,所以基本上找不到源码。根据POC可知道漏洞路径是 /seeyon/htmlofficeservlet 。通过搜索 htmlofficeservlet ,在github上找到一份老的源码 1HtmlOfficeServlet 主要逻辑代码在doGet中,如下所示:

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        CurrentUserToSeeyonApp.set(request.getSession());

        ApplicationContext ctx = (ApplicationContext) getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        HandWriteManager handWriteManager = (HandWriteManager) ctx.getBean("handWriteManager");
        HtmlHandWriteManager htmlHandWriteManager = (HtmlHandWriteManager) ctx.getBean("htmlHandWriteManager");

        DBstep.iMsgServer2000 msgObj = new DBstep.iMsgServer2000();
        try {
            handWriteManager.readVariant(request, msgObj);

            msgObj.SetMsgByName("CLIENTIP", request.getRemoteAddr());

            String option = msgObj.GetMsgByName("OPTION");

            if ("LOADFILE".equalsIgnoreCase(option)) {
                handWriteManager.LoadFile(msgObj);
            }           
            else if("LOADSIGNATURE".equalsIgnoreCase(option))
            {
                htmlHandWriteManager.loadDocumentSinature(msgObj);
            }
            else if("LOADMARKLIST".equalsIgnoreCase(option))
            {
                handWriteManager.LoadSinatureList(msgObj);
            }
            else if("SIGNATRUEIMAGE".equalsIgnoreCase(option))
            {
                handWriteManager.LoadSinature(msgObj);
            }           
            else if("SAVESIGNATURE".equalsIgnoreCase(option))
            {
                htmlHandWriteManager.saveSignature(msgObj);
            }
            else if("SAVEHISTORY".equalsIgnoreCase(option))
            {
                htmlHandWriteManager.saveSignatureHistory(msgObj);
            }
            else if("SIGNATRUELIST".equalsIgnoreCase(option))
            {//调入印章列表
                handWriteManager.LoadSinatureList(msgObj);
            }
            else if("SHOWHISTORY".equalsIgnoreCase(option))
            {
                htmlHandWriteManager.getSignatureHistory(msgObj);
            }

            handWriteManager.sendPackage(response, msgObj);
        }

猜测写入文件的部分应该是进入了某个条件分支中,尝试搭环境测试下。想要把整个环境搭起来很困难,所以这里只搭个 HtmlOfficeServlet 的测试环境, HtmlOfficeServlet 也有很多地方依赖其他类,最后我通过删改还是搭起了一个简单的 HtmlOfficeServlet 环境(有的jar包在github那个项目的 WebContent/WEB-INF/lib 下有,有的通过搜索能找到),如下所示:

致远 OA 代码执行漏洞分析

下面调试分析下通过PoC会进入哪个分支:

PoC

致远 OA 代码执行漏洞分析

致远 OA 代码执行漏洞分析

option是乱码,不会进入任何一个条件。在POC中,有一些我们无法正常识别的加密字符串,但是条件判断中是使用明文判断的,那么这些字符串应该也会被解码,这个解码的操作在 msgObj.GetMsgByName 中:

致远 OA 代码执行漏洞分析

在我这个demo环境中,这个DecodeBase64是一个标准的Base64解码操作,但是无法解码POC中被加密的数据。这里的Base64解码在后面会与后面较新版的致远OA中变种的Base64进行对比。

后面获得了致远OA A8 V7.SP3相关的Jar包,在本地搭建环境测试,不过依然需要修改一些地方东西,因为依赖的东西很多,在实际的环境中配置很多,但是本地测试没办法一一配置,所以可以删除或注释掉某些地方,但是对漏洞分析影响不大。下面进行调试分析:

致远 OA 代码执行漏洞分析

可以看到option被正确解码并且option是SAVEAIMG,而在github老代码中没有SAVEAIMG这个option。fileName是 ..\..\..\ApacheJetspeed\webapps\seeyon\test123456.jsp ,可以看到 test123456.jsp 就是被写入大多数网站的木马文件。通过msgObj.MsgFileSave将恶意代码写入到文件中:

致远 OA 代码执行漏洞分析

这里异常了,不过不要紧,只是我们地没有配置这个路径而已。

Base64编码差异

通过上面的两个分析可以看到,前一个没有正确解码被编码的数据,而后一个正确解码了,两者不同之处在于使用的加解密转换表不同。

前者的解码使用的转换表:

致远 OA 代码执行漏洞分析

this._$902 就是转换表

致远 OA 代码执行漏洞分析

后者使用的转换表:

致远 OA 代码执行漏洞分析

this._TableBase64 就是转换表

致远 OA 代码执行漏洞分析

@kk提供的一个用于加解密脚本,详细信息可以查看2.

参考链接

  1. https://github.com/zhf839428881/seeyon_v3x/blob/master/src_web_common/com/seeyon/v3x/common/office/HtmlOfficeServlet.java

  2. https://paper.seebug.org/964/


以上所述就是小编给大家介绍的《致远 OA 代码执行漏洞分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Thinking Recursively

Thinking Recursively

Eric S. Roberts / Wiley / 1986-1-17 / USD 85.67

The process of solving large problems by breaking them down into smaller, more simple problems that have identical forms. Thinking Recursively: A small text to solve large problems. Concentrating on t......一起来看看 《Thinking Recursively》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具