首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Microsoft GdiPlus.dll EMF GpFont::SetData Stack Overflow
来源:http://www.blacksecurity.org 作者:redsand 发布时间:2009-03-25  

Microsoft GdiPlus.dll EMF GpFont::SetData Stack Overflow


Write up by redsand@blacksecurity.org
Credits to mIKEJONES for providing the .EMF Crash


An integer overflow has been found within the Microsoft Windows gdiplus.dll [0x4ED67060]

This vulnerability currently allows us to write 64 bytes of either NULL's to the stack or UNICODE characters we control, inadvertently overwriting our stacks return addresses as well as the stack canary. We’ve decided to call this the Microsoft GdiPlus EMF GpFont.SetData integer overflow.

One known vulnerable version of GdiPlus.dll is:
x86_Microsoft.Widnows.GdiPlus_6595b64144ccf1df_1.0.2600.5581_x-ww_dfbc4fc4


Below is our confirmed call stack after the stack overflow:

GdiPlus!GpFont::SetData+0xf6
GdiPlus!MetafilePlayer::AddObject+0x8f
GdiPlus!ObjectEPR::Play+0x1a
GdiPlus!GdipPlayMetafileRecordCallback+0x35
GdiPlus!MetafilePlayer::EnumerateEmfPlusRecords+0x66
GdiPlus!EnumEmfWithDownLevel+0x52
gdi32!bInternalPlayEMF+0x6b0
GdiPlus!MetafilePlayer::EnumerateEmfRecords+0xd7
GdiPlus!GpGraphics::EnumEmfPlusDual+0x27d
GdiPlus!GpMetafile::EnumerateForPlayback+0x686
GdiPlus!GpMetafile::Play+0x26
GdiPlus!GpGraphics::DrawImage+0x263


We decided to pull this up using a fancy version of OllyDbg and begin digging around. With that said, this is what we found:

You will note at address 0x4ECFFA33 MOV ESI,DWORD PTR DS:[EAX+14]
We control the value loaded into ESI. For this purpose we use a value greater than 0xFE000000. This integer can be located at the offset 0xC8 (200 bytes) within the given example.

Next you will see we are able to control the value loaded into ECX. For the ESI value of 0xFFFFFFFF (largest unsigned integer) we load the value of 0x16 into our register (for example: if value is 0xEEEEEEEE, our value becomes 0xDDDDDDF4 and becomes greater than 0x16 and is marked as an invalid image)
4ECFFA36 LEA ECX, DWORD PTR DS:[ESI+ESI+18]

This value is increased by 0x18 (24) bytes:
4ECFFA3A ADD EAX, 18

Then compared with a value offset of EBP, which is located on our stack. For this purpose the value stored in ECX is 0x16:
4ECFFA3D CMP DWORD PTR SS:[EBP+C],ECX

This means the jmp is not taken
4ECFFA40 JB gdiplus.4ECFFAC9

Our controlled value is compared with the hex value 0x20 (32)
4ECFFA46 CMP ESI,20

And this jump will also never be taken.
4ECFFA49 JBE SHORT gdiplus.4ECFFA4E

From here, we begin to setup our stack for the __stdcall calling approach to our function gdiplus.4ED67060

4ECFFA4B PUSH 20
4ECFFA4D POP ESI
4ECFFA4E PUSH ESI
4ECFFA4F PUSH EAX
4ECFFA50 LEA EAX,DWORD PTR SS:[EBP-44]
4ECFFA53 PUSH EAX

This is the function in which the stack overwrite actually occurs.
4ECFFA54 CALL gdiplus.4ED67060


Let’s step into our function gdiplus.4ED67060:

First we have a loop setup to go through our Unicode Font String (ARIAL) and copy it (letter by letter) to another location on the stack controlled by EDI. This approach would be the natural code execution process however after further review, we're able to determine we can utilize the length of the font name (ARIAL) and extend it to 32 total WORD bytes (since this is Unicode, that's 64 bytes total). This will eat up our allocated memory and will halt the need to zero out the rest of the buffer.
Stack corruption occurs either here or below.

4ED67069 XOR ESI,ESI
4ED6706B TEST ECX,ECX
4ED6706D JBE SHORT gdiplus.4ED6709C
4ED6706F MOV EDX,DWORD PTR SS:[EBP+C]
4ED67072 PUSH EDI
4ED67073 MOV EDI,DWORD PTR SS:[EBP+8]
4ED67076 MOV AX,WORD PTR DS:[EDX]
4ED67079 TEST AX,AX
4ED6707C JE SHORT gdiplus.4ED6708A
4ED6707E MOV WORD PTR DS:[EDI],AX
4ED67081 INC EDI
4ED67082 INC EDI
4ED67083 INC EDX
4ED67084 INC EDX
4ED67085 INC ESI
4ED67086 CMP ESI,ECX
4ED67088 JB SHORT gdiplus.4ED67076

Once our string copy has been completed, we check to see if our wide character string length of our font (ARIAL) is less than 0x20 (32) characters

4ED6708A CMP ESI,ECX
4ED6708C JNB SHORT gdiplus.4ED6709B


The length of our string (ESI) is subtracted into 0x20 (32) to get the remainder (0x1B if using just the font name ARIAL) and is left in the register ECX
4ED6708E SUB ECX,ESI

Here we clear our value for eax to make it zero
4ED67090 XOR EAX,EAX

Then we shift the value of our remainder 0x1B (27) right one position which leaves us with 0x0D (13)
4ED67092 SHR ECX,1

This is where our overflow occurs; EDI points to our stack just past the location where we copied our font string on the stack earlier.

4ED67094 REP STOS DWORD PTR ES:[EDI]


