52
Software Vulnerability INTRODUCTION IN SOFTWARE EXPLOITING

fg.workshop: Software vulnerability

Embed Size (px)

Citation preview

Page 1: fg.workshop: Software vulnerability

Software VulnerabilityI N TR O D U C TI O N I N S O F TWAR E E X P LO ITIN G

Page 2: fg.workshop: Software vulnerability

What does Remote code executing mean?

Page 3: fg.workshop: Software vulnerability

Legal Aspects (for Germany)

• § 202b Abfangen von Daten

• Wer unbefugt sich oder einem anderen unter Anwendung von technischen Mitteln nicht für ihn bestimmte Daten (§ 202a Abs. 2) aus einer nichtöffentlichen Datenübermittlung oder aus der elektromagnetischen Abstrahlung einer Datenverarbeitungsanlage verschafft, wird mit Freiheitsstrafe bis zu zwei Jahren oder mit Geldstrafe bestraft, wenn die Tat nicht in anderen Vorschriften mit schwererer Strafe bedroht ist.

• § 202c Vorbereiten des Ausspähens und Abfangens von Daten

• Wer eine Straftat nach § 202a oder § 202b vorbereitet, indem er

• Passwörter oder sonstige Sicherungscodes, die den Zugang zu Daten (§ 202a Abs. 2) ermöglichen, oder

• Computerprogramme, deren Zweck die Begehung einer solchen Tat ist,

• herstellt, sich oder einem anderen verschafft, verkauft, einem anderen überlässt, verbreitet oder sonst zugänglich macht, wird mit Freiheitsstrafe bis zu einem Jahr oder mit Geldstrafe bestraft.

Page 4: fg.workshop: Software vulnerability

Legal Aspects (for Switzerland)

• Art. 144 Datenbeschädigung

• Wer unbefugt elektronisch oder in vergleichbarer Weise gespeicherte oder übermittelte Daten verändert, löscht oder unbrauchbar macht, wird, auf Antrag, mit Freiheitsstrafe bis zu drei Jahren oder Geldstrafe bestraft

• Hat der Täter einen grossen Schaden verursacht, so kann auf Freiheitsstrafe von einem Jahr bis zu fünf Jahren erkannt werden. Die Tat wird von Amtes wegen verfolgt.

• Wer Programme, von denen er weiss oder annehmen muss, dass sie zu den in Ziffer 1 genannten Zwecken verwendet werden sollen, herstellt, einführt, in Verkehr bringt, anpreist, anbietet oder sonst wie zugänglich macht oder zu ihrer Herstellung Anleitung gibt, wird mit Freiheitsstrafe bis zu drei Jahren oder Geldstrafe bestraft.

• Handelt der Täter gewerbsmässig, so kann auf Freiheitsstrafe von einem Jahr bis zu fünf Jahren erkannt werden.

Page 5: fg.workshop: Software vulnerability

What are NOT the goals of this workshop

• Teaching how to write malware

• Hacking course

• Reverse engineering

• Cracking Software

• Motivate you to break the law

• But: to secure software it is important to understand how it will be attacked

Page 6: fg.workshop: Software vulnerability

What are the goals of this workshop

• Sensitize for commonest mistakes

• It’s easy to redirect the program flow if a programmer do not care

• If a programmer care it may be harder to exploit

• Software won’t be perfect secured

• Keep at least script kiddies out

• Explain principles of

• Finding software exploits

• Using software exploits

• Present existing counter mechanisms

• Small project

Page 7: fg.workshop: Software vulnerability

Essentials

• Goal: redirect original program flow to shell code

• Shell code: compiled code sequence

• = series of opcodes (e.g. 0xEB 0x06 0x90 0x90)

• In this case: malicious code to be executed

• How comes the shell code into the program?

• How to jump to the shell code?

Page 8: fg.workshop: Software vulnerability

Windows Process and Memory management

0x00000000

0x7FFFFFFF

0x00400000

stack

heap

Push: decrement stack pointer

Grows to higher addresses

Program image:PE header.text (code).data (data), etc.

