A benefit of working for a company like Core Security (working at a company that turns out cutting-edge research, ground-breaking products, and commercial-grade exploits) is that people assume I am as intelligent as the people who actually produce the cutting-edge research, ground-breaking new products and commercial-grade exploits. I'll try and maintain the illusion as long as I can but inevitably the truth will come out.

More often than I care to admit, I am humbled by the abilities of the folks on our Exploit Writing Team (EWT), our testing teams, and our engineering teams. Their technical capabilities are most obvious when you look at how the EWT is able to take a patch and turn it into a working exploit. When a vendor releases a patch, they want to arm the people who need to apply the patch but minimize the amount of information that someone seeking to leverage the patch and create an exploit has to work with - this puts deliberate roadblocks in front of those people.

This post is all intended to walk you through this process, so at this point I want to pass things across to my colleague Nicolas Economou, and have him take us through the work he did taking the release of the MS11-056 patch: identifying the vulnerability that was being patched and then developing a commercial-grade exploit for it. I think, like me, you will gain a deeper appreciation for the work that goes into creating the over 2,300 (at time of writing) commercial-grade exploits provide with Core's security testing products.

-- Alex Horan, CORE IMPACT Product Manager

Exploiting a New Vulnerability with and Old-School Exploit

As Alex said my name is Nicolas Economou and I work for Core Security as a Senior Exploit Writer. I got together with Alex to write this post as I wanted to tell you about how I used an "alleged" violation of the "Windows XP SP3" and "Windows 2003 sP2" memory protection mechanism to exploit a bug in the "csrss.exe" process recently published. And how in doing so I managed to take a new vulnerability and exploit it using an Old-School Exploit...

What do I mean by an Old-School Exploit? Well, usually we when we see viruses or exploits in movies being used by "hackers" to attack computers the colors on the victims screen change and everything that was on the screen turns into a skull or something along those lines. In the real world, on the other hand, when a virus or an attacker decides to take over a computer, a lot of effort is taken to help ensure the user is unaware that they are a victim.

I'm going to talk about how fiction and reality converged and how the computer screen itself was used to exploit a bug in MS11-056 ;-)

Patch Tuesday:
As you know, the second Tuesday of each month Microsoft publishes updates for its products; and we typically refer to this day as "Patch Tuesday". In July Microsoft published its patches on July 12 -http://www.microsoft.com/technet/security/bulletin/ms11-jul.mspx

Four patches were released:

  • MS11-053: Vulnerability in Bluetooth Stack Could Allow Remote Code Execution (2566220)
  • MS11-054: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Elevation of Privilege (2555917)
  • MS11-055: Vulnerability in Microsoft Visio Could Allow Remote Code Execution (2560847)
  • MS11-056: Vulnerabilities in Windows Client/Server Run-time Subsystem Could Allow Elevation of Privilege (2507938)

When the patches were released I reviewed them and I decided to dive into the patch released for the bug MS11-056 which itself fixed 5 bugs located in the "Client/Server Run-time Subsystem" which is more commonly known as "CSRSS".

The vulnerabilities fixed were:

  • CSRSS Local EOP SrvWriteConsoleOutputString Vulnerability - CVE-2011-1870
  • CSRSS Local EOP AllocConsole Vulnerability - CVE-2011-1281
  • CSRSS Local EOP SrvSetConsoleLocalEUDC Vulnerability - CVE-2011-1282
  • CSRSS Local EOP SrvSetConsoleNumberOfCommand Vulnerability - CVE-2011-1283
  • CSRSS Local EOP SrvWriteConsoleOutput Vulnerability - CVE-2011-1284

What is the CSRSS ?
According to Microsoft, the csrss.exe process is: "The Client/Server Run-time Subsystem (CSRSS) is the user-mode portion of the Win32 subsystem (with Win32.sys being the kernel-mode portion). CSRSS is an essential subsystem that must be running at all times. CSRSS is responsible for console windows, creating and/or deleting threads."

Starting my work, a.k.a Binary Diffing:
Once the "Windows XP SP3" update was downloaded, I decompressed the patch and found that it contained two files:

  • csrsrv.dll
  • winsrv.dll

