php imagecreatefrom* 系列函数之 png – janes

0x00 简介


这篇文章主要分析 php 使用 GD 库的 imagecreatefrompng() 函数重建 png 图片可能导致的本地文件包含漏洞。

当系统存在文件包含的点,能包含图片文件; 另外系统存在图片上传,上传的图片使用 imagecreatefrompng() 函数重建图片并保存在本地,则很可能出现文件包含的漏洞。

通常,系统在实现图片上传功能时,为了防范用户上传含有恶意 php 代码的图片,可采用 gd 库重建图片,gd 库重建图片的一系列函数 imagecreatefrom*,会检查图片规范,验证图片合法性,以此抵御图片中含有恶意 php 代码的攻击。

那么, imagecreatefrom* 系列函数是否能完全抵御图片中插入 php 代码的攻击呢,本文以 imagecreatefrompng() 函数作为研究对象,探讨实现重建 png 格式的图片中包含恶意 php 代码的可能性,以及所需要满足的条件。

png 文件格式, imagecreatefrompng 函数解析, 修改图片, 上传, 文件包含 ...

0x01 png 图片格式

要实现重建的 png 图片中仍包含有恶意的 php 代码, 首先要对 png 图片格式有基本的了解。png 支持三种图像类型:索引彩色图像(index-color images),灰度图像(grayscale images),真彩色图像(true-color images), 其中索引彩色图像也称为基于调色板图像(Palette-based images)。

标准的 png 文件结构由一个 png 标识头连接多个 png 数据块组成,如: png signature | png chunk | png chunk | ... | png chunk.

png 标识

png 标识作为 png 图片的头部,为固定的 8 字节,如下

89 50 4E 47 OD 0A 1A 0A

png 数据块

png 定义了两种类型的数据块,一种是称为关键数据块(critical chunk),标准的数据块; 另一种叫做辅助数据块(ancillary chunks),可选的数据块。关键数据块定义了3个标准数据块,每个 png 文件都必须包含它们。3个标准数据块为: IHDR, IDAT, IEND.

这里介绍4个数据块:IHDR, PLTE, IDAT, IEND

png 数据块结构

png 文件中,每个数据块由4个部分组成 length | type(name) | data | CRC, 说明如下

length: 4 bytes, just length of the data, not include type and CRC  
type: 4 bytes, ASCII letters([A-Z,a-z])
CRC: 4bytes

CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中,其值按下面的CRC码生成多项式进行计算: x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

  • IHDR

文件头数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。

文件头数据块由13字节组成,它的如下所示

域的名称 字节数 说明
Width 4 bytes 图像宽度,以像素为单位
Height 4 bytes 图像高度,以像素为单位
Bit depth 1 byte 图像深度.

原文链接:http://drops.wooyun.org/tips/16034

评论已关闭。