Posted by Steve on Fri 23 Jun 2006 at 14:02
Since we last covered the use of Stack Smashing Protection (SSP) the default compiler for Debian Sid has been upgraded to include it, with no need for custom patching. Read on for a brief demonstration of how it can be used to prevent attacks.
The default C compiler for Sid, which will be used in Etch too, is GCC v4.1. This releasecontains the SSP patch which previously needed to be applied manually (we demonstrated applying this patch for GCC v3.4 a long time ago).Since the SSP patch is included in the compiler by default it is suddenly a lot easier to start working with it.
A vulnerable Program
Preventing This Attack With SSPLets look at an example first of all, this is a common sample of a vulnerable C program:
#include <stdio.h> #include <stdlib.h> int main( int argc, char *argv[] ) { // Static buffer on the stack. char buffer[1024]; if ( argc != 2 ) { printf("Usage: %s argument\n", argv[0] ); return( -1 ); } // Unbound string copy. strcpy( buffer, argv[1]); printf( "Copied argument\n" ); return(0); }This simple program accepts one argument and copies it into a static buffer. This is a classic programming mistake, and were this program compiled into a setuid/setgid binary it would easily allow an attacker to gain enhanced privileges.
Since we're going to highlight the new facilities of the newer compiler be sure to compile this example with gcc-3.3.
To test this program compile it as normal:
skx@desktop:/tmp$ gcc-3.3 -o buggy buggy.cNow lets see if we can break it. First of all two test executions:
skx@desktop:/tmp$ /tmp/buggy Usage: /tmp/buggy argument skx@desktop:/tmp$ /tmp/buggy test Copied argumentBoth of these runs worked as expected. Now lets try passing a large argument to see if we can overflow the static buffer:
skx@desktop:/tmp$ ./buggy `perl -e 'print "X"x2048'` Copied argument Segmentation faultSuccess: we overflowed the buffer with our 2k argument, and we resulted in a segmentation fault. If we can produce a core file we can debug this:
skx@desktop:/tmp$ ulimit -c 09999999 skx@desktop:/tmp$ ./buggy `perl -e 'print "X"x3333'` Copied argument Segmentation fault (core dumped)Running gdb we can now look at the program:
skx@desktop:/tmp$ gdb ./buggy core GNU gdb 6.4.90-debian ... Program terminated with signal 11, Segmentation fault. #0 0x58585858 in ?? () (gdb) info registers eip eip 0x58585858 0x58585858Here we see the instruction pointer is at 0x58585858 (the hex for 'X' is 0x58). This means we've effectively taken control of the binary with our malicious input.
From here to actually exploiting the binary to run a shell is trivial and can frequently be automated:
skx@desktop:~/cvs/cmd-overflow$ make gcc-3.3 -o cmd-overflow -Wall -ggdb cmd-overflow.c gcc-3.3 -o cmd-vuln -Wall -ggdb cmd-vuln.c skx@desktop:~/cvs/cmd-overflow$ ./cmd-overflow --target=/tmp/buggy --args='%' --size=2048 Copied argument sh-3.1$ id uid=1000(skx) gid=1000(skx) groups=29(audio),44(video),46(plugdev),100(users),1000(skx) sh-3.1$ exit exitHere we used a simple program to create an argument of length 2048 bytes which contains the code required to run a shell, then invoked our buggy program with this constructed argument.
The buffer was then overflowed and our code ran, this resulting in a shell being executed. ("Shellcode"). Had our buggy program been setuid we'd have gained root privileges!
Note:
Starting sometime in the life of the Linux 2.6.x kernel series a new security measure was introduced, to randomise heap addresses. If you're running such a kernel all of these examples will fail.
To disable this protection run:
root@desktop:~# sysctl -w kernel.randomize_va_space=0This will allow you to experiment with buffer overflows, whilst avoiding the need to use advanced exploitation techniques. (Which can be a lot of fun if you're bored :)
Now that Debian contains the 4.1 compiler we can use the new -fstack-protector argument to compile in automatic buffer overflow protection.
Before we do this we'll need to install a new package:
desktop:~# apt-get install libssp0-dev Reading package lists... Done Building dependency tree... Done The following extra packages will be installed: libssp0 Suggested packages: lib64ssp0 The following NEW packages will be installed libssp0 libssp0-devOnce this is installed we can recompile our buggy program:
skx@desktop:/tmp$ gcc-4.1 -fstack-protector -o buggy buggy.c buggy.c: In function ��main��: buggy.c:16: warning: incompatible implicit declaration of built-in function ��strcpy��This binary should now be protected against simple buffer overflows. Let us test it as we did before:
skx@desktop:/tmp$ ./buggy `perl -e 'print "x"x2048';` Copied argument *** stack smashing detected ***: xxxx .. xxxx terminated Illegal instructionNeat, huh?
Now we'll try to repeat the exploitation which succeeded previously:
skx@desktop:~/cvs/cmd-overflow$ ./cmd-overflow --target=/tmp/buggy --size=2048 --args='%' Copied argument *** stack smashing detected ***: terminated Illegal instructionIt all looks good, and the protection works as designed. (Note that this protection will not help against "advanced" exploitation, such as return into libc.
Using this library you can add simple buffer overflow protection to your binaries with only a minor performance hit. If you maintain a package it might be worth rebuilding using this support to see how well it works in practise.
Rebuilding all the packages on security-critical host might be something worth trying, now that the tools are easily available.
There are papers discussing weaknesses in stackguard, ssp, and similar technologies. The first one I came across with a quick search was this one - caution PDF.
Some of the references aren't valid, but sites such as Phrack have covered this stuff previously too.
[ Parent ]
[ Parent ]
I'd love to see it personally. The only way I see it happening is if many maintainers would test their packages with the new flag and see what breaks.
The more people that test it the better chances we have of making it the default behaviour; hence this introduction.
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
All of this stuff is common knowlege to people who are interested in the topic, so I'm going to assume your sarcasm wasn't terribly serious.
After reading Aleph One's classic paper a good thing to read next is something about format string attacks, something I still struggle to exploit but other people can manage just fine!
[ Parent ]
[ Parent ]
Fair enough, I read your comment it in a sarcastic fashion, but I guess it is hard to tell a lot of the time.
Nice collection of footnotes!
For what its worth I think helping the kiddies actually do things for themselves rather than rely upon pre-cooked exploits is only liable to make them experiment more, and grow out of it. I guess that is part of the reason I rarely provide exploit code when I report vulnerabilities nowadays.
[ Parent ]
[ Parent ]
I'd be happy to post a poll like that, but the options are way too long + complex.
Wanna try a simpler one?
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
In the years since the code the kernel has had changes - asrl, and the compilers have ssp in by default. This article should be ignored.
If you want to make it work you'll need to study hard..
[ Parent ]
[ Parent ]
You have a segfault? You have a debugger? Thats what you should study in this case..
[ Parent ]
[ Parent ]
[ Parent ]