安全研究
安全漏洞
Android软件开发工具包GIF文件处理堆溢出漏洞
发布日期:2008-03-04
更新日期:2008-03-05
受影响系统:
Google Android SDK m3-rc37a不受影响系统:
Google Android SDK m5-rc14描述:
BUGTRAQ ID: 28005
CVE(CAN) ID: CVE-2008-0985
Android是Google通过Open Handset Alliance发起的项目,用于为移动设备提供完整的软件集,包括操作系统、中间件等。
Android SDK的WebKitLib\WebKit\WebCore\platform\image-decoders\gif\GifImageDecoder.cpp文件中的GIFImageDecoder::haveDecodedRow()函数在解析GIF图形时存在堆溢出漏洞,远程攻击者可能利用此漏洞控制用户设备。
当com.google.android.browser进程处理带有GIF文件的内容时,会加载动态库libsgl.so,该库中包含有多种文件格式的解码器,其中解码GIF图形是由libsgl.so中的giflib完成的,而GIFImageDecoder封装对象错误的计算了整个图形大小。
首先,使用以下调用序列读取并储存Logical Screen:
GIFImageDecoder::onDecode() -> DGifOpen() -> DGifGetScreenDesc()
最后一个函数DGifGetScreenDesc()将_Logical Screen Width和Height_存储到了名为GifFileType的结构中:
/-----------
Int DGifGetScreenDesc(GifFileType * GifFile) {
...
/* Put the screen descriptor into the file: */
if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
return GIF_ERROR;
...
}
- -----------/
字段储存到了结构的前两个字中:
/-----------
typedef struct GifFileType {
/* Screen dimensions. */
GifWord SWidth, SHeight,
...
}
- -----------/
通过以下GIFImageDecoder::onDecode()函数反汇编可以看到调用DGifOpen()函数的方式,返回值(GifFileType结构)存储到了$R5 ARM寄存器上:
/-----------
.text:0002F234 BL _DGifOpen
.text:0002F238 SUBS R5, R0, #0 ; GifFile -_ $R5
- -----------/
然后调用了giflib函数DGifSlurp(),使用Image Width和Height而不是Logical Screen Size正确的分配了Image大小:
/-----------
Int DGifSlurp(GifFileType * GifFile)
{ ... ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
sp->RasterBits = (unsigned char *)malloc(ImageSize *
sizeof(GifPixelType));
...
}
- -----------/
之后将_Logical Screen_ Width和Height存储到了R9和R11寄存器:
/-----------
.text:0002F28C LDMIA R5, {R9,R11} ; R9=SWidth R11=SHeight !
- -----------/
但实际图形可能比向GIFImageDecoder方式所错误传送方式的大小大得多:
/-----------
ImageDecoder::chooseFromOneChoice():
.text:0002F294 MOV R0, R8
.text:0002F298 MOV R1, #3
.text:0002F29C MOV R2, R9
.text:0002F2A0 MOV R3, R11
.text:0002F2A4 STR R12, [SP,#0x48+var_3C]
.text:0002F2A8 BL _ImageDecoder19chooseFromOneChoice;
ImageDecoder::chooseFromOneChoice(SkBitmap::Config,int
,int)
Bitmap::setConfig():
.text:0002F2B8 MOV R0, R7 ; R7 = SkBitmap
.text:0002F2BC MOV R1, #3
.text:0002F2C0 MOV R2, R9 ; R9=SWidth R11=SHeight !
.text:0002F2C4 MOV R3, R11
.text:0002F2C8 STR R10, [SP,#0x48+var_48]
.text:0002F2CC BL _Bitmap9setConfig ;
Bitmap::setConfig(SkBitmap::Config,uint,uint,uint)
- -----------/
这个函数将SWidth和SHeight存储在Bitmap对象中,如下代码段所示:
/-----------
.text:00035C38 MOV R7, R2 ; $R2 = SWidth, goes to $R7
.text:00035C3C MOV R8, R3 ; $R3 = SHeight, goes to $R8
.text:00035C40 MOV R4, R0 ; $R4 = *Bitmap
- -----------/
之后:
/-----------
.text:00035C58 BL _Bitmap15ComputeRowBytes ;
SkBitmap::ComputeRowBytes(SkBitmap::Config,uint)
.text:00035C5C MOV R5, R0 ; $R5 = Real Row Bytes
.text:00035C68 STRH R7, [R4,#0x18] ; *Bitmap+0x18 = SWidth
.text:00035C6C STRH R8, [R4,#0x1A] ; *Bitmap+0x1A = SHeight
.text:00035C60 STRH R5, [R4,#0x1C] ; *Bitmap+0x1C = Row Bytes
- -----------/
<*来源:Alfredo Ortega
链接:http://marc.info/?l=bugtraq&m=120467906801934&w=2
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
建议:
厂商补丁:
------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
http://android-developers.blogspot.com/2008/03/android-sdk-update-m5-rc15-released.html
浏览次数:2931
严重程度:0(网友投票)
绿盟科技给您安全的保障
