文章来源:水滴安全实验室
通达OA简介
通达OA是由北京通达信科科技有限公司研发的一款通用型OA产品,涵盖了个人事务、行政办公、流程审批、知识管理、人力资源管理、组织机构管理等企业信息化管理功能。
本次复现环境是通达OAV11.3,文件上传漏洞为全版本通杀,文件包含漏洞/ispirit/interface/gateway.php只有V11.3版本存在。
漏洞分析环境
下载OA软件地址:https://www.tongda2000.com/download/2019.php
下载安装,配置访问端口为8080
网站源码在安装目录的wwwroot目录下:
源码经过zend 5.4加密,解密
文件上传漏洞分析
根据官网发布的补丁,更新的是ispirit/im/upload.php这个文件,跟进这个文件
$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";
}
当传入参数P且P不为空时,包含inc/session.php获取session,否则就会包含/auth.php进行用户认证。
继续跟进upload.php,23行,29行,35行逻辑判断是否传入DEST_UID参数,若参数不存在或者值为0则退出。
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();
}
}
传入一个DEST_UID=2后,访问,提示无文件上传,进入文件上传逻辑。
跟进upload.php的45行,1<=count($_FILES)判断是否有文件上传,如果上传包中存在文件则直接调用52行的upload()函数,否则直接退出。
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();
}
跟进uoload.php第82行,判断UPLOAD_MODE参数的取值,如果没有该参数,直接返回157行的内容,回包中没有路径和后台保存的文件名。
当指定UPLOAD_MODE参数进行上传时,会回显ATTACHMENTS["ID"]和ATTACHMENTS["NAME"]两个变量拼接的字符串。ATTACHMENTS数组是52行上传文件成功upload函数返回的数组。
跟进包含在inc/utility_file.php中第1665行的upload()函数,第1692行通过is_uploadable()函数对上传文件后缀名进行检测,跟进第2307行,判断上传文件"."后面三个字符是否是php,针对Windows可以使用".php."进行绕过上传。
function is_uploadable($FILE_NAME)
{
$POS = strrpos($FILE_NAME, ".");
if ($POS === false) {
$EXT_NAME = $FILE_NAME;
}
else {
if (strtolower(substr($FILE_NAME, $POS + 1, 3)) == "php") {
return false;
}
$EXT_NAME = strtolower(substr($FILE_NAME, $POS + 1));
}
第1715行,ATTACHMENTS[ID]由add_attach()函数返回。
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 . "*";
}
跟进add_attach()函数,1877行,上传文件保存的路径是attach目录下拼接upload.php文件中指定的$MODULE变量拼接$YM变量。
$ATTACH_PARA_ARRAY = TD::get_cache("SYS_ATTACH_PARA");
$ATTACH_POS_ACTIVE = $ATTACH_PARA_ARRAY["SYS_ATTACH_POS_ACTIVE"];
$ATTACH_PATH_ACTIVE = $ATTACH_PARA_ARRAY["SYS_ATTACH_PATH_ACTIVE"];
if (!file_exists($SOURCE_FILE)) {
return false;
}
if ($MODULE == "") {
$MODULE = attach_sub_dir();
}
if ($YM == "") {
$YM = date("ym");
}
$PATH = $ATTACH_PATH_ACTIVE . $MODULE;
if (!file_exists($PATH) || !is_dir($PATH)) {
@mkdir($PATH, 448);
}
$PATH = $PATH . "/" . $YM;
if (!file_exists($PATH) || !is_dir($PATH)) {
@mkdir($PATH, 448);
}
跟进1887行,保存的文件名
$FILENAME = $PATH . "/" . $ATTACH_ID . "." . $ATTACH_FILE;
跟进1926行,add_attach()函数返回ATTACH_ID_NEW变量
$ATTACH_ID_NEW = $AID . "@" . $YM . "_" . $ATTACH_ID;
至此,通过在upload.php文件指定UPLOAD_MODE变量的值为1,2,3都可以获取上传文件的路径和文件名
开发者指定的保存路径不在webroot目录下面,只能通过文件包含漏洞进行包含触发漏洞。
文件包含漏洞分析
文件包含漏洞出现在/ispirit/interface/gateway.php,首先接从客户端接收一个$json的参数,然后将$json转换为数组后再转换成变量,当存在$json数据中存在一个key为url的且不为空的值时,并且url传入的数据中有general/或者ispirit/或者module/时,执行include_once包含该url。
此处文件包含的另外一个利用,直接触发nginx的错误日志,利用文件包含直接getshell成功
包含ngnix错误日志中的php代码
漏洞修补建议
下载官方补丁:http://www.tongda2000.com/news/673.php
推荐文章++++