CAP 6135 Malware and Software Vulnerability Analysis Buffer
CAP 6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2014
A Stack Frame BP SP+offset SP Addresses Parameters Return Address Calling Stack Pointer Added Protection Local Variables 0000 SP: stack pointer BP: base/frame pointer Calling stack pointer: previous function’s SP 2
Using GDB to Check Stack q GDB tutorial: q q http: //sunsite. ualberta. ca/Documentation/Gnu/gdb-4. 18/html_chapter/gdb_toc. html http: //www. yolinux. com/TUTORIALS/GDB-Commands. html#GDB_COMMAND_LINE_ARGS When compile the c code, use “gcc –g …. . ” so that Gdb can match source code line number with code Some knowledge: http: //en. wikipedia. org/wiki/X 86_assembly_language q q Register eip: instruction pointer, the current position of next executable instruction Register ebp: stack pointer, the top of the current stack, used for addressing local variable 3
q Related Gdb Commands: q q q q List: list the source code and each execution’s corresponding line number Break linenumber: set breakpoint at the linenumber Break test. c: foo break when program run in the foo() function in test. c file. Run argv: run the execution code with the parameter argv Next: execute the next line of code Backtrace: show trace of all function calls in stack Info frame: List address, language, address of arguments/local variables and which registers were saved in frame. q q q This will show where the return address is saved Return address is in Register EIP Calling stack pointer is in Register EBP x &variable: show the address and value of a local variable (in hex format) x address: print binary representation of 4 bytes of memory pointed to by address. 4
Example of Using GDB #include <stdio. h> void foo(char * input){ int a 1=11; int a 2=22; char buf[7]; strcpy(buf, input); } void main(int argc, char **argv){ foo(argv[1]); } Question: What does the stack look like before strcpy()? 5
7 czou@eustis: ~/buffer-code$ setarch i 686 –R gdb. /gdb-example (gdb) list 1 #include <stdio. h> Remove address randomization 2 void foo(char * input){ used in Unix (will talk in next lecture) 3 int a 1=11; 4 int a 2=22; 5 char buf[7]; 6 strcpy(buf, input); 7 } 8 void main(int argc, char **argv){ 9 foo(argv[1]); 10 } (gdb) break 6 Breakpoint 1 at 0 x 8048459: file gdb-example. c, line 6. (gdb) run “what is this? a book” Starting program: /home/czou/buffer-code/gdb-example “what is this? a book" Breakpoint 1, foo (input=0 xbffff 838 "1234567890") at gdb-example. c: 6 strcpy(buf, input); 6
(gdb) info frame Stack level 0, frame at 0 xbffff 620: eip = 0 x 8048459 in foo (gdb-example. c: 6); saved eip 0 x 8048497 called by frame at 0 xbffff 640 source language c. Arglist at 0 xbffff 618, args: input=0 xbffff 82 d "what is this? a book" Locals at 0 xbffff 618, Previous frame's sp is 0 xbffff 620 Saved registers: ebp at 0 xbffff 618, eip at 0 xbffff 61 c (gdb) x &a 1 0 xbffff 5 fc: 0 x 0000000 b (gdb) x &a 2 0 xbffff 600: 0 x 00000016 (gdb) x buf 0 xbffff 605: 0 xf 4000000 7
Two Techniques for Generating Stack Overflow Codes
NOPs q q q Most CPUs have a No-Operation instruction – it does nothing but advance the instruction pointer. Usually we can put a bunch of these ahead of our program (in the string). As long as the new return-address points to a NOP we are OK.
Using NOPs new return address nt i po ere n h a C yw ere an n h i Real program (exec /bin/ls or whatever) nop instructions
Estimating the stack size q q We can also guess at the location of the return address relative to the overflowed buffer. Put in a bunch of new return addresses!
Estimating the Location new new new return return address address Real program nop instructions
Explanation of Project 1 • Target. c code vulnerability: int foo(char* arg, short arglen) { char buf[100]; int i, maxlen = 100; int len; if (arglen < maxlen) { len = strlen(arg); strncpy(buf, arg, len); • If input to foo(*arg, Big_Value) where Big_Value overflows ‘short’, then arglen could be negative value and passes the if() security check. 13
Explanation of Project 1 • In the exploit. c code: • • • #define TARGET “/home/czou/cap 6135 -project 1/targets/target” • Need to be changed to point to your own target executable code Change args[1] = “……. . "; • args[1] needs to point to a large buffer that can cause overflow to target code • You can define such a large buffer in exploit. c and make args[1] points to it. Your main task is to: • Find out where in stack stores the return address • Find out where is the starting address of ‘buf’ in foo() in target code • Fill the shellcode[] into the large buffer in your exploit code (which will fill the ‘buf’ variable in target code) • Assign the starting address of buf to the right place in the large buffer in your exploit code in order to overwrite the return address, then CPU will run the shellcode you put at the start of buf variable. 14
Several Tips on Project 1 1. Be sure to use the Makefile to generate executable of both exploit program and target program • At both. /exploit and. /target directory, run “make” 2. Be sure to use “setarch i 686 -R” in front of every execution, including both Gdb and. /exploit 3. You can use “break target. c: foo” to set breakpoint upon entering foo() function. 4. Fill the shell executable code (in the string array shellcode[]) byte-by-byte into the buffer for your modified return address to execute, do not use strcpy() because shellcode[] is not an ASCII string. 5. Make sure the long string you create has no NULL byte except the last byte
Several Tips on Project 1 As an example, suppose we know that: 1. The address of ‘buf’ in target. c is: 0 xbfff 0000 2. The address of the function’s return address (eip) is 0 xbfff 0100 3. We put the shellcode[] at the beginning of ‘buf’. How to Overwrite the return address to execute shellcode? 1. 0 xbfff 0100 – 0 xbfff 0000 = 0 x 100 = 256 in decimal 2. Since address in 32 -bit machine is 4 bytes and Eustis is a little-endian machine: buf[256] = 0 x 00; buf[257] = 0 x 00; buf[258] = 0 xff; buf[259] = 0 xbf; In this way, we have changed the flow to the beginning of shellcode! 16
- Slides: 16