Created
April 30, 2014 21:57
-
-
Save interfector/0fd830ea799b2f5f7c96 to your computer and use it in GitHub Desktop.
shared object injector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#include <memory.h> | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <sys/ptrace.h> | |
#include <sys/user.h> | |
#include <sys/wait.h> | |
#include <dlfcn.h> | |
//#define _DEBUG | |
#define die(i,p) do{ perror(p); exit(i); }while(0) | |
#define push( addr, data ) addr -= 4; \ | |
ptrace( PTRACE_POKETEXT, pid, addr, data ); | |
void | |
memorySet(int pid, long addr, unsigned char* data, int size) | |
{ | |
int i; | |
for (i = 0; i < size; i++) | |
ptrace (PTRACE_POKETEXT, pid, addr + i, *(int*) (data + i)); | |
} | |
int | |
inject_memory(int pid, int dlopen_addr, char* libp) | |
{ | |
long addr; | |
struct user_regs_struct regs; | |
struct user_regs_struct saved_regs; | |
long path; | |
if (ptrace( PTRACE_ATTACH, pid, NULL, NULL )) | |
die(4, "ptrace_attach"); | |
waitpid(pid, NULL, 0); | |
if(ptrace( PTRACE_GETREGS, pid, ®s, ®s )) | |
die(5, "ptrace_getregs"); | |
memcpy( &saved_regs, ®s, sizeof( regs ) ); | |
#ifdef _DEBUG | |
printf("[#] Current %%eax: 0x%.8lx\n" | |
"[#] Current %%ebx: 0x%.8lx\n" | |
"[#] Current %%ecx: 0x%.8lx\n" | |
"[#] Current %%edx: 0x%.8lx\n" | |
"[#] Current %%esi: 0x%.8lx\n" | |
"[#] Current %%edi: 0x%.8lx\n" | |
"[#] Current %%esp: 0x%.8lx\n" | |
"[#] Current %%ebp: 0x%.8lx\n" | |
"[#] Current eflags: 0x%.8lx\n", | |
regs.eax, regs.ebx, regs.ecx, | |
regs.edx, regs.esi, regs.edi, | |
regs.esp, regs.ebp, regs.eflags ); | |
#endif | |
printf("@ Current %%eip : 0x%.8lx\n", regs.eip); | |
printf("@ Current %%esp : 0x%.8lx\n", regs.esp); | |
addr = regs.esp - 1024; | |
memorySet( pid, addr, libp, strlen(libp) + 1 ); | |
path = addr; | |
printf("@ Pushing arguments to 0x%.8lx\n", addr); | |
push( addr, regs.eip ); | |
push( addr, 0x0badc0de ); | |
push( addr, 0x00001102 ); | |
push( addr, path ); | |
push( addr, regs.eip ); | |
regs.esp = addr; | |
regs.eip = (long)dlopen_addr + 2; /* two bytes(nops) subtracted by the kernel */ | |
printf("@ Jumping to dlopen address...\n"); | |
ptrace( PTRACE_SETREGS, pid, ®s, ®s ); | |
if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) | |
die(6, "ptrace_cont"); | |
waitpid(pid, NULL, 0); | |
printf("@ Restore regs...\n", regs.eip); | |
ptrace( PTRACE_SETREGS, pid, NULL, &saved_regs ); | |
ptrace( PTRACE_DETACH, pid, NULL, NULL ); | |
return 0; | |
} | |
unsigned int | |
find_libc(int pid) | |
{ | |
char path[1024]; | |
char buf[1024], *start = NULL, *p = NULL; | |
unsigned long addr = NULL; | |
FILE *fp = NULL; | |
snprintf(path, sizeof(path), "/proc/%d/maps", pid); | |
if ((fp = fopen(path, "r")) == NULL) | |
die(3,"fopen"); | |
while(fgets(buf, sizeof(buf), fp)) | |
{ | |
if (!strstr(buf, "r-xp")) | |
continue; | |
if (!(p = strstr(buf, "/"))) | |
continue; | |
if (!strstr(p, "/libc-")) | |
continue; | |
start = strtok(buf, "-"); | |
addr = (unsigned int)strtoul(start, NULL, 16); | |
break; | |
} | |
fclose(fp); | |
return addr; | |
} | |
int | |
main(int argc, char **argv) | |
{ | |
unsigned int dlopen_addr = NULL; | |
unsigned int dlopen_mode = NULL; | |
unsigned int mylibc_addr = 0; | |
unsigned int pidlibc_addr = 0; | |
int pid; | |
unsigned char *shellcode; | |
int sh_size = 0; | |
int dlopen_offset = 0; | |
if (argc < 3) { | |
printf("Usage: %s <pid> <so path>\n", argv[0]); | |
return 1; | |
} | |
mylibc_addr = find_libc(getpid()); | |
pid = (int)atoi(argv[1]); | |
pidlibc_addr = find_libc( pid ); | |
#ifdef _DEBUG | |
printf("[#] PID: %d\n" | |
"[#] My libc address: 0x%.8lx\n" | |
"[#] %d's libc address: 0x%.8lx\n", | |
pid, mylibc_addr, pid, pidlibc_addr ); | |
#endif | |
printf("Trying obtaining __libc_dlopen_mode address..."); | |
dlopen_mode = dlsym(NULL, "__libc_dlopen_mode"); | |
if (dlopen_mode) | |
dlopen_offset = dlopen_mode - mylibc_addr; | |
else | |
die(2, "dlsym"); | |
printf("\t%p\n@ Offset: 0x%x\n", dlopen_mode, dlopen_offset); | |
dlopen_addr = pidlibc_addr + dlopen_offset; | |
printf("@ dlopen address: %p\n", dlopen_addr ); | |
inject_memory(pid, dlopen_addr, argv[2]); | |
printf("\n[+] Injection done!\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment