CVE-2022-44268漏洞分析

漏洞描述

ImageMagick 7.1.0-49 is vulnerable to Information Disclosure. When it parses a PNG image (e.g., for resize), the resulting image could have embedded the content of an arbitrary file (if the magick binary has permissions to read it).

漏洞环境

vulhub环境

漏洞复现

安装依赖

1
pip install pypng

使用poc.py生成poc

1
python poc.py generate -o poc.png -r /etc/passwd

上传文件并保存新生成的图片为out.png

image-20230303141135564

使用poc.py提取文件信息

1
python poc.py parse -i out.png

image-20230303142958960

PNG组成

最好结合010Editor进行分析

PNG数据块

PNG定义了两种数据块,分别为关键数据块和辅助数据块

数据块符号 数据块名称 多数据块 可选否 位置限制
IHDR 文件头数据块 否 否 第一块
cHRM 基色和白色点数据块 否 是 在PLTE和IDAT之前
gAMA 图像γ数据块 否 是 在PLTE和IDAT之前
sBIT 样本有效位数据块 否 是 在PLTE和IDAT之前
PLTE 调色板数据块 否 是 在IDAT之前
bKGD 背景颜色数据块 否 是 在PLTE之后IDAT之前
hIST 图像直方图数据块 否 是 在PLTE之后IDAT之前
tRNS 图像透明数据块 否 是 在PLTE之后IDAT之前
oFFs (专用公共数据块) 否 是 在IDAT之前
pHYs 物理像素尺寸数据块 否 是 在IDAT之前
sCAL (专用公共数据块) 否 是 在IDAT之前
IDAT 图像数据块 是 否 与其他IDAT连续
tIME 图像最后修改时间数据块 否 是 无限制
tEXt 文本信息数据块 是 是 无限制
zTXt 压缩文本数据块 是 是 无限制
fRAc (专用公共数据块) 是 是 无限制
gIFg (专用公共数据块) 是 是 无限制
gIFt (专用公共数据块) 是 是 无限制
gIFx (专用公共数据块) 是 是 无限制
IEND 图像结束数据 否 否 最后一个数据块

数据块中有 4 个关键数据块,其中 IHDR、IDAT 和 IEND 是必填选项:

  1. 文件头数据块 IHDR(header chunk):包含有图像基本信息,作为第一个数据块出现并只出现一次。
  2. 调色板数据块 PLTE(palette chunk):必须放在图像数据块之前。
  3. 图像数据块 IDAT(image data chunk):存储实际图像数据。PNG 数据允许包含多个连续的图像数据块。
  4. 图像结束数据 IEND(image trailer chunk):放在文件尾部,表示 PNG 数据流结束。

数据块结构

PNG文件中,每个数据块由4个部分组成,如下:

名称 字节数 说明
Length(长度) 4字节 指定数据块中数据域的长度,其长度不超过(231-1)字节。该长度只包含数据块的长度。
Chunk Type Code(数据块类型码) 4字节 数据块类型码由ASCII字母(A-Z和a-z)组成
Chunk Data(数据块数据) 可变长度 存储按照Chunk Type Code指定的数据
CRC(循环冗余检测) 4字节 存储用来检测是否有错误的循环冗余码

PNG标识符

PNG格式固定标识头是89504E47 0D0A1A0A

TIPS

此处漏洞出现的位置位于tEXt数据块

漏洞分析

从补丁看到漏洞出现在ReadOnePNGImage()函数,在使用ImageMagick命令转换png文件时会触发该函数

https://github.com/ImageMagick/ImageMagick/blob/7.1.0-49/coders/png.c#L2164

image-20230303145819699

找到打补丁的地方,是ImageMagick在处理MagickPathExtent的时候,根据源码可以知道FormatLocaleString()用于将一个变量列表转换为字符串,SetImageProperty()用于将指定的字符串赋值给特定的已知属性或自由属性

https://github.com/ImageMagick/ImageMagick/blob/7.1.0-49/coders/png.c#L3982

image-20230303151300826

跟进SetImageProperty()

https://github.com/ImageMagick/ImageMagick/blob/7.1.0-49/MagickCore/property.c#L4360

image-20230303152557017

在处理profile属性时候,会将指定的文件转换成字符串赋值回profile,随后重新将profile的值设置回图片中

https://github.com/ImageMagick/ImageMagick/blob/7.1.0-49/MagickCore/property.c#L4711

image-20230303153256695

跟进FileToStringInfo(),从源码得知该函数用于返回指定文件的内容,所以造成了信息泄漏漏洞

https://github.com/ImageMagick/ImageMagick/blob/7.1.0-49/MagickCore/string.c#L1005

image-20230303152951952

补丁

https://github.com/ImageMagick/ImageMagick/commit/05673e63c919e61ffa1107804d1138c46547a475

image-20230303151018812

参考