Saturday, August 23, 2008

Reversing COM components

There are many free tools available that could prove helpful for analyzing COM components. My favorites are COMRaider and Jose Roca's TypeLib Browser.

Those tools are good for a 1st pass analysis (like fuzzing or calling a specific method from a VBS script), but when it comes to have a look at the binary implementation itself, things become a little thougher...

There are some IDA Pro helpers (scripts and plugins) hanging around, but given the complexity of COM and C++ reversing, it remains quite hard to tell where the code is through static analysis only.

Then I stumbled upon this post (by WebSense) that gives a very easy way to locate all exported methods through the use of #import directive in Visual Studio. Since they only give away screenshots, here is the full piece of code that will retrieve the RVA of the first 10 methods of Flash plugin.

#include <windows.h>
#include <stdio.h>

// Note: this must be a CPP file to use #import directive
#import "C:\\WINDOWS\\SYSTEM32\\Macromed\\Flash\\Flash9e.ocx" no_namespace

int main() {

printf("Hello, world of COM!\n");


IShockwaveFlash *pShockwave=NULL;

HRESULT hr = CoCreateInstance( __uuidof(ShockwaveFlash),

if (hr==S_OK) {

DWORD dwVT=*(DWORD*)pShockwave;

for (int i=1;i<11;i++) {
printf("[%d] VA=%08x RVA=%08x\n",



return 0;

Sample output:

C:\>cl test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86

Copyright (C) Microsoft Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.


Hello, world of COM!
[1] VA=300b4ec2 RVA=000b4ec2
[2] VA=300b38a4 RVA=000b38a4
[3] VA=300b38b1 RVA=000b38b1
[4] VA=300bd353 RVA=000bd353
[5] VA=300b78b7 RVA=000b78b7
[6] VA=300b7d33 RVA=000b7d33
[7] VA=300cbe5c RVA=000cbe5c
[8] VA=300c7c34 RVA=000c7c34
[9] VA=300c7c46 RVA=000c7c46
[10] VA=300c7b9d RVA=000c7b9d

Beware: the COM component will be instanciated by this code. Do not try this on malicious code, unless you know what you are doing!

Monday, August 18, 2008

MS08-051 secrets

On August 12th, Microsoft released a flurry of Office security patches.

Among those patches is to be found MS08-051 / Q949785, a patch targeting all supported versions of PowerPoint and PowerPoint Viewer, excluding PowerPoint Viewer 2007 and PowerPoint 2008 for Mac.

According to the bulletin, this patch fixes at least 3 vulnerabilities, 2 of them being documented on Let's have a look at the first vulnerability, which is an integer overflow resulting in a heap overflow. At the time of writing, a vulnerable version (11.0.5703.0) of PowerPoint Viewer 2003 can be downloaded from Microsoft web site. The vulnerable code path can be found in this version:

.text:300F642C loc_300F642C:
.text:300F642C mov eax, [edi]
.text:300F642E mov ecx, [ebp+var_14]
.text:300F6431 mov ebx, [eax+ecx*4]
.text:300F6434 mov esi, [ebx+2] ; EBX is user-supplied length
.text:300F6437 test esi, esi
.text:300F6439 mov [ebp+var_20], ebx
.text:300F643C mov [ebp+var_1C], esi
.text:300F643F jz loc_300F6516
.text:300F6445 mov ax, [ebx]
.text:300F6448 and eax, 3FFFh
.text:300F644D push eax
.text:300F644E call _MsoPopinfoGet@4 ; MsoPopinfoGet(x)

If EBX==0xFFFFFFFF, this code will result in calling GlobalAlloc(0x00000001) and copying 0xFFFFFFFF bytes later on.

After patching PowerPoint Viewer 2003, the code looks like (thanks to PatchDiff ;):

.text:300DC0BC loc_300DC0BC:
.text:300DC0BC mov eax, [edi]
.text:300DC0BE mov ecx, [ebp+var_14]
.text:300DC0C1 mov ebx, [eax+ecx*4]
.text:300DC0C4 mov esi, [ebx+2]
.text:300DC0C7 test esi, esi
.text:300DC0C9 mov [ebp+var_24], ebx
.text:300DC0CC mov [ebp+var_20], esi
.text:300DC0CF jz loc_300DC1B2
.text:300DC0D5 cmp [ebp+var_18], esi
.text:300DC0D8 jb loc_300DC1DD
.text:300DC0DE mov ax, [ebx]
.text:300DC0E1 sub [ebp+var_18], esi
.text:300DC0E4 and eax, 3FFFh
.text:300DC0E9 push eax
.text:300DC0EA call _MsoPopinfoGet@4 ; MsoPopinfoGet(x)

End of the story ? Not quite ... There is at least another Microsoft product that shares the PowerPoint codebase: Microsoft Office Live Meeting Client 2007.

Since it has PowerPoint rendering capabilities, this client is bundled with "lmpptview.dll". Beta versions of this DLL are internally numbered "12.0.x", showing clear connection with Office 2007. As of RTM version, this DLL is now numbered "8.0.3029.0". However, the following code sequence can be found inside:

.text:004345FC loc_4345FC:
.text:004345FC mov ecx, [ecx]
.text:004345FE lea eax, [ecx+edx*4]
.text:00434601 mov edi, [eax]
.text:00434603 mov esi, [edi+2]
.text:00434606 test esi, esi
.text:00434608 jz short loc_434689
.text:0043460A cmp [ebp-14h], esi
.text:0043460D jb loc_439769
.text:00434613 movzx eax, word ptr [edi]
.text:00434616 sub [ebp-14h], esi
.text:00434619 and eax, 3FFFh
.text:0043461E push eax
.text:0043461F call mightbe_MsoPopinfoGet

My bet is:
  • Live Meeting client is not vulnerable to this flaw, because the codebase comes from PowerPoint Viewer 2007.
  • And PowerPoint Viewer 2007 has been patched against this flaw since the beginning, whereas PowerPoint 2007 "Gold" and SP1 have been left vulnerable.
Men, that was close...

Friday, August 08, 2008

Pentester trick #5: debugging without debugger

Having a debugger at hand is always useful in corner case pentesting (cf. bypassing Symantec password). However, even if OllyDbg is a light-weight, standalone debugger, it might not always be possible to install new applications on the target system (e.g. Citrix servers, Web kiosks, mission critical servers).

Fortunately, there is a built-in command-line debugger bundled with at least Windows 2000, XP and 2003 (this debugger has been removed from Windows Vista). And I am not talking about DEBUG.EXE ;) I am talking about NTSD.EXE, which is originally part of the Debugging Tools for Windows.

Warning: NTSD has not been upgraded since Windows 2000. On Windows XP SP2, NTSD will randomly crash with a "BEX error" message (even if hardware DEP is not enabled).

A useful application of debugging can be logging textboxes (which include asterisks protected boxes). Let's take a running NOTEPAD.EXE process for instance. The following command will attach NTSD to this process:
ntsd -pn notepad.exe

The WinDbg commands would be:
bp GetWindowTextA "r $t0=poi(esp+8); gu; da @$t0; g;"
bp GetWindowTextW "r $t1=poi(esp+8); gu; du @$t1; g;"

Explanation: the target functions (ANSI and Unicode versions) have the following prototype:
int GetWindowText( HWND hWnd, LPTSTR lpString, int nMaxCount );

At the function entry point, save the lpString pointer (esp+8) into a temporary register, then go up (until return), and read output value back.

Unfortunately, this will not work with NTSD (BEX error). We will have to find the RET address manually (using the step over or the unassemble command), then set the following breakpoints:
bp 7e3b218c "da poi(esp+8); g;"
bp 7e39ce0b
"du poi(esp+8); g;"

Then if we try to replace "it" by "works" using NOTEPAD menu:
0100a800 "it"

0100a700 "works"


Next post: how to log form boxes inside Internet Explorer.

Friday, August 01, 2008

Pentester trick #4: removing Symantec Antivirus 10.2 without knowing the password

Antivirus software is often the enemy of pentesting, because most useful tools (Cain, and even NetCat) are detected as "Potentially Unwanted Programs".

Some antivirus are easy to disable (like stopping a service), others are a real pain (non stoppable drivers). Symantec Enterprise 10.2 with anti-tampering options belongs to the second category.

Symantec Antivirus can be removed from the "Add/Remove Programs" Control Panel menu. However it asks for a password on removal.

This password is not a product feature, but a feature of Windows Installer subsystem. Therefore it is very easy to bypass. First step is to attach a debugger (like OllyDbg) to the MsiExec.exe process the password window is belonging to (this requires Administrative rights or Debug priviledge).

Second step is to set a breakpoint on GetWindowTextA. Then run the program, enter any password, and the breakpoint should be triggered. From that point, step out a few times until TEST AL, AL is encountered.

Setting AL register to any non-zero value allows product uninstall.

Note: ECX and EDX registers point to (entered and expected) password hashes. But this is an other story :)