Additional Heap space

Space for DLLs DLLs have header, .text, .data, etc

PEB

Shared user page

No Access

0x7FFDF000PED: Process Execution Block:

location of main executabledll addresses, heap infos

Page 9: fg.workshop: Software vulnerability

Basic: Function Calls

• Each function has its own stack frame (space for local variables)

• Stack pointer: points on the top of the stack frame.

• Frame/Base pointer: points on the button of the stack frame.

• Instruction Pointer: points on the next instruction to be executed.

• Before entering a function:

• Push function parameter on the stack

• Push current Instruction pointer to the stack

• Used to return the program flow

• Push Base Pointer to the stack

• After entering a function:

• MOV EBP, ESP (current stack pointer becomes new base pointer)

Page 10: fg.workshop: Software vulnerability

Basic: Function Calls

Main stackframe

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

1. after program initialization

Stack

ESP

EBP

Page 11: fg.workshop: Software vulnerability

Basic: Function Calls

Main stackframe

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

2. push function parameter

Stack

ptr to argv[1]

ESP

EBP

Page 12: fg.workshop: Software vulnerability

Basic: Function Calls

Main stackframe

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

3. Push instruction pointer

Stack

ptr to argv[1]

EIPESP

EBP

Page 13: fg.workshop: Software vulnerability

Basic: Function Calls

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

4. push base pointer

Main stackframe

Stack

ptr to argv[1]

EIP

EBPESP

EBP

Page 14: fg.workshop: Software vulnerability

Basic: Function Calls

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

5. new stack frame: MOV EBP, ESP

Main stackframe

Stack

ptr to argv[1]

EIP

EBPESPEBP

Page 15: fg.workshop: Software vulnerability

Basic: Stack space allocation

• Local variables of a function are stored on the current stack frame

• decrement stack pointer to store a new variable on top of the stack

• How to allocate arrays?

• SUB ESP, <arraysize>

• decrement stack pointer with array size

• How to store data in a array?

• Array begin + position

• Find “array begin” with fixed offset or LEA (load effective address) instruction

• Remember: a[4] == *(a+4)

Page 16: fg.workshop: Software vulnerability

Basic: Allocate Stack Array

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

6. Allocate array:SUB ESP, 0x80

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Page 17: fg.workshop: Software vulnerability

Basic: Write to Stack Array

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

7. Allocate array:MOV ESP, ECXINC ECX

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Page 18: fg.workshop: Software vulnerability

Basic: Return from a function: LEAVE

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

8. Return: LEAVE

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP ESP

Array

Leave Step 1: MOV ESP, EBP

Page 19: fg.workshop: Software vulnerability

Basic: Return from a function: LEAVE

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

9. Return: LEAVE

Main stackframe

Stack

ptr to argv[1]

EIP

EBP

EBP

Array

Leave Step 2: POP EBP

ESP

Page 20: fg.workshop: Software vulnerability

Basic: Return from a function: RET

void do_sth(char *buf){char var[128];…

}int main(int argc, char** argv){

do_sth(argv[1])}

10. Return: RETN

Main stackframe

Stack

ptr to argv[1]

EIP

EBP

EBP

Array

Restore the instruction pointer

ESP

Page 21: fg.workshop: Software vulnerability

Stack smashing

• What can possibly go wrong?

void do_sth(char *buf){char var[128];strcpy(var, buffer);

}int main(int argc, char** argv){

do_sth(argv[1])}

Page 22: fg.workshop: Software vulnerability

Stack smashing

• What can possible go wrong?

• strcpy terminates when a ‘\0’ character is reached

• What happens if argv[1]is larger than 128 characters?

void do_sth(char *buf){char var[128];strcpy(var, buffer);

}int main(int argc, char** argv){

do_sth(argv[1])}

Page 23: fg.workshop: Software vulnerability

Stack smashing

• What can possible go wrong?

• strcpy terminates when a ‘\0’ character is reached!

• What happens if argv[1]is larger than 128 characters?

