In this post, we are going to talk about Address Space Layout Randomization (ASLR) and a way to bypass this protection measure. We have reproduced this methodology on Android through the exploitation of an old CVE; however, it is possible to apply it in other contexts as well. Let’s go and see what it is all about!
ASLR: an overview
Address Space Layout Randomization (ASLR) is a protection measure against attacks that exploit memory corruption vulnerabilities. It consists of randomizing the addresses of the memory areas associated with a process; for example, the executable bases and locations of the stack, heap, and libraries will change with each execution of the process.
In this way, it becomes much more difficult for an attacker to predict the address of a particular function or data structure. Throwing an exception or crashing the system could be caused by executing arbitrary code that accesses an incorrect address. In conclusion, ASLR is a protection technique born mainly to mitigate buffer overflow or buffer overrun attacks.
Bypass through function address inference
In this section, we explain a technique to bypass ASLR protection. Before explaining this, we need to meet some initial requirements that highlight the situation in which this method can be applied.
Suppose we are in the following situation:
- firstly, we have successfully exploited an information leak vulnerability (for example, a memory disclosure of a particular process);
- we get to know the area of disclosed memory;
- and, finally, we have the possibility to analyze in detail the memory addresses obtained.
We are assuming, then, that we have access to the device’s memory and can perform a static analysis using reverse engineering tools. If these initial requirements are satisfied, we can move on to the next paragraph to see a procedure that allows us to bypass ASLR protection.
The idea behind this methodology is as follows: each time a process runs, ASLR maps it to a different address. However, between executions, the offsets between a specific function and the base address and also those between the functions themselves remain constant. This can be exploited to determine the address of a given function at runtime.
To clarify this concept, let’s take a library of a specific process and make the following considerations:
- the library has a function A mapped to address 0x1000 and a function B mapped to address 0x5000;
- the base address will change each time the process runs with ASLR; however, we still have these values constant:
- offset of function A and function B from the base address;
- offset between function A and function B (equal to 0x4000 in this simple example).
Basically, then, all we need is to understand if, from the exploit of information leakage, we can identify addresses that point to specific functions. In case these addresses are always present, it is possible to perform the following steps to bypass ASLR protection:
- use a reverse engineering tool to disassemble the target library, such as IDA PRO or Ghidra;
- retrieve memory addresses related to specific functions and evaluate offsets from the base;
- calculate offsets between functions;
- compare these offsets with those obtained from the memory leak.
In the next section, we show a practical example of this approach.
Reproduction on an old CVE
The technique explained above was tested on Android devices by exploiting an old vulnerability. Specifically, we have used the CVE-2017-0785 present in the Bluetooth implementation on Android. This vulnerability is an information leak related to the Service Discovery Protocol (SDP) fragmentation mechanism. SDP allows a client to determine what services are available on a server and their characteristics. For example, when connecting a phone to a Bluetooth headset, SDP will be used to determine which headset supports Bluetooth profiles and which parameters are needed to connect. In addition, a detailed paper on the exploitation of this vulnerability is available here.
By exploiting CVE-2017-0785, it is, therefore, possible to obtain a large part of the stack related to the process that handles Bluetooth. In this case, the process in question is com.android.bluetooth and we highlight a memory address that we use to demonstrate the procedure.
By repeating the exploit of CVE-2017-0785 several times, we always found the memory addresses of the following functions:
- btu_general_alarm_cb, alarm_set, sdp_disconnect_ind (present in bluetooth.default.so)
- init_thread, pthread_start, clone (present in libc.so)
At this point, we replicate the steps explained above by examining bluetooth.default.so:
- disassemble the shared object;
- calculate the offsets from the base address of btu_general_alarm_cb, alarm_set and sdp_disconnect_ind;
- estimate the offsets between the functions themselves;
- for each address, evaluate the offsets with all others (in our example, we only show the offsets obtained for address 0xf2f93903);
- compare the offsets obtained from the static analysis with those of the run-time memory leak.
In this way, we are able to obtain the base address of the library from the information obtained from the memory leak.
In summary, we discussed the ASLR protection measure and a methodology to bypass it under certain initial requirements. This technique should have a great success rate for identifying the base address of a library at run-time. In one of the later posts, we will take the exploit of this vulnerability to show how to reproduce a cyber kill-chain on the Dockerized Android framework. If you still don’t know what it’s all about, we recommend you take a look here.