210 likes | 323 Views
Introduction to InfoSec – Recitation 2. Nir Krakowski ( nirkrako at post.tau.ac.il) Itamar Gilad ( itamargi at post.tau.ac.il). Today. More assembly tips Binary Patching Tools Review of the stack Stack overflows Implementation Tools. Little vs Big Endian.
E N D
Introduction to InfoSec – Recitation 2 Nir Krakowski (nirkrako at post.tau.ac.il) ItamarGilad (itamargi at post.tau.ac.il)
Today • More assembly tips • Binary Patching • Tools • Review of the stack • Stack overflows • Implementation • Tools
Little vs Big Endian • Endian-ity is the definition of how numbers are represented in memory (or on a data bus) • In the x86 architecture 0x11223344 would be represented in memory: • 44 33 22 11 • Intel Architecture is little endian. (we are using little) • However the same number in Big Endian would be: • 11 22 33 44 • (we don’t see the bit reordering because our minimum working unit is a byte)
Registers • Common uses: • Eax – used usually for fast calculations / system call numbers /used to pass the return value or self class in c++. • Ecx – used as a counter frequently. • Ebp – used to store the stack frame pointer • Esp – used to store the stack pointer • edi/esi – used for string/buffer manipulations • Ip – used to store the current instruction pointer – can not be accessed directly!
x86 • There are lots of assembly instructions with varying sizes, and they can be used alternative to fit certain constraints. • Examples: • MOV EAX, 0 • Alternatively: • XOR EAX,EAX • There are also 8 bit commands to access partial registers • MOV AL, 5 • There are 16 bit commands • Mov ax, 65535
Binary Patching • Motivation: • Change the behavior of a program • Disable software protections for further analysis • Examples: • Bypass checks in the program • Adding new functionality • Blocking weak/vulnerable functionality • Process: • Find relevant code to modify • Understand code using reverse engineering • Find hook point in the code • Find location to insert new code without damaging the original operation or file structure as much as possible. • Divert flow from the hook point to the inserted code • Write the needed new functionality • Return the point of origin, or other appropriate point in the original code.
Example 1 • Pre patched code: • Load input strings to compare to existing • CALL strcmp • ADD ESP,8 • TEST EAX,EAX • JZ end_of_function • LEA EBX, [address to user input command ] • PUSH EBX • LEA EBX, [address to user parameter] • CALL execv • ADD ESP,4 end_of_function: • LEAVE • RET
Example 1-Identify • Pre patched code: • Load input strings to compare to existing • CALL strcmp • ADD ESP,8 • TEST EAX,EAX • JZ end_of_function • LEA EBX, [address to user input command ] • PUSH EBX • LEA EBX, [address to user parameter] • CALL execv • ADD ESP,4 end_of_function: • LEAVE • RET
Example 1-Patched • Patched code: • Load input strings to compare to existing • CALL strcmp • ADD ESP,8 • TEST EAX,EAX • NOP • NOP • LEA EBX, [address to user input command ] • PUSH EBX • LEA EBX, [address to user parameter] • CALL execv • ADD ESP,4 end_of_function: • LEAVE • RET • Why 2 NOPs ?
patch_util_gcc.py • Compiles assembly and patches input binary into output binary. • Parameters: • Original binary that will be patched • Output binary, this will be patch • Address.patch – code in assembly that will be compiled by gcc and put in the new binary in address which is the same as the patch. • Address2.patch – another patch • Don’t forget to “chmod+x [output binary]” after creation. • Running “patch_util_gcc.py empty.binshellcode.bin 0.patch” – can be used to write shellcode.
va_to_offset.py • Reads the FL structure and converts virtual addresses given at process startup (as shown in IDA). To the actual location in the file. • An alternative solution is to search for the original code with ghex and patch it with the hex editor.
Example 2 • Binary_patching_example_verify • We will override the verification of the login, by seeking the appropriate point, which will be most easy. • Create a patch and apply, verify that everything is well with IDA. • Run and test and hope for the best.
Buffer’Os • History: • First documented buffer overflows were thought of in 1972 COMPUTER SECURITY TECHNOLOGY PLANNING STUDY (Page 61) • The first buffer overflows known in the wild were Stack’Os • Stack Overflows were widely introduced by Aleph One • Phrack Magazine Issue 49on November 8, 1996 • Title: Smashing the stack for fun and profit • http://www.phrack.org/issues.html?issue=49&id=14#article • Purpose: • Like when patching, we re-route the code to new code which adds new functionility. • We modify the behavior of a program without modifying the binary, and only by controlling the input! • Therefore we can subvert the original functionality of the code to any purpose.
Where does it get reallyinteresting • When the program input is from a remote connection • Example: telnet • When the program has higher privileges • Example: su
Process Memory Abstract • /------------------\ lower • | | memory • | Text | addresses • | | • |------------------| • | (Initialized) | • | Data | • | (Uninitialized) | • |------------------| • | | • | Stack | higher • | | memory • \------------------/ addresses
Example1.c • void function(int a, int b, int c) { • char buffer1[5]; • char buffer2[10]; • } • void main() { • function(1,2,3); • }
Stack Structure • bottom of top of • memory memory • buffer2 buffer1 sfp ret a b c • <------ [ ][ ][ ][ ][ ][ ][ ] • top of bottom of • stack stack
Tools List • gdb – GNU Debugger • Core dumping: gdb –core=core.dump • Ollydbg – (for windows) which we will not cover in the course. • IDA • va_to_offset.py – easy program to get offset of code in orig file. • gcc – the gnu compiler • For the course we have prepared an easy utility for compiling small assembly bits: patch_util_gcc.py • ghex – can be used to patch the binary : • Once we have a search string to find the binary code, we can modify it • Other common tools for linux debugging: • ltrace – library tracing • strace – system call tracing • Objdump – dump elf file and symbol information • shellcode
shellcode example with interrupt calls • jmpcall_start # jump to the end of the code to /bin/sh • start_shellcode: # label to jump back • pop ebx # put point to /bin/sh in ebx • xoreax,eax # zero eax, but dont use mov, because it include \x00 • mov al, 0xb # system call 0xb, - execve • xorecx, ecx # clear pointer to envp • int 0x80 # call a system call! • xoreax,eax # ignore return and reset to zero. • mov al, 0x1 # call exit system call • int 0x80 • call_start: • call start_shellcode • .string "/bin/sh"
GDB Quick browse • si, ni – step instruction • s, n – step • info reg – print all registers • dump memory filename startaddressstopaddress • x/i address – disassemble at this address • p (char *) 0x234234 – print at this address as if it was a c-string. • x/bx address – print hex starting from this address • c – continue • r arg1 arg2 – runs the file with the specified arguments • b somefunction – sets a breakpoint