Non-Executable Stack ARM Exploitation.pdf

(230 KB) Pobierz
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
============= Non-Executable Stack ARM Exploitation =================
0.- Introduction
1.- ARM Assembly
1.0 - Exploitation of ARM vs. X86 when stack isn't executable
1.1 - ARM calling convention (APCS)
1.2 - Why simple ret2libc will not work?
1.3 - Understanding the vulnerable function
2.- ARM Exploitation
2.0 - Controlling the PC
2.1 - Ret2ZP (Return To Zero Protection) - For Local Attacker
2.2 - Ret2ZP (Return To Zero Protection) - Attack Explained in Depth (For
Remote Attacker)
2.3 - Ret2ZP - R0..R3 Adjustments
2.4 - Ret2ZP - Using the attack to enable stack
2.5 - Ret2ZP - Hacking Android based phone
3.- Conclusion
4.- Acknowledgments
5.- Author
6.- References
882402523.004.png 882402523.005.png 882402523.006.png
--[ 0.- Introduction
This paper is describing techniques to exploit stack-based buffer overflows and to get
more familiar with ARM exploitation in the modern age - where ARM stack isn't
executable.
This research was made to understand the risks on modern ARM devices in-order to
prevent them by suggesting solutions.
Disclaimer: When using parts from this paper, you should still credit the authors of
this paper and point to an updating link of this paper as a reference.
Ret2ZP Attack is described fully and can be preformed at your own ARM devices. I
will claim no responsibility for doing yourself or other damage. It's on your own risk.
This paper is assuming basic knowledge in X86 assembly or ARM assembly.
Also, knowledge of exploitation techniques may assist understanding the paper
(when stack is not executable, such as ret2libc attacks).
Stack buffer overflow bugs are caused when a program writes more data to a buffer
located on the stack than there was actually allocated for that buffer.
How can a BO be used?
(I) A user can locally run commands to elevate privileges and gain control over a
mobile-device.
(II) A user can remotely exploit a phone, to gain control over a remote phone to
execute commands.
This paper intends to show there’s still a risk in current implied security mechanism
for devices using ARM CPU. My hope is that more effort will be invested in making
solution on mainline kernels.
Now, let's change our thoughts from computers to real world ARM exploitation
scenario. ARM is being used everywhere right now: Televisions, advanced mobile
phones, tablets, etc!
But it appears that all exploitation rely on Stack being executable on ARM, which is
not the modern scenario.
Check if there’s an updated version of this paper at:
882402523.007.png
--[ 1.- ARM Assembly
----[ 1.0 Exploitation of ARM vs. X86 when stack isn't executable
Stack is not executable on many new platforms, causing exploitation to be harder.
ARM Assembly is different than X86 Assembly.
X86 Tricks exists to control the flow of a program after running over the EIP value
[such as : ret2libc (*D)] where you can run over the EBP, EIP and can control the
path of the function + add parameters(!).
No public knowledge of exploitation on ARM exists by the time of writing this paper
[on ARM exploitation when stack isn't executable]. This is the research, enjoy:
----[ 1.1 ARM calling convention (APCS)
The standard ARM calling convention (*A) allocates the 16 ARM registers as:
|=> R15 is the Program Counter (PC)
|=> R14 is the Link Register (LR)
|=> R13 is the Stack Pointer (SP)
|=> R12 is the Intra-Procedure-call scratch register (IP)
|=> R11 is the Frame Pointer (FP)
|=> R4 to R10: used to hold local variables.
|=> R0 to R3: used to hold argument values to and from a subroutine
===========
Which means, that if we want to call SYSTEM() function, which gets one parameter
(char *), it will be passed through R0.
Since parameter is not being pushed on the stack when calling the function, it was
not supposed to be popped from the stack, so the original way of getting parameter
to function
is not the same as X86. We'll need to adjust parameters using the following tricks in-
order for the buffer to do successful exploit.
----[ 1.2 Why simple ret2libc will not work?
What does it mean for (non-executable-stack) exploitation? Parameters needed to be
setup instead of just putting them in the right order on the stack like you were used to
on X86.
For example, simple Ret2Libc attack on X86 would have looked something like this :
|----------------|----------|------------|----------------|-----------------|
| 16 A's | AAAA | SYSTEM | EXIT FUNCTION | &/bin/sh |
|----------------|----------|------------|----------------|-----------------|
| args | EBP [20]| EIP [24] | EBP+8 [28]| EBP+12 [32]|
Meaning you can control the Base Pointer (can be used for Frame faking), the
function to call to (SYSTEM(buf)), the parameter to pass to function (&/bin/sh) ->
and the exit function that will be executed after SYSTEM(buf).
----[ 1.3 Understanding the vulnerable function
In ARM there are a few ways of exploitation depending on the vulnerable function:
(I) Vulnerable Function returns no parameters (void)
(II) Vulnerable Function returns no parameters (void) but does several stuff using
arguments R0-R3.
882402523.001.png
(III) Vulnerable Function does return parameters (int, char* , ...)
Keep reading to understand more about exploiting all of them, or how to take
advantage of some of them in-order to make buffer shorter.
882402523.002.png
--[ 2.- ARM Exploitation
----[ 2.0 Controlling the PC
Exploiting (I) can be easy but can also be very tricky :
It will be explained right after explaining why does it even work, and why can we
control the PC (Program-Counter, equivalent to EIP on X86).
When calling to a function, some parameters are moved to the right registers (R0-R3)
[Depends on the compiling flags, but it mostly looks the same] and not being pushed
on the so-called stack.
let's call a function named Func, that receives 2 parameters :
mov R0,R3
mov R1,R2
bl func ; See **
** Like call instruction in X86, (also note that "l" in "bl" means "Branch with link". The
next instruction will be stored on LR and in-order to return, LR will be moved back to
PC.)
As you can see arguments have been forwarded to the function using R0 and R1
[changes from different compiling flags, but in general case], but what happens when
entering to func?
push {R4, R11(FP), R14(LR)} ; in x86 : push R4\n push R11\n push R14
add FP, SP, #8 ; FP=SP+8
...
R4 is being pushed right after where the SP had pointed to. Also, R11 (which is the
Frame Pointer) and the Link Register is on the stack as-well, in this order :
memory goes this way <-----
stack is going this way ----->
== | R4 | R11 | LR |
== * <-- Stack Pointer is located at * when calling the function
Let's take a look at the epilogue on func:
sub SP,FP, #8 ; 0x8
pop {R4, FP, PC} ; in x86 asm : pop R4\n pop FP\n pop PC\n
.word 0x00008400 ; data function is using stored here
.word 0x........ ; and so on ...
................ ; and so on ...
So, after LR, had been pushed when entering the function, it's being popped as PC(!),
meaning the next instruction will be popped after the overflow allowing to take control
of PC.
If we'll try a Ret2LibC attack, it will failed, because parameters are not being popped.
We'll do some tricks in-order to control the parameter (R0..R3) before calling the
function.
882402523.003.png
Zgłoś jeśli naruszono regulamin