Concept: Virtual Memory
Modern architectures use virtual memory to separate process memory spaces. There are a number of resources online to catch up on the basics [1,2]. This page deals with virtual memory concepts relevant to cybersecurity.
Memory is mapped in a number of ways:
- By applications, using the
mmapfamily of system calls.
- By the program loader, using
mmapto map programs into memory.
- By the kernel, when allocating space for the stack and other necessary parts of a process.
In modern systems, most allocations are at random addresses for security purposes (see ). Fixed addresses are still used for two purposes:
- When loading programs that are not Position Independent into memory.
- To map memory at a specific address due to custom application behavior.
Fixed mapping is accomplished by passing the
MAP_FIXED argument to
Aside from being
0x1000 in size, pages are also aligned to
That is, the base address of any page will always end in three null nibbles.
For example, potential page addresses are:
0x00007ffcff1b1000(library code is frequently mapped at
0x55ea43e0b000(PIE executables are typically loaded at
0x555555554000(the base address that GDB uses when use it to load a PIE executable)
0xffffffffff600000(typical location of
vsyscall, a page that is shared between the kernel and program for performance reasons )
You can look at what pages a process has mapped by doing:
cat /proc/$PID/mapswith the process’ PID
pmap $PIDwith the process’ PID
info proc mapsinside GDB
Weaknesses in Page Address Selection
While modern systems tend to map pages at random locations, recent research has shed light on a problem: the random location is chosen once per process, and, by default, other pages tend to be mapped contiguously to that location . This is a problem for all shared libraries, and many other types of mapped pages, though typically, the main PIE binary itself does not have this issue.
At any rate, this enables a set of potential attacks:
- Having a leak in one library (or many other types of pages) exposes the addresses of all libraries.
- Having a controlled relative write relative to a library location allows you to influence data in any library (along with other allocated data).
Modern operating systems are careful about protecting process memory . Each page has three permission bits:
PROT_READ, which determines whether the process can access memory in the page
PROT_WRITE, which determines whether the process can write memory in the page
PROT_EXEC, which determines whether the process can execute memory in the page
-  https://en.wikipedia.org/wiki/Paging
-  https://www.tldp.org/LDP/tlk/mm/memory.html
-  https://en.wikipedia.org/wiki/Address_space_layout_randomization
-  http://man7.org/linux/man-pages/man2/mmap.2.html
-  https://en.wikipedia.org/wiki/Page_(computer_memory)
-  https://en.wikipedia.org/wiki/Page_(computer_memory)#Multiple_page_sizes
-  https://lwn.net/Articles/446528/
-  https://en.wikipedia.org/wiki/Memory_protection
-  http://man7.org/linux/man-pages/man2/mprotect.2.html
-  https://github.com/kirschju/wiedergaenger