ARMv5 Assembly and a Simulated Buffer Overflow

So I get bored really really easily, especially when I’m at home alone for long periods of time with nothing to do (I should really get an xbox or playstation soon)… Anyway, I just wanted to see how hard it was to convert my extremely basic x86 assembly knowledge to ARM. Here is a basic tutorial on achieving a basic buffer overflow on an ARMv5 platform!

Some initial things to consider before exploiting (I haven’t done all of these steps below but you should!)

  • syntax style (at&t or intel)
  • compatible assembler and linker program
  • no dynamic function calls or shared library dependence (static code only)
  • function or method argument passing (registers or stack)
  • linux syscall numbers (kernel interrupts)
  • statically determined references to potential data areas
  • no null bytes in the final shellcode or machine code

Below is a really basic ARM compatible assembly program. It makes a call out to the write() method and passes the arguments in via the available registers. It makes reference to the data string at the end of the executable by using a static offset from the program counter during the time of execution. It then uses ARM’s version of the software interrupt call to get the kernel’s attention…

$ cat sc.s

.text

.global _start
_start:
	mov %r7, $4
	mov %r0, $1
	mov %r1, %pc
	add %r1, #20
	mov %r2, $12
	swi $0

	mov %r7, $1
	mov %r0, $0
	swi $0

	.string "hello world!"

To compile, link and dump the shellcode, you can run the following commands below (sorry for the huge perl one liner but I was too lazy/tired to hand format the output).

$ as -o sc.o sc.s && ld -o sc sc.o
# print shellcode words in reverse so that when it is stored in the chr array and accessed as an int word item it is read backwards (little endian)
$ objdump -d sc | grep -iv 'file format' | grep -i '[0-9a-f][0-9a-f]*:' | awk '{ print $2 }' | perl -e '$line=" ";while($line){$line=<STDIN>;$line =~ s/[\r\n]+//g;$code="";for($x=(length($line)-2);$x>-1;$x-=2){$code.=("\\x".substr($line,$x,2));}$code.="";printf("$code\n");}'

After getting the shellcode from the above command we can move on to playing with the victim. Here’s an amazingly feature packed program which reads any data it can from standard input and puts it in a pre-sized stack based variable. It then copies the data from the stack variable into a heap based variable and executes whatever is in it for good measure. We really want the attacker to succeed here people!

$ cat ex.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

void user(char *buff)
{
	char stac[64];
	read(0, stac, 256 * sizeof(char));
	bcopy(stac, buff, 64 * sizeof(char));
}

int main()
{
	char *heap = malloc(64 * sizeof(char));
	int (*ret)();

	user(heap);
	printf("self-exec\n");

	ret = (int(*)())heap;
	(int)(*ret)();

	return 0;
}


$ gcc -Wall -o ex ex.c

$ printf '\x04\x70\xa0\xe3\x01\x00\xa0\xe3\x0f\x10\xa0\xe1\x14\x10\x81\xe2\x0c\x20\xa0\xe3\x00\x00\x00\xef\x01\x70\xa0\xe3\x00\x00\xa0\xe3\x00\x00\x00\xef\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21' | ./ex

self-exec
hello world!

Exercise for the reader: Actually overflow the stack variable above and overwrite the return pointer before the self-exec part gets called to achieve a true buffer overflow attack. Tip: you may need to disable certain security features like DEP/NX-bit, ASLR and stack canaries. Also, always remember that return-to-libc is your friend!

As you can see above, this is just the extreme basics and real attackers are insane in what they can actually achieve without having to setup what I did above. Imagine having that program listening on a socket file descriptor instead of standard input and imagine sending it exec() based shell code which could make a system call out to netcat allowing it to listen on a new port as well as passing any of its socket data to a shell program like bash. Or maybe a system call out to wget and then an execution of the downloaded file as root possibly which could then result in bad things happening. Anyway…

I know this is all very noob’ish code but I plan to keep working on it,
Also thanks for reading my stuff!

Johnny Stoops

2 thoughts on “ARMv5 Assembly and a Simulated Buffer Overflow

Leave a reply to Quick Blog Summary | Jon's FOSS Blog Cancel reply