Friday, January 14, 2011

checksec.sh now with FORTIFY_SOURCE support

New checksec.sh release.

What's new with version 1.4:

  * Support for FORTIFY_SOURCE (--fortify-file, --fortify-proc)
  * Lots of other bugfixes and improvements
    - Check if the readelf command is available
    - readelf support for 64-bit ELF files
    - Check if the requested files and directories do exist
    - '--dir' is now case-sensitive and correctly deals with trailing slashes
    - Check user permissions
    - Etc.

► Example of the new '--fortify-file' option

The following testcase is vulnerable to a classical stack buffer overflow (see line 10):
tk@ubuntu$ cat testcase.c
01 #include <string.h>
02 #include <stdio.h>
03
04 int
05 main (int argc, char* argv[])
06 {
07        int     a = 1;
08        char    buf[12];
09
10        strcpy (buf, argv[1]);
11        printf ("%08x\n", a);
12
13        return 0;
14 }
Compile the testcase without stack canary support (-fno-stack-protector) and without FORTIFY_SOURCE:
tk@ubuntu$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.10
DISTRIB_CODENAME=maverick
DISTRIB_DESCRIPTION="Ubuntu 10.10"

tk@ubuntu$ gcc -fno-stack-protector -o testcase testcase.c
Check the executable file with checksec.sh:


The output shows, that FORTIFY_SOURCE is indeed not supported by the executable file. Now we try to overflow the stack buffer:
tk@ubuntu$ ./testcase AAAA
00000001

tk@ubuntu$ ./testcase AAAABBBBCCCCDDDD
44444444
As can be seen from the output, the stack variable 'a' was successfully overwritten with our overly long command line argument ('a' was overwritten by the supplied D's or 0x44 in hexadecimal). Now we compile the testcase with FORTIFY_SOURCE support but without stack canaries and check the executable file with checksec.sh again:
Under Ubuntu FORTIFY_SOURCE is activated when compiled with -O2 or higher. On other Linux distributions (e.g. Fedora or openSUSE) you need to add the compiler flag '-D_FORTIFY_SOURCE=2'.

The output of checksec.sh shows, that the executable file was successfully compiled with FORTIFY_SOURCE. Now we try to overflow the buffer again:
tk@ubuntu$ ./testcase AAAABBBBCCCCDDDD
*** buffer overflow detected ***: ./testcase terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x50)[0x936970]
/lib/libc.so.6(+0xe486a)[0x93586a]
/lib/libc.so.6(__strcpy_chk+0x44)[0x934be4]
./testcase[0x8048447]
/lib/libc.so.6(__libc_start_main+0xe7)[0x867ce7]
./testcase[0x8048381]
======= Memory map: ========
007d4000-007f0000 r-xp 00000000 08:01 135323     /lib/ld-2.12.1.so
007f0000-007f1000 r--p 0001b000 08:01 135323     /lib/ld-2.12.1.so
007f1000-007f2000 rw-p 0001c000 08:01 135323     /lib/ld-2.12.1.so
0080f000-00829000 r-xp 00000000 08:01 131159     /lib/libgcc_s.so.1
00829000-0082a000 r--p 00019000 08:01 131159     /lib/libgcc_s.so.1
0082a000-0082b000 rw-p 0001a000 08:01 131159     /lib/libgcc_s.so.1
00851000-009a8000 r-xp 00000000 08:01 138119     /lib/libc-2.12.1.so
009a8000-009aa000 r--p 00157000 08:01 138119     /lib/libc-2.12.1.so
009aa000-009ab000 rw-p 00159000 08:01 138119     /lib/libc-2.12.1.so
009ab000-009ae000 rw-p 00000000 00:00 0
00ff9000-00ffa000 r-xp 00000000 00:00 0          [vdso]
08048000-08049000 r-xp 00000000 08:01 658356     /home/tk/testcase
08049000-0804a000 r--p 00000000 08:01 658356     /home/tk/testcase
0804a000-0804b000 rw-p 00001000 08:01 658356     /home/tk/testcase
09e50000-09e71000 rw-p 00000000 00:00 0          [heap]
b779f000-b77a0000 rw-p 00000000 00:00 0
b77ae000-b77b0000 rw-p 00000000 00:00 0
bfb00000-bfb21000 rw-p 00000000 00:00 0          [stack]
Aborted

This time the attempt to trigger the buffer overflow was successfully mitigated by FORTIFY_SOURCE.

► Example of the new '--fortify-proc' option

With the new option '--fortify-proc' it is also possible to check running processes for FORTIFY_SOURCE support:


You can download the new version 1.4 of checksec.sh here.