Flag: Tornado! Hurricane!

Process Stalker vs. MS05-030

Wednesday, July 6 2005 09:26.04 CDT
Author: pedram # Views: 51610 Printer Friendly ...


In this article we will walk through the re-discovery of the MS05-030 Microsoft Outlook Express NNTP Response Parsing Buffer Overflow Vulnerability using Process Stalker. For this article the target used is a pre MS05-030 patched Windows XP SP1 box with Outlook Express version 6. The specific version of MSOE.DLL used is 6.0.2800.1437.

First, a quick overview of Process Stalker (Note: Process Stalker has since been deprecated by PaiMei). Process Stalker is broken into three main components; an IDA Pro plug-in (commercial version required), a stand alone tracing tool and a series of Python scripts for instrumenting intermediary and graph files. The generated GML graph definitions were designed for usage with the freely available interactive graph visualization tool, Oreas GDE Community Edition. The graphing application has both Unix and Windows native installs. It's a wonderful graphing package that took me hours of Google-ing to find. I don't know why I didn't come across it sooner.

Getting Started

To begin, load MSOE.DLL into IDA. Once IDA's auto-analysis is complete, launch the Process Stalker plug-in by hitting the hotkey Alt + 5 or by selecting it from the Edit -> Plugins menu. The following dialog should appear:

Process Stalker IDA plug-in dialog

The default options are sufficient for our current purposes. The "Enable Instruction Color" option controls whether or not the plug-in should generate colored instructions. Disable this for increased performance on large graphs. The "Enable Comments" option can also be disabled for increased performance. The "Allow Self Loops" option is best left unchecked as the orthogonal layout is not available in graphs that contain self loops. Hit OK and select a target directory to output generated files to. Do not worry about the filename entry, the filename is stripped so anything will suffice. The plug-in can take some time when analyzing the binary and will output the following messages in the IDA log window:

    [*] pStalker> Profile analysis 25% complete.
    [*] pStalker> Profile analysis 50% complete.
    [*] pStalker> Profile analysis 75% complete.
    [*] pStalker> Profile analysis 100% complete.

The plug-in generates a breakpoint list which is used by the tracer to generate recordings (more on this later), a cross reference list which is used in some graph generation and a .GML graph for each identified function in the binary. When viewed in Oreas GDE, the graphs are interactive, editable, sport instruction level coloring for easy reading and can be displayed with a number of layout algorithms such as hierarchical, orthogonal, symmetric, circular, etc... Entry points are highlighted in green, true/false branches are colored green/red accordingly and implicit edges (edges between nodes where there is no branch) are colored blue. For MSOE.DLL, we generated 4,769 .GML files and our breakpoint listing contains 58,164 entries. In total there is approximately 83 megs of generated data from the plug-in.

Stalking and Filtering

At this stage we are ready to attach to the target process and generate a recording. Copy process_stalker.exe and the generated breakpoint list (MSOE.DLL.BPL) to the Outlook Express directory, "c:\Program Files\Outlook Express". Next, get Outlook Express to connect to an NNTP server. This is easily done through the news:// URI in Internet Explorer, for this article I'll use news://forums.novell.com. Assuming you haven't changed the default URI handler, Outlook Express should launch and present the following dialog (don't click anything yet):

Outlook Express NNTP listing confirmation

The presentation of this dialog box is a major mitigating factor in this vulnerability. In the absence of this confirmation the issue could have been exploited by simply convincing a target user to connect to a malicious web site. 58,164 basic blocks is a lot of code to find a vulnerability in. Let's begin by filtering out the basic blocks / functions that are related to message handling loops and GUI driving code. To do so attach to the running Outlook Express process (MSIMN.EXE), disable breakpoint restoration and start recording immediately:

    C:\Program Files\Outlook Express> tasklist
    MSIMN.EXE   1708    Console 0   11,260 K
    C:\Program Files\Outlook Express>process_stalker.exe -a 1708 --one-time -r 0
    process stalker
    target: 1708
    processing breakpoints for module MSOE.dll at 00791000
    done. 57844 of 58164 breakpoints set.
    initial break, tid = 077c.
    commands: [h]   this screen                     [m] module list
              [0-9] enter recorder modes            [x] stop recording
              [v]   toggle verbosity
              [d]   detach (XP/2003 only)           [q] quit/close
    00798139 T:000003bc [R0] 007A676E push ebp
    00798139 T:000003bc [R0] 007A6856 test eax,eax
    00798139 T:000003bc [R0] 007A6886 cmp eax,0x2
    00798139 T:000003bc [R0] 007A688B push 0x88
    00798149 T:000003bc [R0] 007CC88E push 0x10

