IPBUF安全漏洞报告
English
CVE-2025-68701 CVSS 7.5 高危

CVE-2025-68701: Jervis库确定性AES IV派生漏洞导致加密数据可预测

披露日期: 2026-01-13

漏洞信息

漏洞编号
CVE-2025-68701
漏洞类型
弱加密/密码学漏洞
CVSS评分
7.5 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Jervis

相关标签

弱加密确定性IVAES-CBCJenkins凭证泄露密码学漏洞Jervis

漏洞概述

Jervis是一个用于Job DSL插件脚本和共享Jenkins管道库的Java库。该库在2.2版本之前存在严重的密码学安全漏洞:在加密操作中使用确定性的AES初始化向量(IV)派生方式。正常情况下,AES加密应该使用随机生成的IV以确保相同明文每次加密产生不同的密文,从而防止模式分析和已知明文攻击。然而,Jervis从密码短语直接派生IV,使得相同的明文总是产生相同的密文输出。这种实现违反了现代密码学的最佳实践,攻击者可以通过分析加密数据的模式来推断明文内容或进行密码猜测攻击。由于Jervis常用于处理Jenkins的敏感配置和凭证信息,该漏洞可能导致敏感凭据、API密钥、部署凭证等机密信息泄露。攻击者无需任何认证即可利用此漏洞,对使用受影响版本Jervis的系统构成严重安全威胁。

技术细节

漏洞根因在于Jervis库在AES加密实现中使用了确定性的IV派生算法。在标准的AES-CBC模式中,IV应该是随机生成的,以确保加密语义安全。然而,Jervis在2.2之前的版本中,使用密码短语通过某种固定算法派生IV,这导致:1)相同的密码短语总是产生相同的IV;2)相同的明文在相同的密钥下总是产生相同的密文。攻击者可以利用这一特性进行以下攻击:已知明文攻击 - 如果攻击者知道某段密文对应的明文(如常见的header、配置格式等),他们可以验证密码猜测的正确性;选择明文攻击 - 通过观察加密输出模式,攻击者可以推断明文结构或识别重复内容;密码短语重用攻击 - 如果同一密码短语用于加密多个消息,攻击者可以识别这些消息之间的关系。漏洞代码通常表现为类似:IV = deriveIV(passphrase),而非标准的SecureRandom生成IV。修复方案使用密码学安全的随机数生成器(CSPRNG)生成随机的16字节IV,并在加密时将IV与密文一起传输或存储。

攻击链分析

STEP 1
步骤1
攻击者获取使用Jervis库加密的数据(密文),这些数据可能存储在Jenkins配置文件、构建日志或网络传输中
STEP 2
步骤2
由于使用确定性IV,攻击者可以识别相同密码短语加密的重复模式,或进行已知明文攻击
STEP 3
步骤3
攻击者利用确定性IV特性,通过已知的明文模式(如常见的header、JSON格式等)验证密码短语猜测
STEP 4
步骤4
一旦密码短语被破解,攻击者可以解密所有使用该密码短语加密的敏感数据,包括API密钥、凭证等
STEP 5
步骤5
攻击者利用窃取的凭证进行横向移动,访问Jenkins系统、部署管道或相关联的外部服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.MessageDigest; public class JervisDeterministicIV { // Vulnerable: Deterministic IV derivation from passphrase public static byte[] vulnerableEncrypt(String plaintext, String passphrase) throws Exception { // Derive key from passphrase MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] key = digest.digest(passphrase.getBytes()); // VULNERABLE: Deterministic IV from passphrase MessageDigest md = MessageDigest.getInstance("MD5"); byte[] iv = md.digest(passphrase.getBytes()); // Same passphrase = same IV! SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); return cipher.doFinal(plaintext.getBytes()); } // Secure: Random IV generation public static byte[] secureEncrypt(String plaintext, String passphrase) throws Exception { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] key = digest.digest(passphrase.getBytes()); // SECURE: Generate random IV byte[] iv = new byte[16]; new java.security.SecureRandom().nextBytes(iv); SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); // Prepend IV to ciphertext for storage/transmission byte[] ciphertext = cipher.doFinal(plaintext.getBytes()); byte[] combined = new byte[iv.length + ciphertext.length]; System.arraycopy(iv, 0, combined, 0, iv.length); System.arraycopy(ciphertext, 0, combined, iv.length, ciphertext.length); return combined; } public static void main(String[] args) throws Exception { String passphrase = "secret123"; String plaintext = "API_KEY=abc123"; // Demonstrating deterministic IV vulnerability byte[] enc1 = vulnerableEncrypt(plaintext, passphrase); byte[] enc2 = vulnerableEncrypt(plaintext, passphrase); System.out.println("Same encryption produces same output: " + MessageDigest.isEqual(enc1, enc2)); // Will be true - VULNERABLE! } }

影响范围

Jervis < 2.2

防御指南

临时缓解措施
如果无法立即升级到Jervis 2.2版本,应立即停止使用该库进行敏感数据加密操作,并将所有已加密的凭证和密钥迁移到使用安全随机IV的实现中。同时限制对Jenkins构建环境和配置的访问,减少攻击面。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表