The eighth Chapter ARM uses
Aditya Gupta
Translator: Dragon
Protocol: CC BY-NC-SA 4.0
In this chapter, we will look at the fundamentals of ARM processors and the different types of vulnerabilities that exist in the arm world. We will even continue to exploit these vulnerabilities to get a clear picture of the entire scenario. In addition, we will look at the different Android root attacks and their underlying vulnerabilities in exploit. Given that most Android smartphones now use arm-based processors, it is critical for penetration testers to understand arm and its attendant security risks.
An introduction to 8.1 ARM architecture
ARM is a simplified instruction set (RISC)-based architecture, which means that its directives are much less than machines based on complex instruction sets (CISC). ARM processors are located almost all around our devices, such as smartphones, TVs, e-book readers and more embedded devices.
ARM has a total of 16 visible universal registers starting from R0-r15. Of these 16, 5 are used for a special purpose. Here are five registers and their names:
- R11: Frame pointer (FP)
- R12: In-process register (IP)
- R13: Stack pointer (SP)
- R14: Link Register (LR)
- R15: Program counter (PC)
The following diagram shows the ARM architecture:
In five, we will focus on these three, which are:
- Stack pointer (SP): This is the register that holds the pointer to the top of the stack
- Link Register (LR): Stores the return address when a program enters a sub-procedure
- Program Counter (PC): stores the next instruction to be executed
Attention
One thing to note here is that the PC will always point to the instruction to be executed, rather than simply pointing to the next instruction. This is due to the concept of being called pipelining, which means that instructions will operate in the following order: Extract, Decode, and execute. To gain control of the flow of the program, we need to control the value in the PC or LR (which ultimately directs us to control the PC).
Execution mode
There are two different types of execution modes for ARM:
- Arm mode: In arm mode, all instructions are 32 bits in size
- Thumb mode: In thumb mode, the instruction is mostly 16-bit
The execution mode is determined by the state in the CPSR register. There is also a third mode, the Thumb-2 mode, which is just a mix of ARM mode and Thumb mode. We will not delve into the difference between ARM and Thumb mode in this chapter because it is beyond the scope of this book.
8.2 Setting up the environment
Before you start exploiting the vulnerabilities of the ARM platform, suggest your home environment. Even though the emulator in the Android SDK can be run by simulating the arm platform, most smartphones are arm-based, and we'll start arm exploits by configuring QEMU, which is an open source hardware virtual machine and simulator.
In order to perform all of the following steps on the Android emulator/device, we need to download the Android NDK and compile our binaries for the Android platform using the tools provided in the Android NDK. However, if you are using a MAC environment, it is relatively easy to install QEMU, which you can do by typing brew install qemu
. Now let's configure QEMU on the Ubuntu system. Follow these steps:
The first step is to download and install QEMU by installing dependencies:
sudo apt-get build-dep qemuwget http://wiki.qemu-project.org/download/qemu-1.7.0.tar.bz2
Next, we just need to configure QEMU to specify that the target is ARM and finally take advantage of it. Therefore, we will simply unzip the archive file, access the directory and execute the following command:
.--target-list=arm-softmmu&& make install
Once QEMU has been successfully installed, we can download the Debian image of the ARM platform for use in practice. The list of required downloads is located http://people.debian.org/~aurel32/qemu/armel/
.
-
Here we will download the disk image formatted as Qcow2
, which is the OS image format of the QEMU-based system, that is, our operating system is Debian_squeeze_armel_ Standard.qcow2
. The kernel file should be Vmlinuz-2.6.32-5-versatile
and the RAM disk file should be initrd.img-2.6.32-versatile
. Once we have downloaded all the necessary files, we can launch the QEMU instance by executing the following command:
qemu-< Span class= "Hljs-keyword" >system -arm-m versatilepb-kernel vmlinuz-2.6 Span class= "Hljs-number" >.32 -5 -versatile-initrd initrd.img-2.6 .32 -5 -versatile-hda Debian_squeeze_armel_standard.qcow2-append "root=/dev/sda1" --redir tcp:2222::22
redir
The command only uses port 2222 to enable SSH when you log on to the remote system.
Once the configuration is complete, we can log in to the Debian instance using the following command:
ofQemu2222
You will be asked to enter your user name and password when you log in, and the default credentials are root:root
. Once we have successfully logged in, we will see a screen similar to the following:
8.3 Simple stack-based buffer overflow
Simply put, a buffer is a place to store any type of data. Overflow occurs when the data in the buffer exceeds the size of the buffer itself. An attacker could then perform an overflow attack to gain control of the program and execute a malicious payload.
Let's use an example of a simple program to see how we can use it. In the following, we have a simple program that has three functions: weak
, ShouldNotBeCalled
and main
. Here are the programs we tried to use:
The function is never called during the entire program run ShouldNotBeCalled
.
The vulnerability function simply copies the parameters to a buff
buffer named 10 bytes in size.
Once we have finished writing the program, we can use gcc
it to compile it, as shown in the next command. In addition, we'll disable address space layout randomization (ASLR) here just to make the scene a little simpler. ASLR is a security technology implemented by the OS to prevent attackers from effectively determining the address of a payload and executing malicious instructions. In Android, ASLR is implemented from 4.0 onwards. You can access http://www.duosecurity.com/blog/exploit-mitigations-in-android-jelly-bean-4-1
all Android security implementations.
0/proc/sys/kernel/randomize_va_spacegcc -g buffer_overflow.c -o buffer_overflow
Next, we can simply load the binary file into the GNU debugger, or GDB, and start debugging it, as shown in the following command:
-q buffer_overflow
Now we can use the disass
command to disassemble a specific function, here is ShouldNotBeCalled
, as shown in the following:
As we can see in the above, the ShouldNotBeCalled
function starts from the memory address 0x00008408
. If we look at main
the disassembly of the function, we see the vulnerability function 0x000084a4
being called and 0x000084a8
returning. Therefore, because the program enters the vulnerability function and uses the vulnerable strcpy
, the function does not check the size of the string to be copied, and if we can control the LR of the child procedure when the program enters the vulnerability function, we can control the entire program flow.
The goal here is to estimate when LR is overwritten and then put ShouldNotBeCalled
the address in order to call the ShouldNotBeCalled
function. Let's start with a long parameter run program, as shown in the following command, and see what happens. Before we do that, we also need to strcpy
set breakpoints at the address of the vulnerability function and call.
ofthe strcpy call>
Once we set the breakpoint, we can use the parameters AAAABBBBCCCC
to run our program and see how it is overwritten. We notice that it hits the first breakpoint at the call of the vulnerability function, and then strcpy
hits the next breakpoint at the call. Once it arrives at the breakpoint, we can use the x
command to parse the stack and specify the address from the SP, as shown in the following:
We can see that the stack has been overwritten by the buffers we have entered (ascii:41 represents a,42 for B, and so on). From the above, we see that we still need four more bytes to overwrite the return address, in this case it is 0x000084a8
.
So, the last string is 16 bytes of garbage, then ShouldNotBeCalled
the address, as shown in the following command:
`p"AAAABBBBCCCCDDDD\x38\x84"`
As we can see in the following, we have IShouldNeverBeCalled
added the start address to the parameter:
Note that since this is a small-end structure, the bytes are written in reverse order. Once we run it, we can see that the program ShouldNotBeCalled
function is called, as shown in the following:
8.4 Return-guided programming
In most cases, we do not need to invoke another function that exists in the program itself. Instead, we need to place shellcode in our attack vectors, which will perform any malicious action we specify in Shellcode. However, in most ARM platform-based devices, the in-memory zone is not executable, which prevents us from placing the shellcode and executing it.
Thus, an attacker would have to rely on so-called return-guided programming (ROP), which is a simple link from an instruction fragment from different parts of memory, which will eventually execute our shellcode. These fragments are also known as ROP gadget. In order to link the ROP gadget, we need to find the gadget in the last command, which will allow us to jump to another location.
For example, if we disassemble the program when we execute it seed48()
, we will notice the following output:
If we look at disassembly, we will notice that it contains an ADD instruction followed by a POP and BX instruction, which is a perfect ROP gadget. Here, an attacker might think, in order to use it as an ROP gadget, first jump to a POP instruction that controls the R4 ( /bin/sh
6 smaller than the address), and then put the value of the ADD instruction into LR. So, when we jump back to add R0 = R4 + 6
, we have /bin/sh
the address, and then we can specify any garbage address for R4 and the address specified for LR system()
.
This means that we will eventually jump to the use /bin/sh
of parameters system()
, which will execute the shell. In the same way, we can create any ROP gadget and make it perform whatever we need. Because ROP is one of the most complex topics in development, it is strongly recommended that you try it yourself, analyze the disassembly code, and build the vulnerability.
8.5 Android Root Exploits
Starting with an earlier version of Android, the Android Root vulnerability began to appear in each subsequent version and from a different version of the Android device manufacturer. Android Root is simply a privileged access to the device, which is not granted to the user by default by the device manufacturer. These root attacks take advantage of the various vulnerabilities that exist in the Android system. The following is a list of some of the ideas that are based on exploiting exploits:
- Exploid: Based on the cve-2009-1185 vulnerability in Udev, which is a component of the Android USB connection, it verifies that the NetLink message (a message that is responsible for connecting the Linux kernel to the user) originates from the original source or is spoofed by an attacker. As a result, an attacker could simply send udev messages and elevate permissions from the user space itself.
- Gingerbreak: This is another vulnerability, based on a vulnerability in vold, similar to a vulnerability in exploid.
- Rageagainstthecage: This exploit is based on
RLIMIT_NPROC
, which specifies the setuid
maximum number of processes that can be created for a user when the function is called. The adb daemon starts as root, and then it uses the setuid()
tune to unlock privileges. However, if the RLIMIT_NPROC
program cannot be called to de-privilege according to the maximum number of processes reached, setuid()
ADB will continue to run as root.
- Zimperlich: Uses the same concept as the rageagainstthecage, but it relies on the zygote process to remove root privileges.
- Killinginthenameof: A vulnerability known as a
ashmem
(Shared Memory manager) interface that is used to change ro.secure
the value of the device's root state.
These are some of the most well-known Android exploits available for root Android devices.
Summarize
In this chapter, we learned about the different ways Android exploits and ARM use. Hopefully this chapter will be a good start for anyone who wants to take advantage of ARM more deeply.
In the next chapter, we'll learn how to write an Android penetration test report.
Android Penetration Test Study Manual chapter eighth ARM utilization