Friday, December 19, 2008

Pentester trick #6: logging Internet Explorer boxes

In a previous post (Debugging Without Debugger), I promised to explain how to log content from text areas within Internet Explorer Web pages.

If you tried to apply the previously described technique to Internet Explorer, you should have noticed that GetWindowText is never called for getting text from Web controls. This is because the whole Web page is rendered without relying on standard Windows controls.

Therefore, we need to find the GetWindowTextLength/GetWindowText equivalents in MSHTML.DLL. Fortunately, debugging symbols will help us much in this case. The equivalent functions are:

mshtml!CTxtPtr::GetPlainTextLength()
mshtml!CTxtPtr::GetPlainText()

Which are called from 3 locations, the most common being:

mshtml!CElement::GetPlainTextInScope()

Unfortunately, NTSD does not seem to handle symbols properly, which prevents us from setting a symbolic breakpoint :(

Since MSHTML.DLL is upgraded by virtually every cumulative patch for Internet Explorer, you really need to get access to the debugging symbols for the specific Internet Explorer version installed on the target (hint: use the SYMCHK utility shipped with Debugging Tools) and find appropriate addresses inside.

From my up-to-date Internet Explorer 7 installation, here are some sample addresses:

mshtml!CTxtPtr::GetPlainTextLength : 0x44BB3B85 (entry point) -> 0x44BB3BFD (ret)
mshtml!CTxtPtr::GetPlainText : 0x44BB3C05 (entry point) -> 0x44BB3C75 (ret)
mshtml!CElement::GetPlainTextInScope : 0x44BB3CA6 (entry point) -> 0x44BB3D46 (ret)

The epilog of GetPlainTextInScope function is:

.text:44BB3D3F mov eax, [ebp+var_4]
.text:44BB3D42 pop edi
.text:44BB3D43 pop esi
.text:44BB3D44 pop ebx
.text:44BB3D45 leave
.text:44BB3D46 retn 4
.text:44BB3D46 ?GetPlainTextInScope@CElement@@QAEJPAVCStr@@@Z endp


From here, it is nice to know that ESI points to the Unicode text content before being overwritten at address 0x44BB3D43. Therefore the following NTSD commands will do the trick:

ntsd -pn iexplore.exe
bp 0x44BB3D43 "du poi(esi); g;"

Awkward trick I must admit, but it could save pentesters' lifes anyway ;)

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");

CoInitialize(NULL);

IShockwaveFlash *pShockwave=NULL;

HRESULT hr = CoCreateInstance( __uuidof(ShockwaveFlash),
NULL,
CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
__uuidof(IShockwaveFlash),
(void**)&pShockwave
);

if (hr==S_OK) {

DWORD dwVT=*(DWORD*)pShockwave;
DWORD *p=(DWORD*)dwVT;

for (int i=1;i<11;i++) {
printf("[%d] VA=%08x RVA=%08x\n",
i,
*p,
*p-(DWORD)GetModuleHandle("Flash9e.ocx")
);

p++;
}

pShockwave->Release();
}

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.

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

/out:test.exe
test.obj

C:\>test.exe
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 Reversemode.com. 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 :)

Sunday, April 06, 2008

The case of "thumbs.db" file

My Windows skills were recently challenged by a blog post of Cédric Blancher about the "thumbs.db" file internals.

It is widely documented that this file is an OLE container for holding thumbnail information, when the corresponding Explorer option is checked (which is the default configuration). Some Open Source tools even exist to parse the "thumbs.db" file.

However, there is one more question that has been left unanswered: "how is custom image ordering preserved?".

Naive approach

A quick test yields the following empirical result:
  • Within Explorer, browse a folder which has a sub-folder where some images are stored. A "thumbs.db" file is created in this sub-folder, if necessary.
  • Enter the sub-folder and move images around. "Thumbs.db" file size increases.
  • Backup the existing "thumbs.db" file with the following commands:
attrib -r -s -h thumbs.db
copy thumbs.db backup.db

  • Shuffle images again. Compare the new "thumbs.db" file with the backup, using the following command:
attrib -r -s -h thumbs.db
fc /b backup.db thumbs.db


Files should be exactly the same!

First trail

In a sense, this is perfectly logical in Windows world, since image ordering is a per-user setting. Two users sharing the same computer could order images differently without affecting each other's view. It would make no sense to store this is information in a single, shared file.

Per-user settings could be stored in a configuration file (e.g. ".ini" file) inside the %UserProfile% directory, but this is very "Windows 3.1" style.