Diffing the last version of "winsrv.dll" against the new version ( "v5.1.2600.6001" VS "v5.1.2600.6104" ) I found that 7 functions had changed:

  • ReallocCommandHistory
  • SrvReadConsole
  • SrvAllocConsole
  • SrvSetConsoleLocalEUDC
  • SrvGetConsoleCommandHistory
  • SrvWriteConsoleOutput
  • SrvReadConsoleOutputString

Looking at the "exploitability index" published by Microsoft, I noticed that only 2 of 5 patched bugs were rated as severity type 1 ( Consistent exploit code likely ) on their current platforms.

  • CSRSS Local EOP SrvSetConsoleNumberOfCommand Vulnerability - CVE-2011-1283
  • CSRSS Local EOP SrvWriteConsoleOutput Vulnerability - CVE-2011-1284

Once the comparison was made, the changes in the binaries were checked and based on my experience and understanding of the Microsoft exploitability index I decided to focus on a bug located in one of these vulnerabilities: "SrvSetConsoleNumberOfCommand Vulnerability - CVE-2011-1283".
The investigation

I wanted to determine what was patched in to eliminate the  "SrvSetConsoleNumberOfCommand" Vulnerability - CVE-2011-1283. Internally "winsrv.dll" has a function with the same name as the bug

Difference between the patched and unpatched functions. Difference between the unpatched (left) and patched (right) functions.

description "SrvSetConsoleNumberOfCommand" but curiously, it isn't in the changed function list.

However I was able to determine that a child function of SrvSetConsoleNumberOfComm

and had been changed: "ReallocCommandHistory". The patch was very simple, Microsoft decided to reject all "console command history" length values greater than 32,768 ( 0x7fff ).

A simple way to change the command history length is to go to the console properties and change it in the "command history" box.

Exploiting the bug
Once the bug is triggered and some obstacles are bypassed (This is the place in the movie with the hacking montage...) ;-) it is possible to take control of the csrss.exe execution through the "CALL DWORD PTR [EAX+2Ch]" instruction located in "CookedReadWaitRoutine".

This instruction ends up reading data beyond the limits of the struct allocated for the same process, where its content can be filled with some heap spray technique. I still haven't found a reliable way to fill this memory area with ANSI values ( 0xNNNNNNNN ) but I did find a way to fill the memory with UNICODE values ( 0x00NN00NN ).

There aren't many options, I can only redirect "EIP" ( instruction pointer ) to the addresses range between 0x00000000 to 0x00FF00FF ...

Where Can I Jump ?
Looking at the memory map of the CSRSS process, I found a 1 MB memory area located from the 0 address.

Except for the "ntvdm.exe" process, this is the only process that has this address mapped.

What is this area ?

Dumping the content of this memory area I found 16 bits code. The distribution of the executable code can be found in the same way as in REAL MODE ( used by DOS ).

Doing some old school research (I used a book), I found that the first megabyte was divided as follows:

0000:0000 - a000:0000 = Conventional memory area ( 640kb )
a000:0000 - b000:0000 = Graphic memory area ( 64 kb )
b000:0000 - c000:0000 = Text memory area ( 64 kb )
c000:0000 - d000:0000 = Hard Disk ROM ( 64 kb )
d000:0000 - e000:0000 = Extended Memory Page Frame ( 64 kb )
e000:0000 - f000:0000 = Free ( 64 kb )
f000:0000 - ffff:0000 = BIOS ( 64 kb )

Translating the addresses of the CSRSS memory map, the table looks like:

0x00000 - 0xa0000 = Conventional memory area ( 640kb )
0xa0000 - 0xb0000 = Graphic memory area ( 64 kb )
0xb0000 - 0xc0000 = Text memory area ( 64 kb )
0xc0000 - 0xd0000 = Hard Disk ROM ( 64 kb )
0xd0000 - 0xe0000 = Extended Memory Page Frame ( 64 kb )
0xe0000 - 0xf0000 = Free ( 64 kb )
0xf0000 - 0xfffff = BIOS ( 64 kb )

It's well known that, in REAL MODE ( 16 bits mode ), all the memory was executable, so the "IP" register ( INSTRUCTION POINTER ) could be redirected wherever we want.
We could execute code at 0000h:1000h or F000:3333h.

