通达OA 漏洞分析

漏洞通报信息:

https://mp.weixin.qq.com/s/_bpg8buT92dzRuGdr2ZrRg

https://mp.weixin.qq.com/s/s1yqJNOsCk-uVyCtg6SG7A

 

OA-2017非官网:http://www.downxia.com/downinfo/202980.html

最新版v11下载地址:http://www.tongda2000.com/download/2019.php?F=baidu_natural&K=

补丁包:http://cdndown.tongda2000.com/oasp/2019/2020_A1.rar

 

 

下载补丁包查看,发现新版v11的补丁有点多啊,又看了一下2017版本的,发现只修改了一个ispirit/im/upload.php。于是选择先分析OA2017作为切入点,方便偷懒。

 

基本思路:安装2017版的通达OA,提取出对应的upload.php做个代码对比,就能够知道补丁的修改点了。

安装后在webroot目录下获得了全部代码,不过代码都是zend54加密的,需要解密。

由于文件比较多,可以使用SeayDzendj本地解密:https://www.webshell.cc/6379.html

之后使用Bcompare进行代码比对,发现代码有两处变动。

 

第一处:

通达OA 漏洞分析_第1张图片

 

第二处:

通达OA 漏洞分析_第2张图片

 

 

分析:

第一处代码的修改使原本可以不包含的auth.php变成了必定包含。那我们来看一下auth.php的内容。

auth.php

 

通达OA 漏洞分析_第3张图片

显然,auth.php是用来检验用户登录状态的。那么在修复前,是if..else语句,该检测可以被绕过,从而在未登录的状态下执行后续的文件上传操作。

 

第二处代码的修改则是多了一句

if (strlen(urldecode($_FILES['ATTACHMENT']['name'])) != strlen($_FILES['ATTACHMENT']['name']))

 {

        $_FILES['ATTACHMENT']['name'] = urldecode($_FILES['ATTACHMENT']['name']);

  }

如果字符串解码后的长度与原长度不同,说明可以被url解码,那么再url解码,而不是直接解码。

 

一开始怀疑是把shell.php文件名二次编码后绕过上传检测,然后在其他调用上传文件的页面(例如个人文件移动)中被再次解码,生成shell.php文件。 所以在此加入了检测语句,防止文件名被二次解码。但仔细一想,发现这根本没什么用呀,这里的代码解码只进行了一次,无法检测3次、4次url编码的文件名,并不能达到拦截文件名的效果。

 

网站内随便找点上传功能试试,也没发现什么端倪

通达OA 漏洞分析_第4张图片

这边疑惑了很久,搞不清它的意义。后来觉得可能这并不是漏洞的修补点,因为通达OA2017也有很多个小版本,可能小版本更新中早就已经加入了这段代码,而非此次的补丁(后续对OA v11的分析也印证了这一点)。

 

在url检测后,紧接着是文件上传。

$ATTACHMENTS = upload("ATTACHMENT", $MODULE, false);

尝试构造上传请求,必要的变量名有P,DEST_UID,以及一个文件的变量名ATTACHMENT。

同时上传参数值以及文件内容的请求比较少见,那么此时作为一个垃圾安全人员,如何POST值的同时加入文件上传这种问题,显然是要百度解决的。百度后,我们可以构造类似于下面这种形式的页面代码,抓取其请求进行修改。



     

     

     

 

通达OA 漏洞分析_第5张图片

构造请求包,上传成功。文件保存于\MYOA\attach\im\2003\目录,在原来的文件名前面加了一长串随机值,而且该目录不存在web目录下。 尝试在文件名中插入../测试是否能目录穿越,也不行。

 

我们再看代码,之前提到的第二处代码修改点的外围是if ($UPLOAD_MODE == '1') {  }。

那么就想着尝试$UPLOAD_MODE == '1'来看看会出现什么情况,结果发现$UPLOAD_MODE这个变量是凭空出现的!  先不慌,猜想可能是从其他文件中包含过来的,或者是某种全局变量啥的。 全局搜索字段“UPLOAD_MODE”,也是什么都没有。  那么这个变量是量子力学?平行宇宙?  

可以通过“变量覆盖漏洞”的知识点联想“变量注册”这个概念,参考:https://www.cnblogs.com/xiaozi/p/7768580.html

例如当register_globals=On的时候,可以直接使用$id来代替$_GET['id'] $_POST['id']接受传递过来的值。 当然不只这一种方式,此处也并非是这种方式,就不再浪费时间去找相关的代码了。 实践出真知,直接上传测试。

 