At this point, we rather suspect that settings are stored under the HKCU registry hive.

Chasing the culprit

Process Monitoring the Explorer process could quickly become exhausting, given the amount of registry keys that are accessed during normal system operation. We will rather try to pinpoint the system component that manages the "thumbs.db" file.

A fast and efficient approach is to search for string references in system directories:

C:\WINDOWS\SYSTEM32>strings *.dll | findstr /i thumbs.db

C:\WINDOWS\SYSTEM32\mydocs.dll: thumbs.db
C:\WINDOWS\SYSTEM32\shell32.dll: Thumbs.db
C:\WINDOWS\SYSTEM32\shell32.dll: thumbs.db
C:\WINDOWS\SYSTEM32\wmp.dll: thumbs.db


In this case, we use strings.exe from SysInternals, which has the big advantage over various "grep" ports to be able to handle ANSI and Unicode strings all together.

A quick look inside mydocs.dll shows a string reference from CleanupSystemFolder() function, which does not seem to be related to our matter. Windows Media Player library (wmp.dll) does not seem to be a valid candidate either. Therefore, the core processing should be done in shell32.dll.

Shell32 internals

Shell32 is a rather old and complex system component - a complete analysis is out of question.

However a quick look inside this component yields interesting information:
  • It makes heavy use of the COM model.
  • It holds many interestingly named C++ classes, like CThumbnailMenu, CThumbStore and CEnumThumbStore.
  • Thumbnail processing is done in the background by a worker thread. Therefore changes are not immediately reflected, which hampers the Process Monitoring approach.
The key point is that CThumbStore class seems to implement IPersistFile, IPersistFolder, IPersistStorage and IShellImageStore interfaces, among others.

This should ring a bell about property bags, which is the standard way for a COM object to store opaque, persistent data. Therefore we will make a great leap forward, and search directly for the "bags" keyword inside the binary file.

Beginning to see the light

The search for "bags" is successful: there is very few references, with very interesting content.

The first reference comes from this registry key:
HKCU\Software\Microsoft\Windows\ShellNoRoam\Bags

It is referenced from:
CDefView::_SaveGlobalViewState()
CDefView::_ResetGlobalViewState()


The second reference comes from this registry sub-key:
DUIBags\ShellFolders\{00000000-0000-0000-0000-000000000000}

It is referenced from:
CDUIView::_InitializeShellFolderPropertyBag()

Under the "ShellNoRoam" registry key, we could find thousands of numeric subkeys, which in turn hold values of interest, like the coordinates of the image. After digging a little more, we gather the following information:
  • Monitoring the "ShellNoRoam" key with Process Monitor reveals that registry information is updated only when exiting the folder.
  • Custom image ordering will be used on folder re-opening only if "remember each folder's view settings" is checked in Explorer configuration. Otherwise default layout is used.
  • There is a bug in Windows XP pre-SP2 that prevents creating more than 200 custom views :)
At this point, there are still open questions, like "how does the ItemPos binary blob relates to effective image position?". This would require in-depth analysis of CViewState::LoadPositionBlob() maybe.

But most of the question is answered for now!

Conclusion

With a minimal amount of code analysis, we were able to pinpoint the code block that manages the "thumbs.db" file, and how persistent image location data is internally managed by the Explorer process.

Final note: this article relates to Windows XP SP2 only. Windows Vista might exhibit different behaviour.

Friday, April 04, 2008

The truth about Access 0-days

