安全研究

安全漏洞
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://marc.info/?l=bugtraq&m=120467906801934&w=2

建议:
厂商补丁:

Google
------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://android-developers.blogspot.com/2008/03/android-sdk-update-m5-rc15-released.html

浏览次数:2931
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障