ASLR and friends
Computer Security 2014 – Ymir Vigfusson
Some slides borrowed from David Brumley’s lectures at CMU, and Vitaly Shmatikov’s CS380S
2
Background
In attacks so far, knowing memory addresses is key In regular stack overflows, find the
shellcode buffer In return-to-libc, know the glibc location of
e.g. system() In heap overflows, know location of return
address In format string attacks, know location of
return address In ROP chains, know addresses of the ROP
gadgets
Notice the pattern: (I) Some malicious code or computation to
be run (II) Divert control flow to address of bad
code This family of attacks often called control
flow hijacks
3
Defenses
Addressed concern (I) through DEP/NX Prohibit memory from being
simultaneously writeable and executable (W^X).
Therefore, attackers can‘t inject or create any new code to execute.
What‘s the issue? Defeated by return-to-libc and more
generally ROP Recycle old code in organized, nefarious
ways ROP shown to be Turing-complete (!)▪ Loops and conditional branches
Hovav Shacham. The geometry of innocent flesh on the bone: return-into-libc without function calls (on the x86), CCS 2005.
Return oriented programming
ROP exploit relies entirely
on existing code!
c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c73dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc440dead07beef013ac978f3ff19dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c73badc0dedead07beef013ac978f3ff19dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff19656dead07beef013ac978f3ff196569ba83144cc4401018971c7316569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931cad07beef013ac978f3ff196569ba83144cc44eef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196
5
Computer memory
ff19656dead07beef013ac978f3ff196569ba83144cc4401018971c7316569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931cad07beef013ac978f3ff196569ba83144cc44eef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff1965
c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c73dead07c0ded13ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dea
d07beef013ac978f3ff18f3ff196569ba831018971c7316569ba83144cc4401018971c7316931c9dead07beef01dead07c0ded13ac3ff196569ba83144cbadc0de
d07beef013ac978f3ff18f3ff196569ba831018971c7316569ba83144cc4401018971c7316931c9dead07beef01dead07c0ded13ac3ff196569ba83144cbadc0de
0x0c0c0c0c
6
ROP
Probability of gadgets left in a program being sufficient to spawn a shell (function of prog. size)
Call libc functions in 80% of programs >= true (20KB)
7
Defenses
As defenders, how can we address concern (II)? Diverting control flow to address of malicious
content
One high-level idea: “if we‘re about to run bad code, halt the execution!“ How would you implement this? Determining whether a program will
do a certain thing is undecidable We need some other ideas...
What about making the addresses hard to guess?
8
Defenses
Back in the 2000‘s, worms (self-replicating software) would compromise 100,000s of computers Offsets were the same or similar between all
victims
Prompted research into the topic
PaX team released ASLR in Linux in 2001 Idea: simulate NX bit to address concern (I)
and then make all addresses as random as possible to harden concern (II)
Challenge: be backward compatible with binaries already compiled
9
Address space layout randomization PaX: Randomize base
addresses for: Stack segment Heap segment Code segment Global offset table / PLT
Shifted by random constant x86: 16-bits, 24-bits for
stack amd64: ~40 bits
11
Address space layout randomization PaX is an optional patch (used in grsecurity) A weaker version in Linux kernel (‘05), default since
3.1.1 16-bit randomization of base addresses Kernel parameter kernel.va_randomize_space▪ 0 = No randomization.▪ 1 = Medium randomization: libraries, stack, parts of heap▪ 2 = “Full“ randomization: libraries, stack, all of heap
Text segment [i.e. code], BSS and Data not randomized without PaX
Microsoft default ASLR in Windows Vista (‘07) Initially some bias in the randomization (Black Hat ‘07) Randomization happens at boot time Stack (13-bits), Heap (5 bits), EXE/DLL (8 bits) Only applies to files compiled with /DYNAMICBASE flag
OS X has default ASLR since 2011
12
Brute-force: Chains
What if we have to determine series of addresses? For instance if we need to launch ROP due to NX/DEP
Naive probability calculation:▪ p probability of guessing one address correctly, so must have
probability to guess all k… Assumes you are testing them all at once▪ Often you get (or can get) feedback after intermediate addresses
Remember the Enigma? Break things sequentially▪ Most services use fork() and ASLR does not re-randomize libc for
every child process (why?)▪ Shacham et al.: First try to find location of libc is by returning into
usleep(). Then pivot from there.
Chains normally do not increase difficulty One known address often enough to derandomize
everything!
13
How do we defeat ASLR?
Think about modern, sophisticated software Web browsers, E-mail suites,
Word/Excel/Powerpoint, PDF readers (!), Java, Flash players, ...
Many of these software have internal languages▪ Web browsers: HTML/JavaScript▪ Word/Excel/Powerpoint: Visual Basic▪ Flash: Actionscript (similar to JavaScript)
ASLR normally engages at the start of an execution▪ Thus repeated attacks usually have similar
addresses
How can we overcome ASLR + DEP now?
14
Defeating ASLR
Information leakage about addresses Secondary bugs, format strings, /proc/self/maps, ... Gives us sufficient information to produce offsets! Very common approach in modern exploits
Returning into non-randomized memory jmp *%esp
Executing non-randomized memory Some parts of non-PIE program at fixed locations Not all libraries opt-in to randomization (e.g. JVM)
Brute-force the address How entropic is the ASLR randomization? (x86 32/64-
bit) PaX 64-bit: 40 bits vs. 28 bits on standard Linux
15
NOP sleds revisited
Recall NOP sleds: We put sleds of NOPs in front of shellcode
to reduce guesswork with address offsets
What if we could have tons of NOP sleds and shellcode stored in memory? Increases chances that a random address
contains our malicious payload
16
Heap spraying
Use software to spray NOP sleds all over memory!
Example: JavaScript heap sprayingvar nop = unescape(“%u9090%u9090”)while (nop.length < 0x100000) nop += nop
var shellcode = unescape("%uDEAD%uBEEF%...");
var x = new Array ()for (i=0; i<1000; i++) {
x[i] = nop + shellcode;}
heap
vtable
NOP slide shellcode
17
Heap spraying
Many interesting attack vectors Example: Java Applets disable DEP/NX on
every segment, so load an applet to set up smorgasboard of NOP sleds.
Example: Websites may embed .NET DLLs. Create an exceptionally large one...
Heap Feng Shui (Sotirov ’07) Improve JS heap spraying by noting
that heap allocators are deterministic
Addresses can be made predictable
18
Example
Show you an attack against Windows 7 Found in the wild in 2012 Used to hack the Council of Foreign Affairs
Bypasses DEP by using ROP
Bypasses ASLR by using fixed opcodes from Java Java does not randomize its addresses
Exploit for recent attack
divelm
formelm
button
Use after free
appendChild
used by the system
0c0c0c0c
CVE-2012-4792
Analogy
8256443
c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c73dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc440dead07beef013ac978f3ff19dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c73badc0dedead07beef013ac978f3ff19dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff19656dead07beef013ac978f3ff196569ba83144cc4401018971c7316569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff196569ba83144cc4401018971c7316931cad07beef013ac978f3ff196569ba83144cc44eef013ac978f3ff196569ba83144cc4401018971c7316931c9dead07beef013ac978f3ff1965
Computer memory
used by the system
0c0c0c0c
0x0c0c0c0c
system trusts the reference
therefore, system executes
22
Attack summarized
Program calls malloc(), gets our chunk (still in use)
We put gobs of NOP sleds on heap, so 0x0c0c0c0c likely points at certain offset in a NOP sled
We write 0x0c0c0c0c to a memory address in that chunk later used as a function pointer So no need to know address of saved %eip !
We get CALL *[%eax+0xcd], point to address of instruction xchgl %eax,%esp; ret in Java library Java library is at a fixed location, and executable
We are now executing series of ROP instructions from 0x0c0c0c0c. Some of them will „jump ahead“ using addl %esp, 0xcd
Perform VirtualProtect() using ROP, then shellcode
23
JIT spraying
Just-in-time compilers produce executable code E.g. ActionScript, PDF viewers (Acrobat), ...
Attackers can leverage these instructions kind of like ROP
Allows for gradual creation of shellcode in an executable segment
24
JIT spraying
B8D9D0543C
var y = ( 0x3c54d0d9 ^ 0x3c909058 ^ 0x3c59f46a ^ 0x3c90c801 ^ 0x3c9030d9 …
MOVL %EAX, 3C54D0D9
XORL %EAX, 3C909058
XORL %EAX, 3C59F46A
XORL %EAX, 3C90C801
XORL %EAX, 3C9030D9
355890903C
356AF4593C
3501C8903C
35D930…
compilesinto
25
JIT sprayingB8D9D0543CMOVL EAX, 3C54D0D9
XORL EAX, 3C909058
XORL EAX, 3C59F46A
XORL EAX, 3C90C801
XORL EAX, 3C9030D9
355890903C
356AF4593C
3501C8903C
35D930…
Suppose executionstarts here instead FNOP
PUSH ESP
CMP AL, 35
CMP AL, 35
CMP AL, 35
CMP AL, 35
POP EAXNOPNOP
PUSH -0C
POP ECX
ADD EAX, ECX
NOP
FSTENV DS:[EAX]
Intermediate instructions strike again!