4.6.1 漏洞的起因

“JPEG是联合图像专家小组的英文缩写,该小组制定了图像压缩的国际标准算法——JPEG算法,由该算法产生的图像就是JPEG图像。”老师说道。

小知识:JPEG图像的主要格式

0xFFD8  图像开始标志

0xFFE0 ~0xFFEF 应用0~应用F标志,标志后面接相关数据,下同

0xFFFE 注释标志

0xFFDB 量化表标志

0xFFD0 帧开始标志

0xFFD4 哈夫曼表标志

0xFFDA 图象数据标志

0xFFD9 图像结束标志

“会出现问题的地方在注释部分,注释段以0xFFFE为开始标志;后面是注释段的长度值,再后面为注释的数据。”

“注释段的长度值是2个字节的无符号数,其值为注释的数据长度+2,这里的2是长度值本身占用的2个字节。一个合法的注释段如图4-54。”

老师指着图解释道:“注释数据‘0x0102’为2个字节,所以长度值=2+2=4。当系统要拷贝注释内容时,就分配长度值-2=4-2=2的空间,然后把注释内容拷到那个空间去。

“嗯,看起来都很好啊?有什么问题吗?”古风问道。

“呵呵!问题就在这里,由于长度值本身占据的两个字节要计入长度中,所以长度值的最小值为2,表示没有注释数据在后面。而如果长度值被伪造为0或1,大家想想会有什么问题呢?”老师望着台下听讲的同学们。

“长度值会被减2,那0或1减2,就会得到-2或-1,那程序会怎样呢?”大家觉得很奇怪。

“长度定义是无符号数,那-2或-1就会被认为是……”老师提醒大家。

“-2或-1就会被认为是是无符号数的0xFFFE或0xFFFF!” 大家终于回过神来。

“对!这样系统就分配大量的空间用于存储并拷贝,由于拷贝的数据非常大,自然就会引发异常了。”