• EBP and EIP are overwritten, and possible other stack frames program will crash

void do_sth(char *buf){char var[128];strcpy(var, buffer);

}int main(int argc, char** argv){

do_sth(argv[1])}

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Page 24: fg.workshop: Software vulnerability

From stack smashing to exploiting

• Used to redirect the program flow

• Overwrite the return address of a function call with address of injected shellcode

• Program flow is changed

• Execute Shell code

• Software Exploit:

• An advanced version of stack smashing

• Use an buffer overflow attack

• Overwrite the stored EIP with a meaningful address

Page 25: fg.workshop: Software vulnerability

Shell code

• How to inject shell code in the programs memory?

• Use program IO similar as for overwriting EIP

• write OP_CODES intoinput array behind EIP

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Shellcode

Page 26: fg.workshop: Software vulnerability

Shell code

• How to start the shell code?

• Jump to address where shell code is stored

• BUT: when executing on different machines the address may be different!

• Additional:0x00 in the address breaks the exploit

• you cannot overwrite EIP with hardcoded address

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Shellcode

Page 27: fg.workshop: Software vulnerability

Shell code

• How to start the shell code?

• Idea: After executing “ret” ESP points below the stored EIP

• search an address which contains jmp esp

• In a application dll (address is constant there)

• In a system dll (may differ in different OS versions)

• Overwrite EIP with this address

• When ret is executed the program will jmp to address jmp esp is executed shellcode is executed

Main stackframe

Stack

ptr to argv[1]

EIP

EBP

EBP

ESP

Array

Shellcode

Page 28: fg.workshop: Software vulnerability

Reliable jmp to Shell code

• Search for an address in the .text where JMP ESP is executed

• Overwrite EIP with this address.

• This is reliable, since the address of a program code is constant

• Search in shared libraries / DLLs for OP_CODES to jmp to the shell code

• Not necessary JMP ESP

• CALL ESP effects the same

• use another register if it points on your shellcode

• May use multiple instructions like: POP; JMP ESP etc.

• depends on position of your shell code

Page 29: fg.workshop: Software vulnerability

Shell code development

Write shellcode:

• There is a metasploit compiler to create shellcode

• gcc –c filename and objdump –d

• Write own opcodes:

• Look in disassembly

• Search in opcode table

Find opcodes to jump to shell code

• Search in disassembly,

• or use debugger for op-code search

• First search in program, then in system libraries

Page 30: fg.workshop: Software vulnerability

Windbg/GNU GDB to find vulnerability

Windgb GNU GDB

breakpoint bp label address break file:line

Memory dump d address (e.g. “d esp”) • dump (binary/memory) start_adr end_adr

• x function• x $espx/x, x/d, x/u to dump hex, signed, unsigneddump 4 words as hex:x/4xw $sp

disassemble u/uf address/function_name disassemble address/function_name

search in binary s start_addr end_addr pattern find start_addr end_addr pattern

show libraryaddresses

shown by default on the top of the output

info sharedlibrary

Windbg can be installed as crash debugger using: „windbg –I“

Page 31: fg.workshop: Software vulnerability

Example

void readfile(char *filename){char file[10]; memset(file, 0, sizeof(file));FILE *f = fopen(filename,"r");if (!f) {

printf("FILE NOT FOUND\n");return;

}fseek(f, 0L, SEEK_END);int size = ftell(f);rewind(f);printf("Size: %d\n", size);fread(file, size, 1, f);printf("%s", file);

}

Page 32: fg.workshop: Software vulnerability

Example

int main(int argc, char** argv){char *filename = "C:/foo.txt";printf("Open file: %s\n", filename);readfile(filename);

}

Page 33: fg.workshop: Software vulnerability

Example

• Start application with large file will crash it! (char file[10]) overflow)

• e.g. use a file with many ‘A‘

• Debugger shows an Access violation

Page 34: fg.workshop: Software vulnerability

Example

• Dump stack

• Wingdb: “d esp“

