Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cve-2026-43512-poc — 针对CVE-2026-43512(Apache Tomcat 摘要认证绕过)的可利用性PoC | Kitploit
工具/GitHubGitHub/covepseng/cve-2026-43512-poc
漏洞分析漏洞利用Web安全渗透测试身份验证论文与研究学习与教育
GitHubcovepseng/cve-2026-43512-poc

cve-2026-43512-poc

针对CVE-2026-43512(Apache Tomcat 摘要认证绕过)的可利用性PoC

查看仓库
1162个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-43512 — Apache Tomcat DIGEST 认证绕过

可利用性分析结果: 根本原因已确认。但针对标准 UserDatabaseRealm 部署,端到端利用不可复现。详情请参见分析。


目录

  • 概述
  • 受影响版本
  • 根本原因
  • 分析
  • 仓库结构
  • 要求
  • 使用方法
  • 预期输出
  • 参考
  • 免责声明

概述

CVE-2026-43512 是 Apache Tomcat 的 HTTP DIGEST 认证机制中的一个漏洞。方法 RealmBase.getDigest() 在构造 A1 哈希输入之前,未验证 getPassword(username) 的返回值。当用户名在已配置的 Realm 中不存在时,getPassword() 返回 null,Java 的字符串连接运算符会静默地将其转换为四个字符的字面量 "null"。

服务器因此计算:

root@kitploit:~
A1 = MD5("<username>:<realm>:null")

客户端如果提交的 DIGEST 响应中使用字面量字符串 "null" 作为密码计算,则会产生相同的哈希。根据安全公告,这构成认证绕过。

本仓库包含一个最小可复现环境和一个基于 Go 的概念验证代码,用于对真实 Tomcat 实例验证这一论断。


受影响版本

受影响范围修复版本
7.0.0 – 7.0.1097.0.110
8.5.0 – 8.5.1008.5.101
9.0.0.M1 – 9.0.1179.0.118
10.1.0.M1 – 10.1.54

根本原因

RealmBase.java 中的脆弱代码路径(所有受影响分支):

root@kitploit:~
// RealmBase.java — 脆弱版本
protected String getDigest(String username, String realmName, String algorithm) {
    if (hasMessageDigest(algorithm)) {
        return getPassword(username);  // 对于未知用户返回 null
    }

    // null 会被 Java 连接为字面量 "null"
    String a1 = username + ":" + realmName + ":" + getPassword(username);
    return HexUtils.toHexString(
        ConcurrentMessageDigest.digest(algorithm, a1.getBytes(...))
    );
}

修复(提交 6565a6c)增加了一个显式的空检查:

root@kitploit:~
// RealmBase.java — 已修复
protected String getDigest(String username, String realmName, String algorithm) {
    String password = getPassword(username);
    if (password == null) {
        return null; 
    }
    ...
}

分析

针对 Tomcat 11.0.0-M1 运行 PoC,并启用 FINE 级别日志,观察到以下结果:

root@kitploit:~
Digest:        2388e2c78407def640f37f092a8d3a84   ← 客户端
Server digest: 2388e2c78407def640f37f092a8d3a84   ← 服务端
Failed to authenticate user [ghost]

摘要哈希匹配。 getDigest() 中的错误确实存在且已确认。然而,认证仍然失败,因为 RealmBase.authenticate() 包含一个独立的二次检查:

root@kitploit:~
// RealmBase.authenticate()
if (serverDigest.equals(clientDigest)) {
    return getPrincipal(username);  // 对于不存在的用户返回 null
}
return null;

在由 tomcat-users.xml 支持的典型 UserDatabaseRealm 中,getPrincipal() 会查询内存中的用户数据库。对于数据库中不存在的用户名,返回 null。调用方将 null Principal 视为认证失败,并返回 401。


仓库结构

root@kitploit:~
cve-2026-43512-poc/
├── Dockerfile                          # Tomcat 11.0.0-M1(受影响版本)
├── tomcat-users.xml                    # 最小 Realm 配置 — 无用户 "ghost"
├── web.xml
├── exploit/
│   ├── exploit.go                      # PoC — Go,仅使用标准库
│   └── go.mod
└── README.md

要求

工具版本说明
Podman≥ 4.0Docker 亦可使用
Go≥ 1.22仅在本地运行利用代码时需要

使用方法

1. 构建并启动容器

root@kitploit:~
podman build -t tomcat-cve-2026-43512 .
podman run -d --name tomcat-vuln -p 8080:8080 tomcat-cve-2026-43512

等待数秒使 Tomcat 完成启动,然后验证其是否正常运行:

root@kitploit:~
curl -si http://localhost:8080/protected/secret.html | head -1
# 预期输出:HTTP/1.1 401

2. 运行利用代码

root@kitploit:~
cd exploit
go run exploit.go \
  -target   http://localhost:8080 \
  -path     /protected/secret.html \
  -username ghost

可用参数:

3. 启用详细 Tomcat 日志(可选)

要观察内部认证状态,可添加 logging.properties 文件并挂载:

root@kitploit:~
org.apache.catalina.authenticator.level = FINE
org.apache.catalina.realm.level = FINE
root@kitploit:~
podman run -d --name tomcat-vuln -p 8080:8080 \
  -v ./logging.properties:/usr/local/tomcat/conf/logging.properties:ro \
  tomcat-cve-2026-43512

日志将直接显示摘要比较结果,从而确认哈希是否匹配。

4. 清理

root@kitploit:~
podman stop tomcat-vuln && podman rm tomcat-vuln

预期输出

root@kitploit:~
============================================================
 CVE-2026-43512 — Tomcat DIGEST Auth Bypass PoC
============================================================
 Target   : http://localhost:8080/protected/secret.html
 Username : "ghost"  (must NOT exist in tomcat-users.xml)
 Password : "null"   (literal string)
------------------------------------------------------------
[1] Sending unauthenticated request to obtain DIGEST challenge...
[+] HTTP 401 received — DIGEST challenge:
    Digest realm="UserDatabase", qop="auth", nonce="...", opaque="..."

[*] realm="UserDatabase"  nonce="..."  qop="auth"  algorithm="MD5"

[2] Computing DIGEST response with password="null"...
    Digest username="ghost", realm="UserDatabase", ...

[3] Sending request with crafted DIGEST credentials...
------------------------------------------------------------
[✗] HTTP 401 — exploit failed.
    The UserDatabaseRealm provides a second line of defence:
    getPrincipal("ghost") returned null after the digest matched.
============================================================

参考


免责声明

本仓库仅用于教育目的和本地可利用性分析。所有测试均在自托管的容器环境中进行。请勿将此 PoC 用于非您拥有或未获得明确书面授权的系统。

下载工具
10.1.55
11.0.0.M1 – 11.0.2111.0.22
标志默认值说明
-targethttp://localhost:8080Tomcat 基础 URL
-path/protected/受保护资源的路径
-usernameghost要使用的用户名 — 必须不存在于 tomcat-users.xml 中
资源链接
Apache Tomcat 安全公告https://tomcat.apache.org/security-9.html
修复提交https://github.com/apache/tomcat/commit/6565a6cb6499e56fe2f34457cec99f9d1c4f39e9
RealmBase.java(主分支)https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/realm/RealmBase.java
RFC 2617 — HTTP Digest 认证https://datatracker.ietf.org/doc/html/rfc2617
完整分析 — 博客文章https://return-zero.dev/posts/cve-2026-43512