200 likes | 375 Views
Software attacks. Advanced Buffer Overflow: Pointer subterfuge. The problem. What is a pointer subterfuge ? It is essentially a buffer overflow + pointer manipulation The pointer could be a function pointer (a pointer to a code section) or even a data pointer
E N D
Software attacks Advanced Buffer Overflow:Pointer subterfuge
The problem • What is a pointer subterfuge? • It is essentially a buffer overflow + pointer manipulation • The pointer could be a function pointer (a pointer to a code section) or even a data pointer • This technique can help bypassing stack checks
AAAAAAAAAAA AAAAAAAAAAA unitiliazed buffer locals f 0x00401212 unitiliazed StackCanary 0012FE90 EBP saved 004119A2 Return address 00000003 a params 00000002 b Function-pointer clobbering Recall code from the last lesson void func(void* arg, size_t len){char buffer[100];void(*f)()=...; memcpy(buff, arg, len);//buffer overflow f();...} The function pointer could be set to a value of our own choice! And without being caught by stack checks
Data pointer modification (1) • It requires a particular stack configuration • BUT a modified version of this attack is also used in heap smashing exploits • The basic idea: modify a pointer to a memory region AND the value assigned to perform an arbitrary memory write • It is often used as a building block for other attacks
AAAAAAAAAAA AAAAAAAAAAA My value My Memory unitiliazed buffer locals val unitiliazed ptr unitiliazed StackCanary 0012FE90 EBP saved 004119A2 Return address 00000003 params 00000002 Data pointer modification (2) void func(void* arg, size_t len){char buffer[100];int val;int* ptr; memcpy(buff, arg, len);//overflow...*ptr = val;return;} Even in this case, we don’t have canary or ret overwriting
unitiliazed buffer locals val unitiliazed ptr unitiliazed StackCanary My value 0012FE90 EBP saved 004119A2 Return address 00000003 params 00000002 Data pointer modification (2) void func(void* arg, size_t len){char buffer[100];int val;int* ptr; memcpy(buff, arg, len);//overflow...*ptr = val;return;} AAAAAAAAAAA AAAAAAAAAAA My value My Memory Old value My Memory
The double cookie overwrite exploit uses a data pointer modification to defeat canary based protection in VC++ 7.0 Stores shellcode in buffer as usual Modifies the pointer to point to the global cookie Overwrites stack cookie and global cookie with the same value Litchfield exploit (1)
Random value computed at process startup and stored in .data section Inserted by compiler at stack frame bottom Check inserted by compiler just before ret instruction Litchfield exploit (2) extern int global_cookie; void vulnerable_func(void* arg, size_t len){char buffer[100];int i;int* ptr;int stack_cookie; memcpy(buff, arg, len);//overflow...*ptr = i; if (stack_cookie != global_cookie) //buffer overflow occurred! exit(); return;}
unitiliazed buffer locals i unitiliazed ptr unitiliazed 0x12345678 AAAAAAAAAAA AAAAAAAAAAA 0012FE90 EBP saved 004119A2 Return address 0x0BADF00D 00000003 params 0x00408080 00000002 0x0BADF00D Litchfield exploit (2) 0x1234568 extern int global_cookie; void vulnerable_func(void* arg, size_t len){char buffer[100];int i;int* ptr;int stack_cookie; memcpy(buff, arg, len);//overflow...*ptr = i; if (stack_cookie != global_cookie) //buffer overflow occurred! exit(); return;} 0x00408080 stack_cookie
unitiliazed buffer locals i unitiliazed ptr unitiliazed 0x12345678 0012FE90 EBP saved 004119A2 Return address 00000003 params 00000002 Litchfield exploit (2) 0x0BADF00D extern int global_cookie; void vulnerable_func(void* arg, size_t len){char buffer[100];int i;int* ptr;int stack_cookie; memcpy(buff, arg, len);//overflow...*ptr = i; if (stack_cookie != global_cookie) //buffer overflow occurred! exit(); return;} 0x00408080 AAAAAAAAAAA AAAAAAAAAAA 0x0BADF00D 0x00408080 stack_cookie 0x0BADF00D
unitiliazed buffer locals i unitiliazed ptr unitiliazed 0x12345678 0012FE90 EBP saved 004119A2 Return address 00000003 CHECK PASS!! params 00000002 Litchfield exploit (2) 0x0BADF00D extern int global_cookie; void vulnerable_func(void* arg, size_t len){char buffer[100];int i;int* ptr;int stack_cookie; memcpy(buff, arg, len);//overflow...*ptr = i; if (stack_cookie != global_cookie) //buffer overflow occurred! exit(); return;} 0x00408080 AAAAAAAAAAA AAAAAAAAAAA 0x0BADF00D 0x00408080 stack_cookie 0x0BADF00D
Data pointer modification (3) • An arbitrary memory overwrite can be used to set a function pointer that is everywhere in our address space • The problem is… find it! =) (more on this later, maybe…) extern void (* f)(); void func(void* arg, size_t len) { char buffer[100];int val; int* ptr; memcpy(buff, arg, len);//overflow...*ptr = val;return;} Set ptr to &f, and val to the code we want to execute
call D::f() > Derived Virtual pointer smashing • Virtual pointer (VPTR): what is this? • C++ programming: virtual functions • Inheritance without polymorphism class B {public:int i;void f() { printf(“Base”); }}; int main(){ D d; d.f();} class D: public B {public:int i;void f() { printf(“Derived”); }};
> Derived> Base Virtual pointer smashing • Inheritance with polymorphism class B {public:int i;virtualvoid f() { printf(“Base”); }}; int main(){ B* b = new D(); b.f(); b = new B(); b.f();} class D: public B {public:int i;void f() { printf(“Derived”); }}; How can the compiler distinguish?
vtable void (*f)() … i (4 bytes) vptr (4 bytes) Virtual pointer smashing class B {public:int i;virtualvoid f() { printf(“Base”); }}; i (4 bytes) vptr (4 bytes) int main(){ B* b = new D(); b.f();
vtable void (*f)() … Virtual pointer smashing class B {public:int i;virtualvoid f() { printf(“Base”); }}; i (4 bytes) vptr (4 bytes) int main(){ B* b = new D(); b.f(); mov edx, DWORD PTR bmov eax, DWORD PTR [edx] call DWORD PTR [eax]
0x0012FF6C vtable 0xDDDDDDDD 0x00401050 0xDDDDDDDD void (*f)() AAAAAAAA 0xDDDDDDDD … AAAAAAAA 0xDDDDDDDD 0x00170000 Virtual pointer smashing class B {public:int i;virtualvoid f() { printf(“Base”); }}; i (4 bytes) vptr (4 bytes) buffer void foo() { printf("Foo!!\n");} f int main() {B* b = new D1();char buffer[20]; memcpy(buffer, msg, 24); b->f();return 0;}
0x0012FF6C vtable 0xDDDDDDDD 0x00401050 0xDDDDDDDD void (*f)() AAAAAAAA 0xDDDDDDDD … AAAAAAAA 0xDDDDDDDD 0x0012FF68 0x00170000 Virtual pointer smashing class B {public:int i;virtualvoid f() { printf(“Base”); }}; i (4 bytes) vptr (4 bytes) buffer void foo() { printf("Foo!!\n");} f int main() {B* b = new D1();char buffer[20]; memcpy(buffer, msg, 24); b->f();return 0;}
Virtual pointer smashing Demo?
VC++ (COM-aware compilers) GCC vptr (4 bytes) data data vptr (4 bytes) Virtual pointer smashing • This attack relies on the method adopted by C++ compilers to have dynamic binding • It’s compiler specific: where to place the vptr/vtable is up to the implementation This memory layout leaves space for another exploit (anyone interested?)