php imagecreatefrom* 系列函数之 png

  • Post author:
  • Post category:php


janes · 2016/05/20 9:48

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码生成多项式进行计算: x