Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointer Subterfuge COEN 296A. Pointer Subterfuge Pointer Subterfuge is a general expression for exploits that modify a pointer’s value. Function pointers.

Similar presentations


Presentation on theme: "Pointer Subterfuge COEN 296A. Pointer Subterfuge Pointer Subterfuge is a general expression for exploits that modify a pointer’s value. Function pointers."— Presentation transcript:

1 Pointer Subterfuge COEN 296A

2 Pointer Subterfuge Pointer Subterfuge is a general expression for exploits that modify a pointer’s value. 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.

3 Pointer Subterfuge Using a buffer overflow: 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.

4 Pointer Subterfuge 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.

5 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. }

6 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 (*funcPtr)(const char *str); funcPtr = &good_function; strncpy(buff, argv[1], strlen(argv[1])); (void)(*funcPtr)(argv[2]); return 0; }

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

8 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 (*funcPtr)(const char *str); funcPtr = &good_function; strncpy(buff, argv[1], strlen(argv[1])); (void)(*funcPtr)(argv[2]); return 0; }

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

10 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 (*funcPtr)(const char *str); 5. funcPtr = &good_function; 6. strncpy(buff, argv[1], strlen(argv[1])); 7. (void)(*funcPtr)(argv[2]); 8. } A buffer overflow occurs when the length of argv[1] exceeds BUFFSIZE.

11 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 (*funcPtr)(const char *str); 5. funcPtr = &good_function; 6. strncpy(buff, argv[1], strlen(argv[1])); 7. (void)(*funcPtr)(argv[2]); 8. } When the program invokes the function identified by funcPtr, the shellcode is invoked instead of good_function().

12 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.

13 Data Pointers 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. Intel 32 Architectures: sizeof(void*) = sizeof(int) = sizeof(long) = 4B.

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

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

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

17 Instruction Pointer Modification Static invocation uses an immediate value for the address of the function. 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. Future value of IC is in a memory location that can be changed.

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

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

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

21 Targets for Instruction Pointer Modification: Global Offset Table GOT 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.

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

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

24 Targets for Instruction Pointer Modification: Global Offset Table % objdump --dynamic-reloc test-prog format: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049bc0 R_386_GLOB_DAT __gmon_start__ 08049ba8 R_386_JUMP_SLOT __libc_start_main 08049bac R_386_JUMP_SLOT strcat 08049bb0 R_386_JUMP_SLOT printf 08049bb4 R_386_JUMP_SLOT exit 08049bb8 R_386_JUMP_SLOT sprintf 08049bbc R_386_JUMP_SLOT strcpy The offsets specified for each R_386_JUMP_SLOT relocation record contain the address of the specified function (or the RTL linking function)

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

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

27 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: 0x80483a0. destroy: 0x80483b8. destroy called.

28 Targets for Instruction Pointer Modification:.dtors Both sections have the following layout: 0xffffffff {function-address} 0x00000000 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.

29 Targets for Instruction Pointer Modification:.dtors 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 0x00000000 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.

30 Targets for Instruction Pointer Modification:.dtors For an attacker, overwriting the.dtors section has advantages over other targets:.dtors is always present and mapped into memory. However: 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.

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

32 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; }

33 Targets for Instruction Pointer Modification: Virtual Functions Typical Implementation: 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. my_b b-obj: VPTR code for g() VTBL: g()

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

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

36 Targets for Instruction Pointer Modification: atexit() on_exit() on_exit() Similar functionality under SunOS Present in libc4, libc5, glibc

37 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"; }

38 Targets for Instruction Pointer Modification: atexit() on_exit() 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 __atexit in BSD __exit_funcs in Linux

39 Targets for Instruction Pointer Modification: atexit() on_exit() (gdb) b main Breakpoint 1 at 0x80483f6: file atexit.c, line 6. (gdb) r Starting program: /home/rcs/book/dtors/atexit Breakpoint 1, main (argc=1, argv=0xbfffe744) at atexit.c:6 6 atexit(test); (gdb) next 7 glob = "Exiting.\n"; (gdb) x/12x __exit_funcs 0x42130ee0 : 0x00000000 0x00000003 0x00000004 0x4000c660 0x42130ef0 : 0x00000000 0x00000000 0x00000004 0x0804844c 0x42130f00 : 0x00000000 0x00000000 0x00000004 0x080483c8 (gdb) x/4x 0x4000c660 0x4000c660 : 0x57e58955 0x5ce85356 0x81000054 0x0091c1c3 (gdb) x/3x 0x0804844c 0x804844c : 0x53e58955 0x9510b850 x102d0804 (gdb) x/8x 0x080483c8 0x80483c8 : 0x83e58955 0xec8308ec 0x2035ff08 0x68080496

40 Targets for Instruction Pointer Modification: atexit() on_exit() 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. Last doubleword contains address of function.

41 Targets for Instruction Pointer Modification: atexit() on_exit() (gdb) b main Breakpoint 1 at 0x80483f6: file atexit.c, line 6. (gdb) r Starting program: /home/rcs/book/dtors/atexit Breakpoint 1, main (argc=1, argv=0xbfffe744) at atexit.c:6 6 atexit(test); (gdb) next 7 glob = "Exiting.\n"; (gdb) x/12x __exit_funcs 0x42130ee0 : 0x00000000 0x00000003 0x00000004 0x4000c660 0x42130ef0 : 0x00000000 0x00000000 0x00000004 0x0804844c 0x42130f00 : 0x00000000 0x00000000 0x00000004 0x080483c8 (gdb) x/4x 0x4000c660 0x4000c660 : 0x57e58955 0x5ce85356 0x81000054 0x0091c1c3 (gdb) x/3x 0x0804844c 0x804844c : 0x53e58955 0x9510b850 x102d0804 (gdb) x/8x 0x080483c8 0x80483c8 : 0x83e58955 0xec8308ec 0x2035ff08 0x68080496

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

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

44 Targets for Instruction Pointer Modification: longjmp() longjmp() example: longjmp() returns control back to the point of the set_jmp() invocation. #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; }

45 Targets for Instruction Pointer Modification: longjmp() 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. 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]

46 Targets for Instruction Pointer Modification: longjmp() 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 2 restores the BP The movl instruction on line 3 restores the stack pointer (SP). Line 4 transfers control to the stored PC

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

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

49 Targets for Instruction Pointer Modification: Exception Handling SEH Implemented through try … catch blocks 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++ Used to clean-up anything instantiated in the try block. try { // Do stuff here } catch(…){ // Handle exception here } __finally { // Handle cleanup here }

50 Targets for Instruction Pointer Modification: Exception Handling SEH 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

51 Targets for Instruction Pointer Modification: Exception Handling Stack Frame Initialization Notice: 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, 0FFFFFFF8h push 0FFFFFFFFh push ptr [Exception_Handler] mov eax, dword ptr fs:[00000000h] push eax mov dword ptr fs:[0], esp

52 Targets for Instruction Pointer Modification: Exception Handling Attacker can: Overwrite the exception handler address. (supra) Replace the pointer in the Thread Environment Block (TEB). TEB contains lists of registered exception handlers. 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.

53 Targets for Instruction Pointer Modification: Exception Handling 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 SetUnhandledExceptionFilter() function. If an attacker overwrites specific memory addresses through an arbitrary memory write, the unhandled exception filter can be redirected to run arbitrary code.

54 Targets for Instruction Pointer Modification: Mitigation Strategies Eliminate vulnerabilities that allow memory to be improperly overwritten. These mistakes arise from: Overwriting data pointers (this presentation) Common errors managing dynamic memory Format string vulnerabilities. Eliminate exposure. W^X Reduce privileges of vulnerable processes. Memory segment can either be writable or executable, but not both. Difficult to implement. Does not work with targets such as atexit() that need to be both writable at runtime and executable.

55 Targets for Instruction Pointer Modification: Mitigation Strategies Canaries Does protect against Overflowing a buffer on a stack & overwrite stack pointer and other protected regions. Do not protect against Overflowing a stack by itself. Modification of variables data pointers function pointers

56 Targets for Instruction Pointer Modification: Summary Pointer subterfuge is a response to anti-stack smashing measures Canaries, Stack-Guard Method is a buffer overflow in the vicinity of a target pointer. Function pointer overwrite: Attacker can move control to arbitrary code provided in the payload. Data pointer overwrite: Can result in arbitrary writes to arbitrary memory. These modify one of a large list of “juicy” targets.


Download ppt "Pointer Subterfuge COEN 296A. Pointer Subterfuge Pointer Subterfuge is a general expression for exploits that modify a pointer’s value. Function pointers."

Similar presentations


Ads by Google