Friday, April 20, 2012

Microsoft Incremental Linker Integer Overflow

In this post i will be talking about an integer overflow vulnerability that i have found in Microsoft Incremental Linker (link.exe) of Visual Studio 2008. I am still not aware of any other affected versions.

The integer overflow occurs due to unsafe way of calculating the size of COFF symbol tables embedded in executables.

The "ReadStringsAndSymbols" function is always called to parse the COFF symbol table if  the "PointerToSymbolTable" and "NumberOfSymbolsfields of the  IMAGE_FILE_HEADER structure are not null.


The C code for the function in the image above looks something like this.

As you can see in the image above, the "ReadStringsAndSymbols" function calls the "LoadStrings" and "ReadSymbolTableEx" functions. The "LoadStrings" function is prone to an integer overflow when calculating the end address of the symbol table but it is not the one of interest since it is only used in subsequent calls to the "PbMappedRegion" function for ensuring that symbol table is within boundaries of the mapped view of the input file.
The "ReadSymbolTableEx" function calls the "ReadSymbolTableT" function to calculate the absolute address of the symbol table in the mapped view. Upon return of the "ReadSymbolTableT" function, the "ReadSymbolTableEx" function calculates the size of symbol table in an unsafe manner. See the images below.

The size value is then passed to the "AllocBlk" function, which, as its name implies, allocates memory from heap by calling the "RtlAllocateHeap" function. One more thing to mention about the "AllocBlk" function is that if the size value is less than or equal to 0x400 bytes, it allocates 0x400 bytes. For example, if the "NumberOfSymbols" field is 0x8000000C, it will be truncated to 0xF0 and 0x400 bytes will be allocated.

After memory has been allocated, the "ConvertRgImgSymToRgImgSymEx" function is called with the first parameter set to the number of symbols and the second parameter to the address of the newly allocated memory. Inside the "ConvertRgImgSymToRgImgSymEx" function is a loop that copies data to the newly allocated memory.


Carefully choosing the input file size, "PointerToSymbolTable", and "NumberOfSymbols"  values, we can easily corrupt the heap in a way that allows code execution.

One important thing to add about this vulnerability is that invoking the famous dumpbin utility shipped with Microsoft Visual Studio always ends up with invoking link.exe (link.exe /dump).

Here is a screenshot of a malicious file.
You can follow me on Twitter @waleedassar

Tuesday, April 10, 2012

OllyDbg NumberOfSections Crash

In this post i will be discussing another bug that i found in OllyDbg. The idea came to my mind while debugging link.exe shipped with Microsoft Visual Studio 2008.

Debugging link.exe, i was amazed to see that the maximum number of sections that a PE file can hold is 0xFEFF sections (as assumed by link.exe) not 96 (0x60, hex). In the beginning, i thought that i have an old PE/COFF documentation or that it is a mistake since the documentation says "the Windows loader limits the number of sections to 96".

By creating a PE file with 97 sections, i found out that the 96-section limit applies to Windows XP but not to Windows 7, 64-bit.
I quickly asked myself  "How will Olly Handle that?!!!".

Quickly opened Olly to debug another instance of it and went to the PE parsing code. See the image below.
As you can see in the image above, Olly takes 0x1FFF (8191, decimal) as the maximum number of sections. That's Cool!!
The C code looks something like this. See the image below.

As you can see, if we give it an executable with 0x2000 (8192, decimal) sections or more, Olly will crash.

Here you can find a Proof Of Concept.

Material in this post has been tried on Windows 7, Wow64 and OllyDbg v1.10. I will be glad if someone gives it a shot on Windows 7, 32 bit or Windows Vista.

Update:

Summary:
1) Maximum number of sections that PE loader of Windows XP supports is 0x60 (96, decimal).
2) Maximum number of sections that PE loader of Windows Vista and later supports is 0xFFFF.
3) Maximum number of sections that OllyDbg v1.10 supports is 0x1FFF (8191, in decimal).
4) Maximum number of sections that link.exe (dumpbin.exe) of Visual Studio 2008 supports is 0xFEFF.

You can follow me on Twitter @waleedassar