This is what our stack looks like at that location when we begin overwriting it with zeros.
0007E344 |7C900000 ..�| ntdll.7C900000
0007E348 |7C9101C0 À‘| ntdll.7C9101C0
0007E34C |FFFFFFFF ÿÿÿÿ
0007E350 |7C9101BB »‘| RETURN to ntdll.7C9101BB from ntdll.7C90E8E6
0007E354 |4EC5221F "ÅN RETURN to gdiplus.4EC5221F from ntdll.RtlAllocateHeap

The rest below does not concern us as there is little we can leverage from this.

4ED67096 ADC ECX,ECX
4ED67098 REP STOS WORD PTR ES:[EDI]
4ED6709B POP EDI
4ED6709C POP ESI
4ED6709D POP EBP
4ED6709E RETN 0C

Our call stack doesn't begin to be corrupted until several functions later when our nulls come up to be pop'd into EIP from a RETN from ESP.

When we return execution back to 0x4ECFFA86, our valid returns on the stack have been used, leaving us with a corrupted stack scenario.

Below is a snapshot of our stack before the overflow occurs:

0007E2B0 |003B0041 A.;.
0007E2B4 |0007E0AC ˆ .
0007E2B8 |00000000 ....
0007E2BC |0007ED40 @í .
0007E2C0 |7C90E900 .é�| ntdll.7C90E900
0007E2C4 |7C9101C0 À‘| ntdll.7C9101C0
0007E2C8 |FFFFFFFF ÿÿÿÿ
0007E2CC |7C9101BB »‘| RETURN to ntdll.7C9101BB from ntdll.7C90E8E6
0007E2D0 |4EC5221F "ÅN RETURN to gdiplus.4EC5221F from ntdll.RtlAllocateHeap
0007E2D4 |003B0000 ..;.
0007E2D8 |40000060 `..@
0007E2DC |0000001C ...
0007E2E0 |0007E2F0 ðâ .
0007E2E4 |4EC9DD15 ÝÉN RETURN to gdiplus.4EC9DD15 from gdiplus.4EC52209
0007E2E8 |0000001C ...
0007E2EC |00000006 ...
0007E2F0 |00009C45 Eœ..
0007E2F4 ]0007E318 ã .
0007E2F8 |4EC9E783 ƒçÉN RETURN to gdiplus.4EC9E783



(Again, but more details):

0007E294 B90105D5 Õ¹
0007E298 00000000 ....
0007E29C 00000000 ....
0007E2A0 00000000 ....
0007E2A4 003B4108 A;.
0007E2A8 018E0F08 Ž
0007E2AC 003B5108 Q;.
0007E2B0 003B0000 ..;.
0007E2B4 0007E0AC ˆ .
0007E2B8 00000000 ....
0007E2BC 0007ED40 @í .
0007E2C0 7C90E900 .é�| ntdll.7C90E900
0007E2C4 7C9101C0 À‘| ntdll.7C9101C0
0007E2C8 FFFFFFFF ÿÿÿÿ
0007E2CC 7C9101BB »‘| RETURN to ntdll.7C9101BB from ntdll.7C90E8E6
0007E2D0 4EC5221F "ÅN RETURN to gdiplus.4EC5221F from ntdll.RtlAllocateHeap
0007E2D4 003B0000 ..;.
0007E2D8 40000060 `..@
0007E2DC 0000001C ...
0007E2E0 0007E2F0 ðâ .
0007E2E4 4EC9DD15 ÝÉN RETURN to gdiplus.4EC9DD15 from gdiplus.4EC52209
0007E2E8 0000001C ...
0007E2EC 00000006 ...
0007E2F0 000091F7 ÷‘..




Below is a snapshot of our stack after the overflow occurs:

ESP+4 > 003B4108 A;.
ESP+8 > 018E0F08 Ž
ESP+C > 003B5108 Q;.
ESP+10 > 001D0B0B .
ESP+14 > 001D0B0B .
ESP+18 > 001D0B0B .
ESP+1C > 001D0B0B .
ESP+20 > 001D0B0B .
ESP+24 > 001D0B0B .
ESP+28 > 001D0B0B .
ESP+2C > 001D0B0B .
ESP+30 > 001D0B0B .
ESP+34 > 001D0B0B .
ESP+38 > 001D0B0B .
ESP+3C > 001D0B0B .
ESP+40 > 001D0B0B .
ESP+44 > 001D0B0B .
ESP+48 > 001D0B0B .
ESP+4C > 001D0B0B .
ESP+50 > 00000000 ....
ESP+54 >/0007E318 ã .
ESP+58 >|4EC9E783 ƒçÉN RETURN to gdiplus.4EC9E783



After our function has completed, an internal gdiplus function looks for stack corruption. At 0x4ECFDA78, GdiPlus sets our unhandled exception filter to zero (clears it) and then calls our unhandled exception filter, then immediately terminates the process. This is the standard process for handling detected stack overflows.

CALL gdiplus.4ECFD994 Cookie Security Check


Thanks,

- redsand


Example .EMF File can be found here

http://milw0rm.com/sploits/2009-voltage-exploit.emf


 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Adobe Acrobat Reader JBIG2 Uni
·Femitter FTP Server 1.x Multip
·Free Arcade Script 1.0 Auth By
·IncrediMail 5.86 (XSS) Script
·Syzygy CMS 0.3 LFI/SQL Command
·ECShop <= v2.6.2 SQL injection
·POP Peeper 3.4.0.0 .html file
·Mozilla Firefox XSL Parsing Re
·POP Peeper 3.4.0.0 .eml file U
·PHPizabi v0.848b C1 HFP1-3 Rem
·Telnet-Ftp Service Server v1.x
·Codice CMS 2 Remote SQL Comman
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved