Post on 21-Dec-2015
transcript
What is the deal with overflows
• Why does it exist?
• Can we get rid of it?
• Why cant we get rid of it?
Bounds checking?
int main(){ int a[4]; int n; scanf(“%d”, &n); while (n>0){ scanf(“%d”, &a[n]); n--;}}
int main(){ int a[4]; int n; scanf(“%d”, &n); if (n>3) n=3;// return while (n>0){ scanf(“%d”, &a[n]); n--;}}
Takeaways?
• How secure is any code?
• What would happen if we all used different architecture, custom compiled OS?
Benefits of custom compilation
• Randomize application memory
• Modify the relative distance between Return address and locals on stack for every binary– Attacker needs to determine correct input
values on every binary– Return of investment is lower
• Randomize the stack frame of every routine– Add padding between local variables and
return address– Makes buffer overflow exploits difficult
• So how to randomize the code– Source code?– Executable?
Binary re writing
• No net instructions added (or subtracted)
• Change arguments for adding space on stack
• Every instruction that use locations on stack (local variables) has to be fixed
void foo() {
char buffer[1024];
gets(buffer);
}
push %ebp
mov %esp,%ebp
sub $0x408,%esp
lea -0x400(%ebp),%eax
mov %eax,(%esp)
call 80482c8 <gets@plt>
leave
ret
Was this done
• Yes
• Use objdump to parse out the text
• Identify instructions
• Determine max pad for each function
• Go and re write instructions
Lets write code#include <stdio.h>
#include <stdlib.h> #include <errno.h> #include <sys/mman.h> #include <limits.h> /* for PAGESIZE */ #ifndef PAGESIZE #define PAGESIZE 4096 #endif
int test(); int main() { int a; char *location = &test; char *d = &test; test(); printf("\nAttempting not possible stuff"); fflush(NULL); d = (char *)(((int) d) & ~(PAGESIZE-1)); if (mprotect(d, 1024, PROT_WRITE|PROT_EXEC)) { perror("Couldn't mprotect"); exit(errno); } location [1] = 0xc3; test(); printf("\nShould not be here"); fflush(NULL); return 0;
}
int test() { int i; printf("\n hello from test"); return 0;
}
What does this show
• If an application wants to, it can cause havoc on itself.
• Is this useful?
• But this is a system call
• All system calls are available to every binary
• Can you make the execution jump to mprotect with correct stack arguments?
fork
• Creates a child process
• Execution returns back twice at the same location
• If return value is 0, it’s a child, else parent
• Code example 1
Example 2
• PTRACE_TRACEME– Process allows parent to trace it. When child
executes a system call (any signal), the control causes it to wait and sends control to parent which is waiting.
• PTRACE_CONT– Parent resumes the stopped child
Example 3
• Reads a word at offset addr in the child's USER area, which holds the registers and other information about the process
Example 6
• PTRACE_ATTACH– Attaches to the process specified in pid, making it a
traced "child" of the current process; the behavior of the child is as if it had done a PTRACE_TRACEME.
• PTRACE_GETREGS– Copies the child's general purpose or floating-point
registers, respectively, to location data in the parent.
• PTRACE_PEEKTEXT– Reads a word at the location addr in the child's
memory, returning the word as the result of the ptrace() call.
Example 7
• PTRACE_SETREGS– Copies the child's general purpose or floating-
point registers, respectively, from location data in the parent.