This time
- Everything you’ve always wanted to know about
gdb but were too afraid to ask
- Overflow defenses
- Other memory safety vulnerabilities
Buffer
- verflows
We will continue
and other memory safety vulnerabilities
By looking at
Overflow
Defenses
Buffer Overflow overflows Defenses and other memory safety - - PowerPoint PPT Presentation
This time We will continue By looking at Buffer Overflow overflows Defenses and other memory safety vulnerabilities Everything youve always wanted to know about gdb but were too afraid to ask Overflow defenses Other memory
gdb but were too afraid to ask
We will continue
and other memory safety vulnerabilities
By looking at
Defenses
i f i r x/<n> <addr> b <function> s Set a breakpoint at <function> step through execution (into calls) Examine <n> bytes of memory starting at address <addr> Show info about registers (%ebp, %eip, %esp, etc.) Show info about the current frame (prev. frame, locals/args, %ebp/%eip)
How can we make these even more difficult?
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
…
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
…
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
… 02 8d e2 10
canary
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
… 02 8d e2 10
canary
nop nop nop …
0xbdf
\x0f \x3c \x2f ...
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
… 02 8d e2 10
canary
nop nop nop …
0xbdf
\x0f \x3c \x2f ...
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
… 02 8d e2 10
canary
nop nop nop …
0xbdf
\x0f \x3c \x2f ...
Not the expected value: abort
Detecting overflows with canaries
00 00 00 00
buffer
Text
%eip
...
&arg1 %eip
%ebp
… 02 8d e2 10
canary
nop nop nop …
0xbdf
\x0f \x3c \x2f ...
Not the expected value: abort What value should the canary have?
From StackGuard [Wagle & Cowan]
How can we make these even more difficult? More next time…
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
nop nop nop …
nop sled
0xbdf
good guess padding
\x0f \x3c \x2f ...
malicious code libc
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
nop nop nop …
nop sled
0xbdf
good guess padding libc
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
0xbdf
good guess padding libc
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
padding libc
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
padding libc
exec()
... ...
printf()
...
“/bin/sh”
libc
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
padding
0x17f
known location libc
exec()
... ...
printf()
...
“/bin/sh”
libc
&arg1 %eip
%ebp
00 00 00 00
buffer
Text
%eip
...
…
padding
0x17f
known location
0x20d
libc
exec()
... ...
printf()
...
“/bin/sh”
libc
How can we make these even more difficult?
Address Space Layout Randomization (ASLR)
How would you overcome this as an attacker?
gdb but were too afraid to ask
We continued
and other memory safety vulnerabilities
By looking at
Defenses
Required reading:
“StackGuard: Simple Stack Smash Protection for GCC” Optional reading: “Basic Integer Overflows” “Exploiting Format String Vulnerabilities”
Writing & testing for
Continuing with
http://nob.cs.ucdavis.edu/bishop/secprog/robust.html
Cat and mouse
Cat and mouse
injection of code
Cat and mouse
injection of code
Cat and mouse
injection of code
return address using ASLR
Cat and mouse
injection of code
return address using ASLR
Cat and mouse
injection of code
return address using ASLR
the program text instead
Cat and mouse
injection of code
return address using ASLR
the program text instead
return oriented programming (ROP)
Return-oriented Programming
Return-oriented Programming
Return-into-libc without Function Calls (on the x86), CCS’07
Return-oriented Programming
Return-into-libc without Function Calls (on the x86), CCS’07
your shellcode, string together pieces of existing code, called gadgets, to do it instead
Return-oriented Programming
Return-into-libc without Function Calls (on the x86), CCS’07
your shellcode, string together pieces of existing code, called gadgets, to do it instead
Approach
Approach
with ret
Approach
with ret
etc.
Simple example
0xffffffff 0x00 mov %edx, 5
equivalent to
%edx
Simple example
0x17f: pop %edx ret 0xffffffff 0x00 Text mov %edx, 5
equivalent to
%edx
Gadget
Simple example
0x17f: pop %edx ret 5 0x17f 0xffffffff 0x00 Text mov %edx, 5 …
equivalent to
%edx
next gadget
Gadget “Instructions”
Simple example
0x17f: pop %edx ret 5 0x17f 0xffffffff 0x00 Text mov %edx, 5 …
equivalent to
%eip
%edx
next gadget
%esp
Gadget “Instructions” “program counter”
(ret)
Simple example
0x17f: pop %edx ret 5 0x17f 0xffffffff 0x00 Text mov %edx, 5 …
equivalent to
%eip
%edx
next gadget
%esp (ret)
Simple example
0x17f: pop %edx ret 5 0x17f 0xffffffff 0x00 Text mov %edx, 5 …
equivalent to
%eip
%edx
5
next gadget
%esp (ret)
Simple example
0x17f: pop %edx ret 5 0x17f 0xffffffff 0x00 Text mov %edx, 5 …
equivalent to
%eip
%edx
5
next gadget
%esp (ret)
Code sequence
0xffffffff 0x00 0x404 … … 5 …
%eax %ebx
… %esp 0x17f: mov %eax, [%esp] mov %ebx, [%esp-8] mov [%ebx], %eax %eip 0x404 Text
Code sequence
0xffffffff 0x00 0x404 … … 5 …
%eax %ebx
… %esp 0x17f: mov %eax, [%esp] mov %ebx, [%esp-8] mov [%ebx], %eax %eip 0x404 Text 5
Code sequence
0xffffffff 0x00 0x404 … … 5 …
%eax %ebx
… %esp 0x17f: mov %eax, [%esp] mov %ebx, [%esp-8] mov [%ebx], %eax %eip 0x404 Text 5 0x404
Code sequence
0xffffffff 0x00 0x404 … … 5 …
%eax %ebx
… %esp 0x17f: mov %eax, [%esp] mov %ebx, [%esp-8] mov [%ebx], %eax %eip 0x404 Text 5 0x404 5
Equivalent ROP sequence
0xffffffff 0x00 0x404 0x20d 0x21a 5 …
%eax %ebx
… %esp 0x17f: pop %eax ret … 0x20d: pop %ebx ret … 0x21a: mov [%ebx], %eax %eip 0x404 Text
Equivalent ROP sequence
0xffffffff 0x00 0x404 0x20d 0x21a 5 …
%eax %ebx
… %esp 0x17f: pop %eax ret … 0x20d: pop %ebx ret … 0x21a: mov [%ebx], %eax %eip 0x404 Text 5
Equivalent ROP sequence
0xffffffff 0x00 0x404 0x20d 0x21a 5 …
%eax %ebx
… %esp 0x17f: pop %eax ret … 0x20d: pop %ebx ret … 0x21a: mov [%ebx], %eax %eip 0x404 Text 5
Equivalent ROP sequence
0xffffffff 0x00 0x404 0x20d 0x21a 5 …
%eax %ebx
… %esp 0x17f: pop %eax ret … 0x20d: pop %ebx ret … 0x21a: mov [%ebx], %eax %eip 0x404 Text 5 0x404
Equivalent ROP sequence
0xffffffff 0x00 0x404 0x20d 0x21a 5 …
%eax %ebx
… 0x17f: pop %eax ret … 0x20d: pop %ebx ret … 0x21a: mov [%ebx], %eax %eip 0x404 Text 5 0x404
Equivalent ROP sequence
0xffffffff 0x00 0x404 0x20d 0x21a 5 …
%eax %ebx
… 0x17f: pop %eax ret … 0x20d: pop %ebx ret … 0x21a: mov [%ebx], %eax %eip 0x404 Text 5 0x404 5
Image by Dino Dai Zovi
Whence the gadgets?
Whence the gadgets?
Whence the gadgets?
instructions, work backwards)
Whence the gadgets?
instructions, work backwards)
Whence the gadgets?
instructions, work backwards)
libc), gadgets are Turing complete
Whence the gadgets?
instructions, work backwards)
libc), gadgets are Turing complete
gadget shellcode creation, though not needing/requiring Turing completeness
Blind ROP
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
versions of executables
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
versions of executables
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
versions of executables
If server restarts on a crash, but does not re-randomize:
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
versions of executables
If server restarts on a crash, but does not re-randomize: 1.Read the stack to leak canaries and a return address
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
versions of executables
If server restarts on a crash, but does not re-randomize: 1.Read the stack to leak canaries and a return address 2.Find gadgets (at run-time) to effect call to write
Blind ROP
(by compiling for position independence) on a 64- bit machine makes attacks very difficult
versions of executables
If server restarts on a crash, but does not re-randomize: 1.Read the stack to leak canaries and a return address 2.Find gadgets (at run-time) to effect call to write 3.Dump binary to find gadgets for shellcode
http://www.scs.stanford.edu/brop/
Defeat!
automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server
Defeat!
automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server
with full stack canaries and randomization
Defeat!
automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server
with full stack canaries and randomization
Defeat!
automatically, only through remote interactions, develop a remote code exploit for nginx, a popular web server
with full stack canaries and randomization
void safe() { char buf[80]; fgets(buf, 80, stdin); } void safer() { char buf[80]; fgets(buf, sizeof(buf), stdin); }
void safe() { char buf[80]; fgets(buf, 80, stdin); } void safer() { char buf[80]; fgets(buf, sizeof(buf), stdin); } void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
void safe() { char buf[80]; fgets(buf, 80, stdin); } void safer() { char buf[80]; fgets(buf, sizeof(buf), stdin); } void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
int i = 10; printf(“%d %p\n”, i, &i);
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
caller’s stack frame printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
caller’s stack frame printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
caller’s stack frame printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
specified in the format string
caller’s stack frame printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
specified in the format string
caller’s stack frame printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
specified in the format string
caller’s stack frame printf’s stack frame
int i = 10; printf(“%d %p\n”, i, &i);
0xffffffff 0x00000000
&i 10 %eip %ebp &fmt …
specified in the format string
void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
“%d %x"
void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
caller’s stack frame 0xffffffff 0x00000000
%eip %ebp &fmt …
“%d %x"
void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
caller’s stack frame 0xffffffff 0x00000000
%eip %ebp &fmt …
“%d %x"
void vulnerable() { char buf[80]; if(fgets(buf, sizeof(buf), stdin)==NULL) return; printf(buf); }
caller’s stack frame 0xffffffff 0x00000000
%eip %ebp &fmt …
“%d %x"
0.125 0.25 0.375 0.5 2002 2004 2006 2008 2010 2012 2014 2016
% of vulnerabilities that involve format string bugs
http://web.nvd.nist.gov/view/vuln/statistics
What’s wrong with this code?
#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); }
What’s wrong with this code?
#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n);
What’s wrong with this code?
#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;
What’s wrong with this code?
#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;
Negative
What’s wrong with this code?
#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;
Ok Negative
What’s wrong with this code?
#define BUF_SIZE 16 char buf[BUF_SIZE]; void vulnerable() { int len = read_int_from_network(); char *p = read_string_from_network(); if(len > BUF_SIZE) { printf(“Too large\n”); return; } memcpy(buf, p, len); } void *memcpy(void *dest, const void *src, size_t n); typedef unsigned int size_t;
Ok Negative Implicit cast to unsigned
What’s wrong with this code?
void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }
What’s wrong with this code?
void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }
HUGE
What’s wrong with this code?
void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }
HUGE Wrap-around
What’s wrong with this code?
void vulnerable() { size_t len; char *buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }
HUGE Wrap-around Takeaway: You have to know the semantics
0.5 1 1.5 2 2.5 2002 2004 2006 2008 2010 2012 2014 2016
% of vulnerabilities that involve integer overflows
http://web.nvd.nist.gov/view/vuln/statistics