• Stack contains many ‘A‘ Base and stored Instruction Pointer are overwrittenwhen returning Instruction Pointer is set to AAAA or 41414141 behind the stack pointer there are many ‘A’ place shellcode here

Page 35: fg.workshop: Software vulnerability

Example

• Dump the base pointer:

• Wingdb: “d ebp“

• EBP contains now the address 41414141

• ‘A‘ is 0x41 in ASCI

• Same for the instruction pointer

Page 36: fg.workshop: Software vulnerability

Example

• How to find the address of the instruction pointer?

• Use meaningful content for the exploit and dump eip:

• ABCDEFGHIJKLMNOPQUVWXYZabcdefghijklmnopquvwxyz

• The instruction pointer now contains: 63646566

• (intel is little endian)

• EIP is where cdef is (look in ASCII table)

Page 37: fg.workshop: Software vulnerability

Example

• How to place shell code?

• Place shellcode behind the instruction pointer on the stack

• dump ESP

• ESP is where the ’f’ is

• Simple shellcode: 9090eef4

• twice NOP and jump back to esp

• eef4 is the opcode for “jmp esp”

• 0x90 is opcode for NOP

Page 38: fg.workshop: Software vulnerability

Example

• What address to use to overwrite the EIP?

• ffe4 is the opcode for “jmp esp”

• Search this opcode in ddl and the binary

• Kernel32.dll is loaded in address space 7c800000 to 7c906000

• It contains ffe4 at 0x7c803234

• replace cdef with 3432807c to execute jmp esp

• Program hang in a loop

Page 39: fg.workshop: Software vulnerability

Entire Exploit generation (Python)

f = open('C:/foo.txt', 'w')

offset1 = „ABCEDEFHIJKLMNOPQRSTUVWXYZab"

eip = chr (0x34) + chr (0x32) + chr (0x80) + chr(0x7c) #jmp esp is on this address in dll

opcode = chr(0x90) + chr(0x90) +chr(0xff) + chr(0xe4) # NOP, NOP, jmp esp

for i in offset1:f.write(i)

for i in eip:f.write(i)

for i in opcode:f.write(i)

f.close()

Page 40: fg.workshop: Software vulnerability

Jumping

• For some reason you cannot place your shellcode in ESP

• Search the shellcode in other registers:

• jmp EAX or jmp EBX

• Search the shellcode on the stack

• Search the address of the shellcode on the stack

• What if only a few bytes are usable for the shellcode

• What if

Page 41: fg.workshop: Software vulnerability

Gap between ESP and shellcode

• Sometimes it is not possible to write the shellcode directly to ESP

• May overwritten by other data or

• OS counter mechanism.

• Assume you have 8 byte gap overwrite EIP with an address that

contains “pop pop ret” first bytes of the shellcode are address

of “jmp esp”

• Pop takes 4 byte from stack (32bit)

• ret loads the first stack value in EIP

• goto “jmp esp” address and execute shellcode

• popad removes 32bytes from stack if pop is not enough

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Shellcode

gap

Page 42: fg.workshop: Software vulnerability

Search the address of the shellcode on the stack

• Sometimes the shellcode address is not inany register

• but it can be found on the stack

• POP until you reached shellcode address

• execute ret to load the address to EIP

• if the gap is 8 bytes again overwrite EIPwith an address that points on a“pop pop ret”

Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array

Shellcodeaddress

gap

Shellcode

Page 43: fg.workshop: Software vulnerability

What if only a few bytes are usable for theshellcode

• Sometimes only a few bytes are usablefor shellcode behind EIP

• but you can place more shellcode above

• use the few bytes to jmp the the shellcodeabove:

• Small shellcode can be:sub esp, 80 jmp esp

• Start shellcode with NOPs

• no exact jmp required Main stackframe

Stack

ptr to argv[1]

EIP

EBPEBP

ESP

Array Shellcode

Shellcode

Page 44: fg.workshop: Software vulnerability

Counter Mechanisms

• GS

• Reorder variables on the stack. Put arrays to higher addresses

• Other variables cannot be overwritten, but still EIP

• DEP

• Stack is not executable.