Note that we didn't need to specify a breakpoint list on the command line. Process Stalker will automatically search the current directory for a pertinent breakpoint list whenever it loads a module. Also note the [R0] in the breakpoint hit output specifying that we are in recorder #1. There are 10 available recording modes per session, labeled 0-9. You should see the screen scroll through some breakpoints and then stop. As we're not interacting with the process those breakpoints must have been related to a message handling loop. Now, click 'No' on the presented dialog and start interacting with the GUI. Go through the menu's, move the window around, click and right-click various buttons etc. As you move around you'll notice decreasing output from Process Stalker, eventually you will exhaust the breakpoints reachable through GUI interaction. When that occurs hit 'q' to quit Process Stalker and kill the debuggee. Two files were generated, 1708-regs.0 contains the register inspection metadata and 1708.0 is the recording that contains the list of breakpoints we hit during our stalk. We actually didn't need register metadata for this part of the analysis and could have disabled it's generation with the --no-regs command line option. Process the recording with the ps_process_recording utility. A normalized recording is generated for each thread, in this case we don't care to differentiate by thread so we concatenate them all into the file 'gui_hits':

    $ time ps_process_recording 1708.0
    real    0m0.599s
    user    0m0.380s
    sys     0m0.180s
    $ ls -1 1708.0.*
    $ cat 1708.0.00000* > gui_hits
    $ wc -l gui_hits
    4533 gui_hits

In total we hit 4,533 breakpoints. We can generate the list of functions associated with those breakpoints with the ps_recording_to_list command and filter them out of the original breakpoint list with the command ps_bp_filter:

    $ time ps_bp_filter msoe.dll.bpl msoe.dll.nogui `ps_recording_to_list gui_hits msoe.dll` out
    real    0m29.751s
    user    0m28.801s
    sys     0m0.260s
    $ wc -l msoe.dll.bpl msoe.dll.nogui
      58164 msoe.dll.bpl
      50185 msoe.dll.nogui
     108349 total

Excellent, we've filtered out nearly 8,000 breakpoints that are more then likely completely uninteresting. While there are still over 50,000 breakpoints remaining, keep in mind that not all of them will be related to the process space we are searching for vulnerabilities in (more on this later).

Stalking with a Finer Toothed Comb

With the GUI related breakpoints filtered out we can now trace the target application with a finer toothed comb to pinpoint the location of the vulnerability. Copy the new breakpoint list to the Outlook Express directory and re-stalk. Don't forget to rename it to msoe.dll.bpl, otherwise Process Stalker won't find it at run-time.

    C:\Program Files\Outlook Express> tasklist
    MSIMN.EXE   1792    Console 0   11,260 K
    C:\Program Files\Outlook Express>process_stalker.exe -a 1792 --one-time -r 0
    process stalker
    target: 1792
    processing breakpoints for module MSOE.dll at 00791000
    done. 49999 of 50185 breakpoints set.
    initial break, tid = 0778.
    commands: [h]   this screen                     [m] module list
              [0-9] enter recorder modes            [x] stop recording
              [v]   toggle verbosity
              [d]   detach (XP/2003 only)           [q] quit/close

You'll notice this time that no breakpoints are hit. At least not until we hit 'Yes' on the dialog. Start up your Ethereal (filter: src or dst port 119) and hit 'Yes' now. Once the list of newsgroups is retrieved you can quit Process Stalker and the debuggee by hitting 'q' again. Again two files are generated, 1792-regs.0 and 1792.0. Process them using the Process Stalker Python utilities.

    $ time ps_process_recording 1792.0
    real    0m0.597s
    user    0m0.420s
    sys     0m0.160s
    $ ls -1 1792.0.*
    $ wc -l 1792.0.0000058c-processed
    747 1792.0.0000058c-processed

Only one thread with 747 hit basic blocks to analyze this time, much more manageable then what we would have had to deal with sans filtering.


With a filtered recording and register inspection metadata in hand we can now generate visualizations for analysis. Let's begin with a graph of only the functions that were called during our last stalk:

    $ time ps_view_recording_funcs 1792.0.0000058c-processed > hitgraph.gml
    real    0m16.584s
    user    0m11.306s
    sys     0m0.250s

hitgraph.gml excerpt

