Memory Vulns Delalleau
Memory Vulns Delalleau
vulnerabilities
System, compiler, and application issues
Gaël Delalleau
gael.delalleau@beijaflore.com
gael.delalleau+csw@m4x.org
http://www.beijaflore.com
CancSecWest 2005
Vancouver – May 4-6
OS, cc
issues ► Operating systems & compilers security issues
Exploiting
more bugs ► Exploiting unexploitable bugs
Application
flaws ► Application flaws dealing with large data sizes
► Naive view
► Naive view memory protections
► Solaris 10
► FreeBSD 5.3
► Linux 2.6
Unmapped memory
brk()
Dynamically allocated data: “heap”
Static data
Mapped from executable
Executable code file at a static address
Unmapped memory
00000000
Static data
Mapped from executable
Executable code file at a static address
▐ Additional mappings
► Dynamic libraries: code and data
► Additional heaps and stacks (threads...)
► Anonymous memory (mmap, VirtualAlloc...)
► Shared memory (IPC)
► Files mapped in memory
► System mappings: PEB, TEB (Windows), vsyscall (Linux), ...
mmap
4 Gb
stack
heap
Solaris 10 / x86
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Upper and lower limits of the heap
08050000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
Linux 2.6
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128 M)
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
FreeBSD 5.3
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
Mmap area “from bottom to top”
[fragmented]
Heap growing up [continuum]
2 Gb
Limit between heap and mmap area
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
Operating systems and compilers
security issues
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
Linux 2.6
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
Linux 2.6
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
Linux 2.6
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
Linux 2.6
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
Stack growth
needed by %esp lies in
application heap mapping
1 Gb
(for purists: the
stack and heap
VMAs don't
overlap)
08048000
00000000 Large memory management vulnerabilities
OS, cc
issues
Heap / stack overlap Demo
▐ Exploiting mod_php 4.3.0 on Apache 2.0.53
► Goal: execute assembly code from a restricted PHP script
► Allows for breaking out of safe_mode
► Needs ability to allocate ~3 GB of memory
Enough RAM + swap
Disabled PHP memory_limit option, or use a memory leak
▐ Exploit scenario
► Allocate large blocks of memory with emalloc() => malloc()
► Call recursive function many times
the stack “goes down” and overlap with one of the allocated block
R/W access to this block == R/W access to stack memory :-)
Modify a saved EIP address in stack to point to shellcode and return
Large memory management vulnerabilities
OS, cc
issues
Vulnerability Status
for heap / stack overlap
► Linux 2.4 SAFE
► Linux 2.6 UNSAFE
► FreeBSD 5.3 MMAP UNSAFE
► OpenBSD 3.6 SAFE (but...)
► Linux emulation on FreeBSD 5.3 UNSAFE
► Linux emulation on OpenBSD 3.6 SAFE (but...)
► Solaris 10 / x86 SAFE
► Solaris 9 / Sparc SAFE
► Windows XP SP1 SAFE
► AnyOS with certain uncommon UNSAFE
threading libraries
Large memory management vulnerabilities
OS, cc
issues
Jumping the stack gap
▐ Protection with gap or guard page: unsafe
► A few KB under the stack are protected by the OS
No other mapping can lie there
OS grows the stack mapping if a GP fault happens below the stack
If the stack can't be grown a SIGSEGV is delivered
► BUT: the application controls the stack pointer, not the OS
Local (“automatic”) variables allocation on function calls
Usage of alloca()
▐ Vulnerability is not in the application C code...
▐ ... but may be introduced by the compiler
%esp
%esp - 10008
int
f(char *src) {
char buffer1[5000];
char buffer2[5000];
memcpy(buffer2, src, 5000);
...
return 0;
}
Other mappings
%esp
Other mappings
%esp
%esp - 10008
Heap or int
other f(char *src) {
interesting char buffer1[5000];
mappings char buffer2[5000];
allocated
just under
memcpy(buffer2, src, 5000);
the stack ...
return 0;
}
%esp
mmap
4 Gb
stack
heap
Solaris 10 / x86
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Upper and lower limits of the heap
08050000
00000000 Large memory management vulnerabilities
FFFFFFFF
4 Gb
Linux 2.6
mmap
stack
heap
ELF
libs
ELF mapping : code segment [r-x]
ELF mapping : data segment [rwx]
3 Gb
“top down” mmap area [fragmented]
2 Gb
Lower limit of the stack (default 128
M)
Mapping forbidden
1 Gb Mapping allowed
08048000
00000000 Large memory management vulnerabilities
Exploiting
more bugs
Example
▐ Sample vulnerable code
/* Let's copy 'userdata' into 'buffer' */
size = strlen(userdata) + 1;
buffer = (char *) malloc(size); // no check of return value
memcpy(buffer, userdata, size); // buffer may be 00000000
TEB N-1
TEB N
► System limitations
► Network limitations
► Protecting ourselves
▐ Resource limitations
► Stack size, data size, total VM size...
▐ Allocation speed
► RAM is quick even for GBs
► Becomes quite slow (minutes) when switching to disk swap