ARM Architecture Shellcoding
ARM is a family of instruction set architectures for computer processors based on a reduced instruction set computing (RISC) architecture developed by British company ARM Holdings. Also it is the most widely used 32-bit instruction set architecture. For a list of the ARM processor cores and handsets built on them, have a look at the link http://en.wikipedia.org/wiki/List_of_applications_of_ARM_cores.
ARM architecture today has some features that were derived from the old Berkeley RISC including loadstore architecture, fixed length 32-bit instructions and 3-address instruction formats.
The ARM architecture is also the most present in the field of Mobile Computing. Numerous operating systems have been ported to that architecture including Linux (Used by Android), iOS (Used by iPhone & iPad) and Windows Phone 8 (Used by many Nokia-Lumia smartphones).
Out of the 16 accessible registers there are 11 generalpurpose registers and 5 special purpose registers, which are assigned specific names.
R11 is the frame pointer and holds the pointer to the current stack frame.
R12 is the Intra-procedure call scratch register used by a subroutine to store temporary data.
R13 is the stack pointer and holds the pointer to the top of the stack.
R14 is the link register holds the return addresses whenever a subroutine is called with a branch and link instruction.
R15 is the program counter and holds the address of the next instruction to be executed.
The arguments of a function are stored in registers r0 to r3. If the number of arguments is greater than 3 then the excess arguments are stored onto the stack.
Let’s start by writing a shellcode called execve(). We first need to know the address of the syscall.
Note that we are using a Raspberry Pi to demonstrate this article.
We have 11 for _execve. We know that _execve consumes three arguments:
Which gives us:
It worked however in order create our shellcode, we should have no null bytes, and our shellcode has many of them.
Under ARM, we have the THUMB MODE that allows us to use 16 bits addressing for our calls as opposed to 32 bits, which does simplify our life at this stage.
When compiling, use “-mthumb” to indicate that we are switching to “Thumb Mode”. The value of the constant being added to r0 was changed. Instead of the original “add r0, #20”, we are doing “add r0, #10” since we have now switched to “thumb mode”, the address where our chain is at, has been halved.
So now we have to modify the following instruction: “svc 0”. For SVC we will use “svc 1” which is perfect in this case.
Here we are, we have got an operational shellcode without any null bytes. In C that gives us:
About The Author
Anwar Mohamed, Mobile Security Researcher