The generated graph contains a total of 1,337 (this # wasn't made up) nodes, 1,944 edges and 91 clusters (functions). 747 of the basic blocks (nodes) were actually hit and therefore colored red. We can further decrease the number of basic blocks to for initial analysis by highlighting potentially "interesting" portions of the graph using the ps_graph_highlight utility:

    $ time ps_graph_highlight --nodes hit hitgraph.gml > hitgraph_hl.gml
    real    0m9.119s
    user    0m8.702s
    sys     0m0.170s

hitgraph_hl.gml excerpt

In this generated graph the purple nodes are those that Process Stalker considers potentially "interesting". The logic behind the highlighting is currently very basic but will be enhanced in the future. The '--nodes hit' command line option specifies that we are only interested in highlighting nodes that were hit during our stalk. We can specify 'missed' for nodes that were not hit or 'all' to highlight any nodes determined as possibly interesting. For this run we ended up with 26 purple nodes total.

Before we begin analyzing the highlighted basic blocks, let's add our captured register inspection metadata into the graph to ease data flow analysis:

    $ time ps_add_register_metadata 1792-regs.0 hitgraph_hl.gml > hitgraph_hl_regs.gml
    real    0m8.973s
    user    0m8.402s
    sys     0m0.200s

The Vulnerability

The combination of function filtering, control flow analysis and block-level highlighting doesn't leave us with much work. As it turns out, the 2nd of the 26 purple nodes (in natural reading order) is our MS05-030 vulnerability. The vulnerability exists in the 4-block sequence depicted in the following hitgraph_hl_regs.gml excerpt:

hitgraph_hl_regs.gml excerpt

The 'rep movsd ... movsb' instruction sequence is a typical inlined strncpy(EDI, ESI, ECX). The register inspection data tells us that ESI contains data from the heap, likely a heap buffer allocated to store data received from the network. This can be confirmed by viewing the data stream from Ethereal:
    200 Welcome to forums.novell.com (Twister v2.1.1.380)
    200 Welcome to forums.novell.com (Twister v2.1.1.380)
    215 NewsGroups Follow
    novell.community.applications.jboss 0000000015 0000000002 y
    novell.community.applications.openoffice.org 0000000199 0000000002 y
    novell.community.brainshare 0000013054 0000000002 y
    novell.community.certifications.cle 0000000225 0000000002 y

The ESI register points directly to the highlighted string above in the block the overflow occurs in. Above the purple node you will find a loop that calculates the length of a space delimited field which is used as the strncpy() copy amount (ECX = end of string (0x000CB13E) - start of string (0x000CB134) = 0xA = 10). The 4-block sequence can be roughly translated into the following C-code:
    // this is not the actual stack-layout of the target function.
    char  server_response[] = "0000000015 0000000002 y";
    char  buffer[16];
    char *cursor;
    int   length;
    for (cursor = server_response; cursor != NULL; cursor = CharNextA(cursor))
        if (FIsSpaceA(cursor))
    length = cursor - server_response;
    // 44-byte overwrite necessary to hit saved EBP/EIP (in our target DLL).
    strncpy(buffer, server_response, length);

We can now easily trigger the stack smash by writing a malicious server that responds with the example captured data while replacing the second field, 0000000015, with a long string of data.


With approximately 30 minutes of analysis the specifics of the vulnerability in question were pinpointed with the help of the filtering and highlighting features of Process Stalker. To following state map was generated using the ps_state_mapper utility to visually demonstrate the benefits of the filtering step:

MS05-030 Process Stalk: GUI vs non-GUI Functions

Note that the state map does not show the entire process space of MSOE.DLL (which is much larger), but rather only the process space reachable from the interactions outlined previously. The yellow nodes represent functions. The black region represents the process space that deals with the GUI handling code that we filtered out. The red region represents the process space wherein the vulnerability resides.

Downloads and Further Information

Process Stalker is available for download from http://www.openrce.org/downloads/details/171.
The slides for the Process Stalker presentation at RECON are available for download from http://www.recon.cx/recon2005/papers/Pedram_Amini/.
The usage manual and API documentation is available from my personal site at http://pedram.redhive.com/process_stalking_manual/
The visualization software used, Oreas GDE Community Edition, is a free download available from http://www.oreas.com.

Article Comments Write Comment / View Complete Comments

    Username Comment Excerpt Date
pedram Much appreciated, thanks. There are some bug fi... Tuesday, July 12 2005 11:18.52 CDT
fluxist I am very impressed with the Process Stalker to... Monday, July 11 2005 23:38.32 CDT

There are 31,310 total registered users.

Recently Created Topics
[help] Unpacking VMP...
Reverse Engineering ...
let 'IDAPython' impo...
set 'IDAPython' as t...
GuessType return une...
About retrieving the...
How to find specific...
How to get data depe...
Identify RVA data in...

Recent Forum Posts
Finding the procedur...
Question about debbu...
Identify RVA data in...
let 'IDAPython' impo...
How to find specific...
Problem with ollydbg
How can I write olly...
New LoadMAP plugin v...
Intel pin in loaded ...
OOP_RE tool available?

Recent Blog Entries
Breaking IonCUBE VM

Anatomy of a code tracer

IAT Patcher - new tool for ...

CryptoShark: code tracer ba...

Build a debugger in 5 minutes

More ...

Recent Blog Comments
nieo on:
IAT Patcher - new tool for ...

djnemo on:
Kernel debugger vs user mod...

acel on:
Kernel debugger vs user mod...

pedram on:
frida.github.io: scriptable...

capadleman on:
Using NtCreateThreadEx for ...

More ...

SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit