note: this grimoire is not maintained anymore!
draft by Thomas Houssin
Creation of this grimoire was decided in bug #8670. The Hardened Grimoire is currently work in progress. It's usable, but there are probably some bugs left.
Quickstart
Adding the hardened grimoire
The hardened grimoire is not a full grimoire. It redefines several spells, to add new patches, features, etc. That's why you still need a full grimoire (test, stable-rc or stable) behind the hardened grimoire.
To begin to use the hardened grimoire, just do scribe add hardened. scribe index should then give you something like :
[0] : hardened : /var/lib/sorcery/codex/hardened [1] : test : /var/lib/sorcery/codex/test [2] : z-rejected : /var/lib/sorcery/codex/z-rejected [3] : games : /var/lib/sorcery/codex/games
Choosing the features
Then cast the hardened-profile spell. It'll let you choose various features.
This will then trigger a run_script, to recast needed spells based on your choices. Do not try to avoid this step, or it may lead to a broken box. If you choose to use SSP and/or PaX, it's a good idea to rebuild everything to benefit of the protection, and and ensure everything will work as expected. sorcery rebuild is a good way... You can then rebuild your kernel.
Rebuilding the kernel
To rebuild the kernel, recast linux : cast -r linux. Latest supported kernel is version 2.6.11.12 (only 2.6 kernel is supported).
The following patches are available :
- frandom: it's a very good idea to apply this one. This will create to additional devices : /dev/erandom and /dev/frandom, used to generate random numbers. They're used in several places, including SSP. Not using this patch will not break anything, but will probably slow down the box. Do not forget to make /dev/erandom and /dev/frandom world-readable. If you're using udev, create a file 00-local.rules in /etc/udev/rules.d with :
# permissions
KERNEL="erandom", OWNER="root", GROUP="root", MODE="0644"
KERNEL="frandom", OWNER="root", GROUP="root", MODE="0644"- grsecurity: apply this one if you want to use the additional features provided by grsecurity or PaX.
Available features
PIE
By default, gcc and g++ use special specs. gcc -fPIC, ld -pie, and cpp -D_PIC -DPIC are used by default to build dynamical programs. -z relro and -r now are also user by default. Moreother, if you choose to use SSP, -fstack-protector-all can also be used by default. Unsupported flags are disabled in the spells. If you find a spell where it should, please report a bug.
Other available features are:
Stack Smashing Protector
Stack Smashing Protector It was developed for protecting applications from stack smashing attacks (mainly linear buffer overflows). This is done by adding some code at compilation time. This will typically gives a performance loss around 2% at run time.
This feature needs gcc and glibc to be recompiled. Patches mainly come from HLFS. The patch for glibc adds _guard_setup and _stack_smash_handler to libc.so. _guard_setup is a function used to create a unique and random value for _guard each run time. In the event of a stack overflow, the _stack_smash_handler function will use the glibc syslog facility to record the overflow, and will then abort the program. More information, see http://www.research.ibm.com/trl/projects/security/ssp/
Be aware that using -O3 optimisations and SSP can be problematical. You should disable speedy in the optimisations menu ; if you want to optimize your apps, add -O2 to the custom CFLAGS and CXXFLGAS.
GRSecurity
grsecurity This kernel patch offer various new features, such as chroot restrictions, /tmp race prevention, extra logging, ...
PaX
PaX With this, you'll benefit from non-executable stack and address space layout randomisation. Used with PIE programs, ASLR randomize their return addresses. This can prevent security bugs from being taken advantage of by attackers. Non-executable stack can prevent injected code from being executed. Most of PaX features can be disabled on a per file basis. This is done by adding PT_PAX_FLAGS to the program headers (binutils is patched to do this in the hardened grimoire), and can be tweaked thanks to the paxctl program. (binary only executables can use the EI_PAX old header marking scheme, and chpax utility). For few programs, some features need to be disabled. These are taken care in the spells.
- paxctl -m ${INSTALL_ROOT}/usr/X11R6/bin/Xorg
- paxctl -spm ${INSTALL_ROOT}/sbin/grub
- chpax -rm /usr/lib/jdk$VER/bin/java
- chpax -m /usr/lib/jdk$VER/bin/javac chpax -m /usr/lib/jdk$VER/bin/javadoc
If you find other spells that need suchs precautions, please report a bug. The further informations, http://pax.grsecurity.net/docs/index.html is a good place.
Using these settings in the kernel is a good beginning :
[ ] Support soft mode`
[*] Use legacy ELF header marking
[*] Use ELF program header marking
MAC system integration (none) --->
[*] Enforce non-executable pages
[*] Paging based non-executable pages
[*] Segmentation based non-executable pages
Default non-executable page method (SEGMEXEC) --->
[ ] Emulate trampolines
[*] Restrict mprotect()
[ ] Disallow ELF text relocations
[*] Address Space Layout Randomization
[*] Randomize kernel stack base
[*] Randomize user stack base
[*] Randomize mmap() base
--- Disable the vsyscall page
Work in progress
This grimoire plans to add support for :
SELinux : see http://wiki.sourcemage.org/index.php?page=SMGL+SELINUX for the status of the work.
RSBAC : http://www.rsbac.org/
How to test
You can use the following code (from HLFS) for a quick test:
cat > test.c << "EOF"
#include <stdio.h>
#include <unistd.h>
extern long __guard[];
int overflow(char *test) {
char buffer[7];
sprintf(buffer, "12345678901234567890123456789012345678901234567890");
return(1234);
}
int main(int argc, char **argv) {
printf("__guard\\t=\\t0x%08x;\
", __guard[0]);
overflow("test");
printf("This line should never get printed.\
");
}
EOFCompile it with gcc and run it :
# gcc -o test test.c # ./test
You'll have something like :
__guard = 0x6c8f1eec; test: stack smashing attack in function overflow() Abandon
You'll also have a line in your log file:
[test] test: stack smashing attack in function overflow()
you can check that this application is dynamically linked with readelf -l test:
Elf file type is DYN (Shared object file)
Entry point 0x684
There are 9 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x00120 0x00120 R E 0x4
INTERP 0x000154 0x00000154 0x00000154 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x00000000 0x00000000 0x00ab0 0x00ab0 R E 0x1000
LOAD 0x000edc 0x00001edc 0x00001edc 0x00130 0x00134 RW 0x1000
DYNAMIC 0x000ef0 0x00001ef0 0x00001ef0 0x000d8 0x000d8 RW 0x4
NOTE 0x000168 0x00000168 0x00000168 0x00020 0x00020 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
GNU_RELRO 0x000edc 0x00001edc 0x00001edc 0x00124 0x00124 R 0x1
PAX_FLAGS 0x000000 0x00000000 0x00000000 0x00000 0x00000 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
03 .ctors .dtors .jcr .dynamic .got .data .bss
04 .dynamic
05 .note.ABI-tag
06
07 .ctors .dtors .jcr .dynamic .got
08First line shows that file type is Shared object file. Also note the additional GNU_RELRO and PAX_FLAGS (if you choose to use PaX) headers.
You can check for -z now with readelf -d test | grep BIND_NOW:
0x00000018 (BIND_NOW)
Hopefully a PaX test suite will be available soon.
