Enhancing System Security Through Diversity Strategies
E N D
Presentation Transcript
Papers • S. Forrest, A. Somayaji, and D. Ackley. "Building Diverse Computer Systems", HotOS (1997). paper • PaX Team, "Documentation for the PaX project", link • A. van de Ven, "New Security Enhancements in Red Hat Enterprise Linux v. 3, update 3", paper
Diversity • Adds robustness in biological systems • Ecosystem vulnerabilities if only a few species are dominant (fires, disease, infestations) • Health problems when there is low genetic diversity in species • Disease propagation in population if immunological defenses are not diverse • Computer system homogeneity • Leads to worms and viruses • Tension with compatibility and portability • Apply randomization to add diversity transparently
Papers • S. Forrest, A. Somayaji, and D. Ackley. "Building Diverse Computer Systems", HotOS (1997). paper • PaX Team, "Documentation for the PaX project", http://pax.grsecurity.net/docs/index.html • A. van de Ven, "New Security Enhancements in Red Hat Enterprise Linux v. 3, update 3", http://www.redhat.com/f/pdf/rhel/WHP0006US_Execshield.pdf
Overall strategy • Avoid unnecessary consistency • Compiler strategy • All but the lowest-level tasks are implemented in a high-level programming language • Each program can have many correct translations into machine code • Each aspect of a programming language that is “arbitrary” or “implementation-dependent” can be targets for randomized compilation techniques • Compilation includes machine code generation as well as load-time and execution-time transformations
Issues • Correctness • Preserve high-level functionality • Effectiveness • Add to places most often attacked • Efficiency • Minimize run-time performance cost
Approaches • Add or delete nonfunctional code • NOOPs or other sequences • Must make sure compiler does not optimize them out • Reordering code • Rearrange basic blocks of compiled code in random order (different locations, same execution order) • Use parallel processing techniques to identify code blocks that can be run simultaneously (and can thus be reordered) • Do the same within code blocks (instruction reordering)
Approaches • Memory layout • Pad each stack frame by random amount • Randomize locations of global variables • Assign new stack frames a random location (instead of next contiguous location) • Treats stack as a heap and increases memory management overhead
Approaches • Others • Process initialization crt0.o, command-line arguments, environment variables (kernel changes) • Dynamic libraries • System calls • System files • Bad for system administrators • Magic numbers in certain files (executables) • Marks external executables versus native ones • Randomized run-time checks • Random array bounds checking
Implementation • gcc and random padding in stack frame • Disrupts simple attack against lpr
NOEXEC • Prevent injection and execution of code • Prevent new writable/executable mappings • Separation writable and executable properties on memory pages • Applies to executable file mappings as well (breaks some applications) • Prevent writable/non-exec from going to executable • Least privilege enforcement • If data in address space does not need to be executable, it should not be (via marking such pages) • If applications do not need to generate code at run-time, it should not be able to • Support on most MMUs on CPUs except IA-32 • All stack, heap, and anonymous mappings are non-execute • Only ELF segments holding code will be executable
ASLR • Address Space Layout Randomization • Applied to entire memory space • Main executable code/data/bss segments • brk() managed memory (heap) • mmap() managed memory (libraries, heap, thread stacks, shared memory) • User stack • Kernel stack
PAGEEXEC • Non-executable page feature using paging logic of IA-32 CPUs • Need hack since IA-32 MMU doesn't support execution protection in hardware yet • Use split TLB for code/data in Pentium CPUs • Software control of ITLB/DTLB loading • Mark all non-executable pages as either not present (causing a page fault) or requiring supervisor level access (overload no-exec with supervisor mode) • Modify page fault handler accordingly to terminate task
SEGMEXEC • Implement non-executable pages via segmentation logic of IA-32 • Split 3GB userland address space into half • Define data segment descriptor to cover one half • Define code segment descriptor to cover other half • Need mirroring since executable mappings can be used for data accesses • Place copies of executable segments within data range • Instruction fetching from data space will end up in code segment address space and raise a page fault • Page fault handler can terminate task
MPROTECT • Prevent introduction of new executable code into address space via restrictions on mmap() and mprotect() • Prevent the following • Creation of anonymous mappings • Creation of executable/writable file mappings • Making an executable/read-only file mapping writable except for performing relocations on an ET_DYN ELF file • Making a non-executable mapping executable
RANDUSTACK • Randomize user stack on task creation • exec.c: do_execve() • Randomize bits 2-11 (4kB shift) • setup_arg_pages() • Randomize bits 12-27 (256MB shift) for copying previously populated physical stack pages into new task's address space • create_elf_tables() • Aligns stack pointer on 16-byte boundary (throws away randomization in bits 2-3 • Result is bits 4-27 randomized
RANDKSTACK • Randomizes every task's kernel stack pointer before returning from a system call to userland • Two pages of kernel stack allocated to each task • Used whenever task enters kernel • Kernel land stack pointer will always end up at the point of the initial entry to the kernel • Attack against kernel bug from userland could rely on this • Entropy from rdtsc() applied to bits 2-6 (128 byte shift)
RANDMMAP/RANDEXEC • Randomness into memory regions of do_mmap() kernel interfact • All file and anonymous mappings • Main executable of ET_DYN type, libraries, brk() and mmap() heaps • Need big memory hole • Randomize bits 12-27 • Randomness into main executable • Main executable of ET_EXEC type • Use of absolute addresses • Must provide a file mapping of ET_EXEC file at original base address • Mirror executable regions
ExecShield • Rolled into Linux 2.4.20
No-execute regions • Use segment size limits to emulate page table execute permission bits • Generalized form of SolarDesigner’s no-exec stack patch • Cover other areas as well as stack • Kernel keeps track of maximum executable address “exec-limit” • Process-dependent • Remap all execute regions to “ASCII armor” • Contiguous addresses at beginning of memory that have 0x00 (no string buffer overruns) • 0x0 to 0x01003fff (around 16MB) • Stack and heap are non-executable as result
Example • Compare this with the memory layout without exec-shield: • 08048000-0804b000 r-xp 00000000 16:01 3367 /bin/cat0804b000-0804c000 rw-p 00003000 16:01 3367 /bin/cat0804c000-0804e000 rwxp 00000000 00:00 040000000-40012000 r-xp 00000000 16:01 3759 /lib/ld-2.2.5.so40012000-40013000 rw-p 00011000 16:01 3759 /lib/ld-2.2.5.so40013000-40014000 rw-p 00000000 00:00 040018000-40129000 r-xp 00000000 16:01 4058 /lib/libc-2.2.5.so40129000-4012f000 rw-p 00111000 16:01 4058 /lib/libc-2.2.5.so4012f000-40133000 rw-p 00000000 00:00 0bffff000-c0000000 rwxp 00000000 00:00 0 • In this layout none of the executable areas are in the ASCII-armor, plusthe exec-limit is 0xbfffffff (3GB) - ie. including all userspace mappings. • Note that the kernel will relocate every shared-library to the • ASCII-armor, but the binary address is determined at link-time. To easethe relinking of applications to the ASCII-armor, Arjan Van de Ven haswritten a binutils patch (binutils-2.13.90.0.18-elf-small.patch), whichadds a new 'ld' flag "ld -melf_i386_small" (or "gcc -Wl,-melf_i386_small")to relink applications into the ASCII-armor.
Example • With exec-shield • $ ./cat-lowaddr /proc/self/maps00101000-00116000 r-xp 00000000 03:01 319365 /lib/ld-2.3.2.so00116000-00117000 rw-p 00014000 03:01 319365 /lib/ld-2.3.2.so00117000-0024a000 r-xp 00000000 03:01 319439 /lib/libc-2.3.2.so0024a000-0024e000 rw-p 00132000 03:01 319439 /lib/libc-2.3.2.so0024e000-00250000 rw-p 00000000 00:00 001000000-01004000 r-xp 00000000 16:01 2036120 /home/mingo/cat-lowaddr01004000-01005000 rw-p 00003000 16:01 2036120 /home/mingo/cat-lowaddr01005000-01006000 rw-p 00000000 00:00 040000000-40001000 rw-p 00000000 00:00 040001000-40201000 r--p 00000000 03:01 464809 locale-archive40201000-40207000 r--p 00915000 03:01 464809 locale-archive40207000-40234000 r--p 0091f000 03:01 464809 locale-archive40234000-40235000 r--p 00955000 03:01 464809 locale-archivebfffe000-c0000000 rw-p fffff000 00:00 0 • In the above layout, the highest executable address is 0x01003fff, ie.every executable address is in the ASCII-armor.
RHEP add-ons • Use of NX bit in subsequent CPUs • Randomization • Stack itself • Locations of shared libraries • Start of program’s heap • Want to randomize location of application code • But, many are compiled w/ absolute address information • PIE = position-independent executable