Security flaws in popular Office file formats (namely DOC, XLS and PPT) have been very common in the past few years, accounting for a large amount of Microsoft Security Bulletins (cf. slide #4 on this presentation). They have been also involved in high-profile targeted attacks.

However, flaws in lesser used Office file formats (namely PUB and MDB) were largely disregarded by Microsoft, for at least 2 reasons:
  • Access (.MDB) and Publisher (.PUB) applications are not part of Office Standard suite - they are available in higher grade SKUs only.
  • Access file format is considered "insecure by design" since automatic code execution on file opening cannot be blocked. Therefore MDB files are included in Microsoft blocked list. This list is enforced by Outlook application on attachments, among others.
A large amount of "buffer overflow"-like bugs involving MDB files have been floating around since year 2005 at least.

Some malware authors recently found a way to bypass Microsoft filters by sending 2 attachments in the same email (or the same ZIP file): the first one is an approved Office file format (let's say DOC), the other has an unknown extension.

However, when the Word document tries to open the second one as an ODBC Datasource using Jet Engine (where the flaw lies), it will disregard the extension.

McAfee Avert Labs blogged about that, but they missed something that is regularly re-discovered: OLE documents will be opened by the right Office application regardless of their extension.

How to reproduce:
  1. Create a new Word document named "test.doc".
  2. Rename "test.doc" into "test.xxx" (the extension shall not be already registered).
  3. Double-click on "test.xxx". Enjoy!
Therefore, if you want to be protected against Office-based attacks, you shall block any unknown extension (or rather, use a white-list of "known safe" extensions) at your mail gateway.

Monday, March 03, 2008

Pentester trick #3: using Cain without installing it

Cain is one of the most useful pentesting tool for Windows. It has been rated #9 in the Top 100 of security tools.

While Cain is powerful when used on the pentester's computer, it is quite limited in terms of "pivoting" (i.e. using a compromised host as a bouncer to reach another part of the target network).

Installing Cain on a compromised host yields at least two severe limitations :
  1. Cain requires Winpcap. If Winpcap is not found, Cain will refuse to load. Winpcap installs a new driver, and might require a reboot, which is not good in terms of footprint.
  2. Cain is being detected as Potentially Unwanted Software by most antivirus software out there.
Fortunately, both limitations can be removed.

To have Cain loading properly, it is enough to add the following DLLs in Cain directory :
  • packet.dll
  • wanpacket.dll
  • wpcap.dll
Note#1: without Winpcap driver, Cain will lack network features like password sniffing and ARP poisoning.

To make Cain undetected by most (if not all) antivirus software, the software must be "repacked". However, this is another story :)

Note#2: Cain still requires administrative rights on the compromised host.

Wednesday, February 20, 2008

Pentester trick #2: faking NetBIOS names

Trick #2: faking NetBIOS names

There has been a buzz at BlackHat US 2007 around H.D.Moore+Valsmith attack against Internet Explorer autoconfiguration feature.

To sum up, if anything is named after "WPAD" on the network, it will be considered as the enterprise Web proxy by Internet Explorer.

The original attack is based on the "Dynamic DNS Update" feature of Windows DNS servers. DNS updates can be:
  • DNS-based, unauthenticated. Game over.
  • DNS-based, authenticated. Nice try, but since any domain user can create up to 10 computer accounts in Active Directory, it is quite easy to name a computer "WPAD", join a domain and authenticate.
  • DHCP-based. Game over, too: the DNS server will blindly trust your host name.
Ok, but what if "Dynamic DNS Update" feature has been disabled? Or if you need to quickly register names? Joining a new computer to the domain is not an option in this case.

Fortunately, everybody who has sniffed a Windows network for more than 5 minutes knows that most Windows clients "in the wild" use misconfigured name resolution: they rely on NBNS (NetBIOS Name Service) as a fallback.

So how could you take advantage of a broadcasted NBNS request for "WPAD" (or anything else) to redirect target's traffic?

One solution would be to use FakeNetBIOS tools, but they rely on raw sockets, which are broken on Windows XP SP2. Another would be to use Scapy as a NBNS responder, but Windows port is not mature yet :)

As usual, the best solution is to rely on Windows built-in mechanisms to solve the puzzle.

Under HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters, there is a value of type REG_MULTI_SZ called OptionalNames.

Any name put in there will be claimed by the local computer during NBNS name resolution. Then:

net stop lanmanserver
net start lanmanserver

Job done!

Pentester trick #1: using RDP Client 5 on Vista

Nonop's recent post on pentester's essentials was inspiring enough for me to get back on-line, on this long-abandoned blog.

So here is the first post of a (hopefully long) series about pentester tricks, from my very own field experience. Enjoy!

Trick #1 : using RDP Client 5 on Vista

RDP Client 5 has a great advantage over RDP Client 6 : it allows connecting to the remote target without giving any credential ; thus the pentester can get access to server version, computer name and trusted domains, without leaving any track in the security audit trail.

However RDP Client 6 has been pushed on Windows Update quite a while ago, and is required in some cases (like Windows Vista/2008 Remote Desktop with full security options ... which are recommended given flaws found in previous versions of RDP protocol).

Fortunately, it is quite easy to make both clients living together. RDP Client 5 consists of only 2 binaries : MSTSC.EXE and MSTSCAX.DLL. The trick is to copy both files, and to create a MSTSC.EXE.LOCAL file in the same directory. This will force MSTSC.EXE to load libraries from the current directory instead of the global system directory.

References: [1] [2]