commit e675b26311d3890d6859a65f16706374550b6145 Author: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Mon Apr 10 01:39:49 2017 +0300 Initial commit diff --git a/proc.c b/proc.c new file mode 100644 index 0000000..4411114 --- /dev/null +++ b/proc.c @@ -0,0 +1,89 @@ +#include "proc.h" + +int is_numeric(char* s) +{ + while(*s) + { + if(!isdigit(*s)) + return 0; + s++; + } + return 1; +} + +int walk_proc(walk_proc_callback func,void *data) +{ + struct dirent* dr; + DIR* d; + if(!(d = opendir("/proc"))) + return -1; + while((dr = readdir(d))) + { + if(dr->d_type == DT_DIR) + { + if(is_numeric(dr->d_name)) + { + if(func(atoi(dr->d_name),data)) + return 1; + } + } + } + closedir(d); + return 0; +} + +int walk_thread(pid_t pid,walk_thread_callback func,void *data) +{ + struct dirent* dr; + DIR* d; + char path[256]; + sprintf(path,"/proc/%d/task",pid); + if(!(d = opendir(path))) + return -1; + while((dr = readdir(d))) + { + if(dr->d_type == DT_DIR) + { + if(is_numeric(dr->d_name)==1) + { + if(func(atoi(dr->d_name),data)) + return 1; + } + } + } + closedir(d); + return 0; +} + +int suspend_proc_callback(pid_t tid,void *data) +{ + int status; + if(*(bool*)data == true) + { + ptrace(PTRACE_ATTACH,tid,0,0); + waitpid(tid,&status,0); + } + else + { + ptrace(PTRACE_DETACH,tid,0,0); + waitpid(tid,&status,0); + } + return 0; +} + +int suspend_proc(pid_t pid,bool suspend) +{ + return walk_thread(pid,&suspend_proc_callback,(void*)&suspend); +} + +int open_proc(pid_t pid) +{ + char path[256]; + sprintf(path,"/proc/%d/mem",pid); + return open(path,O_RDWR); +} + +void close_proc(int pd) +{ + close(pd); +} diff --git a/proc.h b/proc.h new file mode 100644 index 0000000..4f6359d --- /dev/null +++ b/proc.h @@ -0,0 +1,26 @@ +#ifndef __PROC_H +#define __PROC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int (*walk_proc_callback)(int pid,void *data); +typedef int (*walk_thread_callback)(pid_t tid,void *data); + +int walk_proc(walk_proc_callback func,void *data); +int walk_thread(pid_t pid,walk_thread_callback func,void *data); + +int suspend_proc(pid_t pid,bool suspend); + +int open_proc(pid_t pid); +void close_proc(int pd); + +#endif diff --git a/shellcode/vm_hello.bin b/shellcode/vm_hello.bin new file mode 100644 index 0000000..cc802e7 --- /dev/null +++ b/shellcode/vm_hello.bin @@ -0,0 +1 @@ +ë^H1ÀH1ÒHÿÀH‰Ç² [ÃèèÿÿÿHello World! diff --git a/shellcode/vm_hello.s b/shellcode/vm_hello.s new file mode 100644 index 0000000..0b027f2 --- /dev/null +++ b/shellcode/vm_hello.s @@ -0,0 +1,19 @@ +use64 + +jmp _text +_code: +pop rsi + +xor rax,rax +xor rdx,rdx +inc rax +mov rdi,rax +mov dl,13 +syscall + +pop rbx +ret + +_text: +call _code +db "Hello World!",0x0A diff --git a/shellcode/vm_hello32.bin b/shellcode/vm_hello32.bin new file mode 100644 index 0000000..988874c --- /dev/null +++ b/shellcode/vm_hello32.bin @@ -0,0 +1,2 @@ +1À1Û1Òë +Y°² CÍ€[ÃèñÿÿÿHello World! diff --git a/shellcode/vm_hello32.s b/shellcode/vm_hello32.s new file mode 100644 index 0000000..7f458a6 --- /dev/null +++ b/shellcode/vm_hello32.s @@ -0,0 +1,20 @@ +use32 + +xor eax,eax +xor ebx,ebx +xor edx,edx +jmp _text +_code: +pop ecx + +mov al,4 +mov dl,13 +inc ebx +int 0x80 + +pop ebx +ret + +_text: +call _code +db "Hello World!",0x0A diff --git a/shellcode/vm_load.bin b/shellcode/vm_load.bin new file mode 100644 index 0000000..4d3b07b Binary files /dev/null and b/shellcode/vm_load.bin differ diff --git a/shellcode/vm_load.s b/shellcode/vm_load.s new file mode 100644 index 0000000..b5be359 --- /dev/null +++ b/shellcode/vm_load.s @@ -0,0 +1,17 @@ +use64 + +jmp _text +_code: +pop rdi + +xor rsi,rsi +inc rsi +lea rax,[rbx+0x125320] +call rax + +pop rbx +ret + +_text: +call _code +db "/home/adriane/sys4proc/libtest.so",0 diff --git a/shellcode/vm_load32.bin b/shellcode/vm_load32.bin new file mode 100644 index 0000000..354c257 Binary files /dev/null and b/shellcode/vm_load32.bin differ diff --git a/shellcode/vm_load32.s b/shellcode/vm_load32.s new file mode 100644 index 0000000..a0df6e0 --- /dev/null +++ b/shellcode/vm_load32.s @@ -0,0 +1,17 @@ +use32 +;ebx+0x127090 + +push 1 +jmp _text +_code: + +lea eax,[ebx+0x127090] +call eax +add esp,8 + +pop ebx +ret + +_text: +call _code +db "/home/adriane/sys4proc/libtest.so",0 diff --git a/vmap.c b/vmap.c new file mode 100644 index 0000000..2fb085c --- /dev/null +++ b/vmap.c @@ -0,0 +1,60 @@ +#include "vmap.h" + +void vmap_parse(vmap_t* map,const char* str) +{ + sscanf(str,"%lx-%lx %s %08d %*02d:%*02d %*s %s", + &map->vm_start,&map->vm_end,map->perms, + &map->magic_num,map->path); +} + +int vmap_walk(pid_t pid,walk_map_callback func,void *arg) +{ + char buf[256]; + char path[64]; + vmap_t map; + FILE* fmap; + + sprintf(path,"/proc/%d/maps",pid); + if(!(fmap = fopen(path,"rb"))) + return -1; + + while(fgets(buf,256,fmap) != NULL) + { + vmap_parse(&map,buf); + if(func(&map,arg)) + return 1; + } + return 0; +} + +int walk_map_func(vmap_t *map,void *arg) +{ + vmap_request_t *vreq = (vmap_request_t*)arg; + vreq->status = VMAP_NOTFOUND; + if(vreq->type == VMAP_WALK_SHELL && strchr(map->perms,'x')) + { + vreq->status = VMAP_OK; + memcpy(vreq->map,map,sizeof(vmap_t)); + return 1; + } + else if(vreq->type == VMAP_WALK_LIBC && strstr(map->path,"libc-")) + { + vreq->status = VMAP_OK; + memcpy(vreq->map,map,sizeof(vmap_t)); + return 1; + } + return 0; +} + +int vmap_reqeust(pid_t pid,request_t what,vmap_t *map) +{ + vmap_request_t vreq; + + vreq.type = what; + vreq.map = map; + vmap_walk(pid,&walk_map_func,(void*)&vreq); + if(vreq.status == VMAP_OK) + return 0; + + return -1; +} diff --git a/vmap.h b/vmap.h new file mode 100644 index 0000000..f6e89f6 --- /dev/null +++ b/vmap.h @@ -0,0 +1,41 @@ +#ifndef __VMAP_H +#define __VMAP_H + +#include +#include +#include +#include +#include +#include + +typedef enum { + VMAP_WALK_SHELL, + VMAP_WALK_LIBC, +} request_t; + +typedef enum { + VMAP_OK, + VMAP_NOTFOUND, +} status_t; + +typedef struct { + uintptr_t vm_start; + uintptr_t vm_end; + char perms[5]; + uint32_t magic_num; + char path[256]; +} vmap_t; + +typedef struct { + request_t type; + status_t status; + vmap_t *map; +} vmap_request_t; + +typedef int (*walk_map_callback)(vmap_t *map,void *arg); + +void vmap_parse(vmap_t* map,const char* str); +int vmap_walk(pid_t pid,walk_map_callback func,void *arg); +int vmap_reqeust(pid_t pid,request_t what,vmap_t *map); + +#endif diff --git a/vtrace b/vtrace new file mode 100644 index 0000000..7cf74c5 Binary files /dev/null and b/vtrace differ diff --git a/vtrace.c b/vtrace.c new file mode 100644 index 0000000..8e3274f --- /dev/null +++ b/vtrace.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "proc.h" +#include "vmap.h" + +void emu_push(pid_t pid,struct user_regs_struct *regs, + unsigned long value) +{ +#ifdef __i386__ + regs->esp -= sizeof(unsigned long); + if(ptrace(PTRACE_POKEDATA,pid,regs->esp,value) < 0) + perror("ptrace_pokedata"); +#elif __x86_64__ + regs->rsp -= sizeof(unsigned long); + if(ptrace(PTRACE_POKEDATA,pid,regs->rsp,value) < 0) + perror("ptrace_pokedata"); +#endif +} + +int main(int argc,char** argv) +{ + pid_t pid = atoi(argv[1]); + struct user_regs_struct regs; + struct stat st; + vmap_t shell,libc; + void* local_shell; + int fd,pd,wr; + + if(vmap_reqeust(pid,VMAP_WALK_SHELL,&shell) < 0) + { + fputs("[-] Place for shellcode not found!\n",stderr); + exit(0); + } + + if(vmap_reqeust(pid,VMAP_WALK_LIBC,&libc) < 0) + { + fputs("[-] Libc not found!\n",stderr); + exit(0); + } + + if((fd = open(argv[2],O_RDONLY)) < 0) + { + perror("open shellcode file"); + exit(1); + } + + if(fstat(fd,&st)) + { + perror("fstat"); + close(fd); + exit(1); + } + + local_shell = mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,fd,0); + if(local_shell == MAP_FAILED) + { + perror("mmap"); + close(fd); + exit(1); + } + + suspend_proc(pid,true); + + if((pd = open_proc(pid)) < 0) + { + perror("open_proc"); + suspend_proc(pid,false); + exit(1); + } + + printf("%lx-%lx\n",shell.vm_start,shell.vm_end); + + if((wr = pwrite(pd,(void*)local_shell, + st.st_size,(off_t)shell.vm_start)) < 0) + { + perror("pwrite"); + goto ex; + } + else + printf("[+] Shellcode written %d\n",wr); + + ptrace(PTRACE_GETREGS,pid,0,®s); +#ifdef __i386__ + emu_push(pid,®s,regs.eip); + emu_push(pid,®s,regs.ebx); + + regs.eip = (unsigned long)shell.vm_start+2; + regs.ebx = (unsigned long)libc.vm_start; +#elif __x86_64__ + emu_push(pid,®s,regs.rip); + emu_push(pid,®s,regs.rbx); + + regs.rip = (unsigned long)shell.vm_start+2; + regs.rbx = (unsigned long)libc.vm_start; +#endif + + ptrace(PTRACE_SETREGS,pid,0,®s); +ex: + suspend_proc(pid,false); + + munmap(local_shell,st.st_size); + close_proc(pd); + close(fd); + return 0; +}