通达OA 漏洞分析_第6张图片

变量$UPLOAD_MODE注册成功,上传文件成功,实际在目录中的文件名是1123589952.12345.gif,还是仍旧保存在原来的目录。

不过只能上传小马文件,却无法触发,这就很难受。继续分析一下,会发现一个奇怪的地方,upload.php所在的目录\ispirit\im中的代码似乎是一条独立的系统,并没有用于其web页面。

这im其实是负责通达OA的客户端程序-办公精灵的后端接口。从菜单栏-附件程序可以下载

                   通达OA 漏洞分析_第7张图片                      通达OA 漏洞分析_第8张图片

 

下载了客户端,不过客户端一直连不上服务。而且也为这2017版的漏洞点花了太多时间,性价比不高,就暂时停止了。

 

回过头来看最新版v11,我们以2017的upload.php漏洞进行切入。

查看ispirit/im/upload.php,通过对比可以发现只有一个修改点,和2017版本的补丁一样,是对auth.php的包含问题。而之前在2017版本的困惑的第二个修改点,在此却并不是补丁,代码前后一致,说明之前的想法是对的,这里并不是漏洞触发点。

通达OA 漏洞分析_第9张图片

 

 

然后我们对所有的补丁的文件做个统计,会发现大部分的代码修改点都是一致的

general\appbuilder\modules\officeproduct\models\OfficeProducts.php

general\netdisk\api.php

general\person_info\avatar\avatar.upload.php

general\picture\upload_new.php

general\reportshop\design\report\set_report.php

general\reportshop\workshop\report\crscell\set_report.php

general\setting_guide\update.php

general\index_simple_submit.inc.php

inc\attendance\attend.clock.funcs.php

inc\interface\interface.netdisk.funcs.php

inc\interface\interface.picture.funcs.php

inc\utility_file.php

module\AIP\upload.aip.php

task\clean\slow_logs.inc.php

 

上述14个文件的代码修改点:rename函数更改为td_rename

 

general\system\attachment\position\add.php

general\system\attachment\position\update.php

上述2个文件的代码中皆增加了如下代码检测,检测路径中的关键字。通达OA 漏洞分析_第10张图片

ispirit\im\upload.php  包含auth.php,检测登录状态。

通达OA 漏洞分析_第11张图片

 

    \ispirit\interface\gateway.php增加了..检测,防止跨目录包含

通达OA 漏洞分析_第12张图片

 

mobile\inc\funcs.php

general\netdisk\swfupload_new.php

这两个文件改动有些大,不再讨论。

 

分析一下最广泛的补丁:rename函数更改为td_rename,

   rename()是php的自带函数,rename(oldname,newname)函数重命名文件或目录。若成功,则该函数返回 true。若失败,则返回 false。rename也是支持路径输入的,即可以移动文件,跨目录改名。

td_name()则是在inc\utility_file.php中被定义的:

function td_rename($oldname, $newname)

{

if (!is_uploadable($newname)) {

Message(_("禁止"), _("禁止创建此类型文件"));

Button_Back();

exit();

}



if (file_exists($oldname)) {

return rename($oldname, $newname);

}

else {

Message(_("错误"), _("原文件不存在"));

Button_Back();

exit();

}

}

 

有了is_uploadable()的检测, 其定义也在inc\utility_file.php中,禁止改名后的新文件以php为后缀。

 

通达OA 漏洞分析_第13张图片

 

     很容易联想到在ispirit\im\upload.php中存在无需登录的文件上传,只不过文件名称被做了限制,而且保存目录不在网站目录下。 这时候配合rename()的改名和移动目录的能力,就能把文件名改为xx.php并放入网站目录下。不过遗憾的是,这个改名操作的漏洞点需要用户在登录状态下才能,降低了安全风险。 rename()带来的安全隐患应该普遍存在于各个web项目中。

 

参考:

UnicodeSec出了一个分析,https://www.cnblogs.com/potatsoSec/p/12516234.html

在ispirit/interface/gateway.php中存在的文件包含漏洞可以通过包含日志的形式触发,且无需登录。

poc:

首先构造url并访问,在日志中写入一句话

/ispirit/interface/gateway.php?json={}&aa=

 

然后通过如下url进行文件包含利用

/ispirit/interface/gateway.php?json={}&url=../../ispirit/../../nginx/logs/oa.access.log

你可能感兴趣的:(信息安全,代码审计,PHP)