Anatomy of a format string exploit : Anatomy of a format string exploit Péter ZSÍROS
CEH, ECSA, MCSE, CISSP, MCT
What is %n good for? : variable1=strlen(„hello world”);
Is the same as:
printf(„hello world%n”,variable1);
What will printf(„%n”) do for you? What is %n good for?
The normal workflow : printf(„hello world%n”,variable1); The normal workflow stack Hello world%n Pointer to variable1 variable1 11
The abnormal workflow : printf(„hello world%n”); The abnormal workflow stack hello world%n Random data Random place in memory 0x0000000B
Searching for possibilities : printf(„hello world%n%n%n%n”); Searching for possibilities stack hello world%n Random data Junk Random data Random data SEH Garbage Trash Exception handler ( catch{ } ) ? ? ? Random data Read only area
What happens if the program crashes? : printf(„hello world%x %x %x %n”); What happens if the program crashes? stack hello world%n Random data Random data Random data SEH Exception handler ( catch{ } ) Random data Read only area
…so we need a crash ? : Why don’t we just write to the read only area?
We need just one more %n
printf(„hello world%x %x %x %n%n”);
The program crashes and jumps to the code pointed by SEH
The „code” there is 0x0000001E now ?
(PUSH DS) …so we need a crash ?
Running some more meaningful : What can we write there?
We have room for 4 bytes only!
Some ideas
The JMP family
RET
CALL
Where to jump?
Back to our inputstring Running some more meaningful
We need a better inputstring : Let’s calculate 1+1
MOV AL,1 (0xB0 01)
ADD AL,1 (0x04 01)
(The result appears in the AL register)
Speaking a little endian?
0x01 04 01 B0 == „????”
„hello world%x %x %x%n%n????”
This string will calculate 1+1 if we can jump here! We need a better inputstring
Where is this string in the memory? : It’s somewhere in the memory!
Let’s suppose it is on address: 0x45 84 96 84
We need JMP 0x45849684
This means we have to print out so many characters before using %n!
Writing two billion characters…?
Is there a trick to do it?
„%2224456773x” seems to be a solution, but… Where is this string in the memory?
Jumping relative to a register : JMP [EBP+0x404] == 0xFFA504040000
We have to write 0x0404A5FF characters before %n
„hello world %x %x %67413503x%n%n????” Jumping relative to a register 1+1 Writing so many characters Overwriting SEH Crash!
Using arbitrary code : Attach arbitrary code at the end of the string
Jump at the position after %n
„hello world%x %x %67413503x%n%nPAYLOAD…” Using arbitrary code Writing so many characters Overwriting SEH Crash!
Let’s do it! : Let’s do it! End of theory. And now... LAB: forging a format string exploit (2 hours)