• Enforced by hardware.

• OS can disable it (required for JIT programs)

• You can ret to the lib function that disable DEP

• Stack Cookie

Page 45: fg.workshop: Software vulnerability

SEH (Structured Exception Handler) exploits

• a try-catch block runs in its own stack frame

• Information about the EH are pushed on the stack

• 8bytes:

• pointer to the next exception handler(for the case the current exception handler cannot handle the exception)

• pointer to the actual exception handler

• Chain of exception handlers

• FFFFFFFF marks the end of the chainOS exception handler kicks in

Main stackframe

Stack

EH

ptr to argv[1]

EIP

Array

EBP

Page 46: fg.workshop: Software vulnerability

SEH (Structured Exception Handler) exploits

• Cause an exception to kick EH in

• Overwrite the pointer to the next EH record with some jmpcode (to jmp to shellcode)e.g. eb069090 = jmp +06 NOP NOP

• Overwrite the EH with a pointer to an instructionthat will bring you back to next EH and executethe jmpcode(e.g. pop pop ret)

• The shellcode can be directly after the overwrittenEH.

next EH

next EH

FFFFFFFF

EH1

EH2

EH3

Page 47: fg.workshop: Software vulnerability

Stack Cookies

• Compiler flag (only for string buffer)

• Random value is computed when applicationstarts (stack cookie)

• Stored in .data section on the program

• After saving EBP and EIP push stack cookieon the stack

• To overwrite EIP you have to overwrite the Stack Cookie

• Before ret the stack cookie will be checked.

• So do not return, overwrite SEH to exploit

• Sometimes you can compute the value or it is constant

• Overwrite stack cookie in .dataMain

stackframe

Stack

EH

EIP

Stack Cookie

Array

ptr to argv[1]

ESP

Page 48: fg.workshop: Software vulnerability

Final words

• Check array bounds

• ensure nobody can overwrite

• Be carefully with pointer arithmetic

• Use secure programming languages (C#, Java, Haskell, Ada)

• but down forget:• it runs on a unsecure basis

• JAVA programs cannot be exploited with buffer overruns - theoretically

• JVM is written without focus on security there are many issues!

• SoftBound + CETS: Complete and Compatible Full Memory Safety for C

• proven approach to eliminate all possible bufferoverflows!

• Most of this problem are not caused by OS or software, but by unsafe CPU-architectures.

• Possible future CPU-architectures are less vulnerable (MILL CPU)

• on this architecture concept call stack cannot be overwritten to redirect program flow

• many popular exploiting technics become harder or impossible

• not classic buffer overruns, but there are other technics e.g. dangling pointers

Page 49: fg.workshop: Software vulnerability

Preventing Buffer Overflows

• ALWAY check array boundaries

• Do NOT forget to check for index overflows:

0 1 2 3 4 5 6 7 8 9 10 11 12

base bound

int array[4]:

ptr: array

• Iterate through the array: ++array;

• Boundary check:array > base && array+elementsize < bound

Page 50: fg.workshop: Software vulnerability

Preventing Buffer Overflows

• ALWAY check array boundaries

• Do NOT forget to check for index overflows:

0 1 2 3 4 5 6 7 8 9 10 11 12

boundbase

int array[4]:

ptr: array

• Boundary check:array > base && array+elementsize < bound

• Point with long long *ptr2 on element 12:• ptr2 > base: 12 > 9 • ptr2 + 1 < bound: 1 < 12 Access to element 0!

ptr2

Page 51: fg.workshop: Software vulnerability

Preventing Buffer Overflows

• ALWAY check array boundaries

• Do NOT forget to check for index overflows:

0 1 2 3 4 5 6 7 8 9 10 11 12

boundbase

int array[4]:

ptr: array ptr2

• Boundary check correct:array > base && array+elementsize < bound&& base < array+elementsize• ptr2 > base: 12 > 9 • ptr2 + 1 < bound: 0 < 12

• ptr2 + 1 > base: 0 > 9 X

Page 52: fg.workshop: Software vulnerability

Any Questions?