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

参考