CVE Certified

Fuzzing vs Reversing – Round #1 (Fuzzing)

22nd November 2010 - by zelik

I have recently been doing some fuzzing on the Adobe Flash Player. I started by implementing a simple format fuzzer for Flash based on a homegrown framework that I have been developing for awhile. I implemented and executed tests and progressively covered more and more of the format. After a few days, I noticed one of the SWF files causing strange crashes, the “Just in time” debugger gets triggered but the process is terminated.

FontNameCrash

Note: The debugging process has taken place under a Windows XP SP2 machine with Adobe Flash 10.1.85.3 installed. During the debugging process we debugged Internet Explorer while it was rebased to the address 03281000.

I started debugging it for awhile and saw that there was an off-by-one vulnerability in one of the functions responsible for parsing the “DefineFont2” tag’s data. The vulnerability is not as straight-forward as it may seem, however. The main function that parses “DefineFont2” is parsing the entire tag correctly, as the data propagate and the font we defined is rendered for use, the vulnerability occurs. The tag “DefineFont2” allows us to specify a font-name with the size of up-to 0xFF bytes. The “DefineFont2” tag’s format is as follows:

DefineFont2Format

After the initial processing of the “DefintFont2” tag, the function at 032ACB45 “CopyFontName” allocates a new buffer to store the font-name parameter it received. The buffer is allocated by calling the function “AllocateBuffer” at the address 032CA7FE.

Note: The function “AllocateBuffer” is wrapped by another function. The call is indirect but for the sake of simplicity, we modified the listing to show a direct call.

.text:032ACB45  CopyFontName
...
.text:032ACB68      push    [esp+0Ch+FontName]
.text:032ACB6C      jge     short loc_32ACB79
.text:032ACB79  allocateFontName:
.text:032ACB79      lea     esi, [edi+10h]
.text:032ACB7C      mov     ecx, esi
.text:032ACB7E      call    AllocateBuffer ; // AllocateBuffer(Buf, FontName);
.text:032ACB83      mov     ecx, esi
.text:032ACB85
.text:032ACB85  terminateFontName:
.text:032ACB85      push    80h
.text:032ACB8A      call    NullTerminate ; // NullTerminate(Buf, 0x80);
.text:032ACB8F      mov     ecx, edi
.text:032ACB91      call    sub_32ACA47
.text:032ACB96      pop     edi
.text:032ACB97      pop     esi
.text:032ACB98      pop     ebx
.text:032ACB99      retn    8

AllocateBuffer” allocates a new buffer at the size of the given string. (This buffer will be used to overflow the stack with an off-by-one vulnerability later-on)

.text:032CA609  AllocateBuffer

.text:032CA61C      lea     edx, [eax+1]
.text:032CA61F
.text:032CA61F  loc_32CA61F:
.text:032CA61F      mov     cl, [eax]
.text:032CA621      inc     eax
.text:032CA622      test    cl, cl
.text:032CA624      jnz     short loc_32CA61F
.text:032CA626      sub     eax, edx
.text:032CA628      jmp     short loc_32CA62C

This part of the function calculates the length of the given string; it is equivalent to the following code:

length = strlen(string); // The length is EAX

After the length of the string is calculated, the function allocates a buffer at the proper size and copies the contents of the string onto the buffer. When “AllocateBuffer” returns, “CopyFontName” calls “NullTerminate with the constant parameter of 0×80 to limit the buffer size to no more than 0×80.
Later on, the buffer that we allocated gets copied to a stack buffer during the execution of the function “Overwrite” (03426283). This function has a stack buffer with the size 0×80 to copy the string into. The problem is that the string size is 0×80 + a null terminator (which is actually 0×81). The function copies the string using the following compiler-generated code:

.text:03426372  StringCopy:
.text:03426372      mov     cl, [eax]
.text:03426374      mov     [edx+eax], cl
.text:03426377      inc     eax
.text:03426378      test    cl, cl
.text:0342637A      jnz     short StringCopy

This code fragment first copies a character and only then checks if that character is a null (as most string copy functions do). The result is a classic off-by-one vulnerability that results in the overwrite of a single byte of the stack cookie with null. This condition is not exploitable under the windows platform and it causes the browser to crash while failing the stack-cookie test.

(Btw, this vulnerability is currently a zero-day as far as i know)

About the Author

Tal Zeltzer (zelik) is a security researcher from Israel, focusing on reverse engineering both software and hardware. He spends most of his free time developing private security tools and exploits for fun.