Looking at the first megabyte protections of the csrss.exe memory map I found something very unusual ...

CSRSS.EXE - Memory Protections:
Printing the memory attributes values I found this:

*BASE    *LEN   *ATTRIBUTES
00000000 0a0000 EXECUTE_READWRITE
000a0000 020000 READWRITE NOCACHE
000c0000 00d000 READWRITE
000cd000 013000 EXECUTE_READWRITE
000e0000 020000 READWRITE

In some way, Microsoft tried to keep the CSRSS first megabyte as executable, like REAL MODE ( 16 BITS ), with some exceptions.

The memory pages used by the VGA video board ( 128 kb ) have "READWRITE NOCACHE" attributes, they don't have execution privileges, or maybe they do ...

VGA memory area ( 0xa0000 - 0xc0000 ):
The "csrss.exe" process uses this memory area when the console is running in full-screen mode.

When the screen is in this mode, all characters showed by the screen are mapped from the address 0xb8000.
This memory area ( B800:0000 ) is used by many video modes supported by the BIOS. Among the more common video modes we found "mode 3" ( text mode 80 x 25 ). Another well-known mode was "mode 13h" ( graphic mode 320 x 200 ).

From an exploit writer's point of view, this is an interesting way to do heap spray in the "csrss.exe" process, since from a process using a full-screen console it would be easy to write in the memory screen using any API written for this purpose ( eg. "WriteConsole()" ).

So, my next question was what would happen if "EIP" is redirected to the 0xb8000 address? or Is the CSRSS "VGA memory area" executable ?

For some reason I don't fully understand ( although I can made a few assumptions ), the CSRSS VGAmemory area is executable.

It's easy to prove:
1. Execute a program running into a full-screen console on "Windows XP SP3" that prints a message on the screen using "printf()".

Printing to Full Screen` Printing to Full Screen

2. Attach "kd.exe" ( Kernel Debugger ) to the virtual machine and then, set the debugger context to csrss.exe process.

Then, check the result:

Debugger output Debugger output

3. If we dump the memory from the address 0xb8000, we can see that the screen memory area is mapped here.
The format of the screen characters are made up by couples of characters + attributes.

4. Set "EIP" value pointing to the VGA text area ( 0xB8000 ).
We can see that the string "testing the screen" is disassembled as instructions.

Our string is now seen as instructions Our string is now seen as instructions

5. Finally, execute one instruction:

Executing an instruction Executing an instruction

We can see that, the instruction "JZ 0xB8009" was executed and now, "EIP" is pointing to the next instruction. In the same way that the screen characters can be executed, the video mode could be changed to 13h ( graphic mode 320 x 200 ) and screen pixels could be executed :-) This means that, the memory area used by the csrss.exe process to show characters or pixels in the screen is executable ( like the old times ! ).

Exploit Video
The real exploit of this vulnerability using Core Impact can be seen in this video. It's launched against "Windows XP SP3" running into a VMware Workstation. The screen is written with the shellcode of the Core Impact agent and the rest of the screen is filled with a Logo made in ASCII. Once the screen is drawn, a 16 bit program dumped by the same exploit is executed. This 16 bit program calls to "INT 10h" of the BIOS and changes the video mode to 7.

After that, the console mode is changed to full-screen. When it happens, the memory area 0xB0000 of the csrss.exe process is filled with the content of the original console ( before normal size ). There is a short delay and then, the console is changed to its previous size. In the end, two invalid commands are executed, finalizing the exploit redirecting the CSRSS process execution to the address 0xB0000 :-)

 

Conclusions
This "issue" allows us to exploit bugs in the CSRSS process in "Windows XP SP3/Windows 2003 SP2" in a %100 reliable way, writing in full-screen mode as a heap spray technique, while bypassing DEP ( NX bit ), because the VGA memory area ( the screen ) is executable.

On subsequent Windows versions, the mapping of the first megabyte on csrss.exe was deprecated.

On Windows 7 and Windows 2008 the full-screen mode was supressed.

Thanks to:
- Diego Juarez ( PNX ): Video mode 7 and Core Logo.
- David Weil ( Tenuki ): 16 bit Resident programs and Character Encodings.

-- Nicolas Economou, Senior Exploit Writer