TippingPoint Digital Vaccine Laboratories
DID YOU KNOW... The DVLabs research team discovered 10 unique Adobe Shockwave vulnerabilities during October and November of 2010.

MindshaRE: MSEC !exploitable

Amongst the talks on Laser Snooping, Mac Hacking, MD5 collisions, and contest like the Pwn2Own at last weeks CanSecWest security conference was a presentation by Microsoft engineers Jason Shirk & Dave Weinstein titled "Automated Real-time and Post Mortem Security Crash Analysis and Categorization". The presenters unveiled their new WinDbg plugin that allows a user to determine the exploitability of a crash without the need for much experience or hours of investigation. Today we are going to take a look at this plugin and get our !exploitable on.

MindshaRE is our bi-weekly look at some simple reverse engineering tips and tricks. The goal is to keep things small and discuss every day aspects of reversing. You can view previous entries here by going through our blog history.

First off, determining exploitability takes time and skill. In some cases it takes more time than skill, or vice-versa. We see this problem all of the time when verifying cases for the ZDI. We may receive a submission where an access violation happens on a read at address 0x0000000. In 90% of cases this is unexploitable after verifying that the address of the read is not user controllable and does not have a negative side effect. This kind of analysis can take anywhere from 1 minute to several days based on the complexity of the software, and vulnerability. This is where Microsoft has stepped in to offer some help.

This new MSEC extension provides the !exploitable command for users of WinDbg. The command uses a defined rule set to determine the severity of a crash by processing the information post-mortem. It achieves this by processing meta-instructions such as a branch, data move, return, etc. The rule may ask "Is the faulting instruction a read violation of EIP?". If the answer is yes, it calls it a day and labels it exploitable. The details of the design can be found in the presentation slides here. Let's look at an example of the plugin.
0:000> g @@masm(`c:\test\call_taint.c:26+`)
ModLoad: 5cb70000 5cb96000   C:\WINDOWS\system32\ShimEng.dll
eax=00033258 ebx=0013ff78 ecx=00000000 edx=0041c4f0 esi=00fcf762 edi=00fcf6f2
eip=00401030 esp=0013ff68 ebp=0013ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
call_taint!main+0x20:
00401030 8b55fc          mov     edx,dword ptr [ebp-4] ss:0023:0013ff74=41414141
0:000> t
eax=00033258 ebx=0013ff78 ecx=00000000 edx=41414141 esi=00fcf762 edi=00fcf6f2
eip=00401033 esp=0013ff68 ebp=0013ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
call_taint!main+0x23:
00401033 ffd2            call    edx {41414141}
0:000> t
eax=00033258 ebx=0013ff78 ecx=00000000 edx=41414141 esi=00fcf762 edi=00fcf6f2
eip=41414141 esp=0013ff64 ebp=0013ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
41414141 ??              ???
0:000> t
(ca0.79c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00033258 ebx=0013ff78 ecx=00000000 edx=41414141 esi=00fcf762 edi=00fcf6f2
eip=41414141 esp=0013ff64 ebp=0013ff78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
41414141 ??              ???
0:000> !MSEC.exploitable -v
HostMachine\HostUser
Executing Processor Architecture is x86
Debuggee is in User Mode
Debuggee is a live user mode debugging session on the local machine
Event Type: Exception
Exception Faulting Address: 0x41414141
First Chance Exception Type: STATUS_ACCESS_VIOLATION (0xC0000005)
Exception Sub-Type: Read Access Violation

Exception Hash (Major/Minor): 0x2b214251.0x1a224251

Stack Trace:
Unknown
call_taint!main+0x25
call_taint!__tmainCRTStartup+0xfb
kernel32!BaseProcessStart+0x23
Instruction Address: 0x41414141

Description: Read Access Violation at the Instruction Pointer
Short Description: ReadAVonIP
Exploitability Classification: EXPLOITABLE
Recommended Bug Title: Exploitable - Read Access Violation at the Instruction Pointer 

starting at Unknown Symbol @ 0xfce1dcffff000a

(Hash=0x2b214251.0x1a224251)

Access violations at the instruction pointer are exploitable if not near NULL.
In this example I have written a test that overwrites a register being used in a call. When the access violation occurs I issue the !MSEC.exploitable -v command. The verbose output of this command shows the meta-info from the crash after processing the offending function and register state. Of importance is the "Short Description", "Exploitability Classification", and "Recommended Bug Title". Here, the plugin does a fantastic job of calling this one exploitable, or does it?

In reality this bug is not exploitable. Here is the assembly.
_declspec(naked) int main()
{
    _asm
    {
        push ebp
        mov ebp, esp
        sub esp, 0x10
        mov dword ptr [ebp-4], 0x0
        
      pre:
        mov ecx, 0x10
        lea ebx, [ebp-0x10]

      cpy_loop:
        test ecx, ecx
        jz kill
        mov byte ptr [ebx], 0x41
        dec ecx
        inc ebx
        jmp cpy_loop
        
      kill:
        mov edx, dword ptr [ebp-4]
        call edx
        mov esp, ebp
        pop ebp
        retn 0x10
    }
}
The problem is the lack of user input. In my opinion, this is the most necessary question in "exploitability", and the one Microsoft themselves claim is a fundamental limitation. Their assumption is any register in the faulting instruction is user controllable. While this is a good stance to take, it is a bit misleading.

Lets take a look at another example.
_declspec(naked) int main()
{
    _asm
    {
        push ebp
        mov ebp, esp
        sub esp, 0x10
        mov dword ptr [ebp-4], 0x21212121
        mov edx, dword ptr [ebp-4]
        mov ebx, dword ptr [edx]
        mov esp, ebp
        pop ebp
        retn 0x10
    }
}
As you can see, this is not exploitable. What does !exploitable say?
(5e4.918): Access violation - code c0000005 (!!! second chance !!!)
eax=00033258 ebx=7ffd5000 ecx=00000001 edx=21212121 esi=0127f766 edi=0127f6f2
eip=00401020 esp=0013ff68 ebp=0013ff78 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
read_untaint!main+0x10:
00401020 8b1a            mov     ebx,dword ptr [edx]  ds:0023:21212121=????????
0:000> !MSEC.exploitable -v
HostMachine\HostUser
Executing Processor Architecture is x86
Debuggee is in User Mode
Debuggee is a live user mode debugging session on the local machine
Event Type: Exception
Exception Faulting Address: 0x21212121
Second Chance Exception Type: STATUS_ACCESS_VIOLATION (0xC0000005)
Exception Sub-Type: Read Access Violation

Faulting Instruction:00401020 mov ebx,dword ptr [edx]

Basic Block:
    00401020 mov ebx,dword ptr [edx]
       Tainted Input Operands: edx
    00401022 mov esp,ebp
    00401024 pop esp
    00401025 ret 10h
       Tainted Input Operands: edx

Exception Hash (Major/Minor): 0x72653670.0x5d651c5a

Stack Trace:
read_untaint!main+0x10
read_untaint!__tmainCRTStartup+0xfb
kernel32!BaseProcessStart+0x23
Instruction Address: 0x401020

Description: Data from Faulting Address may be used as a return value
Short Description: TaintedDataReturnedFromFunction
Exploitability Classification: UNKNOWN
Recommended Bug Title: Data from Faulting Address may be used as a return value 

starting at read_untaint!main+0x10 (Hash=0x72653670.0x5d651c5a)

The data from the faulting address may later be used as a return value from this function.
Hrmm UNKNOWN? Now what?

The more crashes I look at with this plugin the more I understand its goal. The goal is to raise the attention of a developer that has little security knowledge regarding exploitation. In almost all cases I see an "UNKNOWN", "PROBABLY_EXPLOITABLE", or "EXPLOITABLE" label outputted by the plugin. While I agree with the approach of erring on the side of EXPLOITABLE, I also think it may lead to an influx in false positives. Microsoft themselves even claim "The lightweight flow analysis and the above assumption can result in over-assessing risk".

I applaud the work the security science team at Microsoft has done. The plugin design is impressive, including a functional meta-language and rule set. The problem is when the output is considered reliable as one media outlet claims. I hope the tool does not lead to an influx of "But !exploitable said its exploitable" or even worse "!exploitable said it is not exploitable". In the plugins current state I do not believe this tool saves security researchers time. Hopefully as the tool matures and more rules are added it becomes a goto plugin for determining exploitability.

As always feel free to leave your thoughts.

-Cody

 
Tags:
Published On: 2009-03-26 14:52:18

Comments post a comment

  1. Anthony Towry commented on 2009-05-29 @ 09:50

    Great article. I just recently tried the MSEC bang exploitable extension.

    My situation was that I had found a bug, it wasn't obviously exploitable from the outset, and I thought maybe !exploitable would give me a good second opinion.

    I loaded the extension and ran the crash analysis and it came back EXPLOITABLE. Further investigation reaffirmed it was not.

    I think your spot on with this post. !exploitable wasn't built to help security researchers and it absolutely doesn't, at least from what I can tell with my very limited exposure. It's there for organizations that want to improve their SDLC (God love 'em) and that's just about it.

  2. Cody Pierce commented on 2009-06-03 @ 18:40

    @Anthony Towry:

    Yes. !exploitable is fantastic if you are in a large development organization having to prioritize bugs. However, as you stated, it is of minimal use to security researchers. My main fear is the use of !exploitable to hype 0day vulnerabilities that may be harmless.


Trackback