Initial commit

This commit is contained in:
mykola2312 2017-04-10 01:53:45 +03:00
commit c9048bd2b4
11 changed files with 408 additions and 0 deletions

89
proc.c Normal file
View file

@ -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);
}

26
proc.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef __PROC_H
#define __PROC_H
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
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

BIN
sh2load Normal file

Binary file not shown.

162
sh2load.c Normal file
View file

@ -0,0 +1,162 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>
#include <sys/ptrace.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <unistd.h>
#include <dlfcn.h>
#include "proc.h"
#include "vmap.h"
#ifdef __i386__
char shellcode[] = {
0x6A,0x01,0xEB,0x07,0xFF,0xD3,0x83,0xC4,
0x08,0x5B,0xC3,0xE8,0xF4,0xFF,0xFF,0xFF,
0x90
};
#define STR_OFFSET 0x10
#define SHELL_SIZE 0x10
#elif __x86_64__
char shellcode[] = {
0x48,0x31,0xF6,0xEB,0x08,0x5F,0x48,0xFF,
0xC6,0xFF,0xD3,0x5B,0xC3,0xE8,0xF3,0xFF,
0xFF,0xFF,0x90
};
#define STR_OFFSET 0x12
#define SHELL_SIZE 0x12
#endif
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
}
unsigned long getfuncaddr(const char* name)
{
void* mod;
if(!(mod = dlopen("libc.so.6",RTLD_LAZY)))
return -1;
return (unsigned long)dlsym(mod,name);
}
int main(int argc,char** argv)
{
pid_t pid = atoi(argv[1]);
struct user_regs_struct regs;
struct stat st;
vmap_t shell,libc,local_libc;
unsigned long dlpn_off,dlpn_addr;
char* local_shell;
size_t path_size,total_size;
int pd,wr;
char filename[PATH_MAX];
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(vmap_reqeust(getpid(),VMAP_WALK_LIBC,&local_libc) < 0)
{
fputs("[-] Local libc not found!\n",stderr);
exit(0);
}
suspend_proc(pid,true);
if((pd = open_proc(pid)) < 0)
{
perror("open_proc");
suspend_proc(pid,false);
exit(1);
}
realpath(argv[2],filename);
path_size = strlen(filename) + 1;
total_size = path_size + SHELL_SIZE;
local_shell = (char*)malloc(total_size);
if(!local_shell)
{
perror("malloc");
suspend_proc(pid,false);
exit(1);
}
memcpy((void*)local_shell,shellcode,SHELL_SIZE);
memcpy((void*)(local_shell+STR_OFFSET),filename,path_size);
printf("%lx-%lx\n",shell.vm_start,shell.vm_end);
if((wr = pwrite(pd,(void*)local_shell,
total_size,(off_t)shell.vm_start)) < 0)
{
perror("pwrite");
goto ex;
}
else
printf("[+] Shellcode written %d\n",wr);
if(!(dlpn_addr = getfuncaddr("__libc_dlopen_mode")))
{
perror("getfuncaddr");
goto ex;
}
printf("__libc_dlopen_mode %lx\n",dlpn_addr);
dlpn_off = dlpn_addr - local_libc.vm_start;
printf("offset %lx\n",dlpn_off);
dlpn_addr = dlpn_off + libc.vm_start;
printf("remote __libc_dlopen_mode %lx\n",dlpn_addr);
ptrace(PTRACE_GETREGS,pid,0,&regs);
#ifdef __i386__
emu_push(pid,&regs,regs.eip);
emu_push(pid,&regs,regs.ebx);
regs.eip = (unsigned long)shell.vm_start+2;
regs.ebx = (unsigned long)dlpn_addr;
#elif __x86_64__
emu_push(pid,&regs,regs.rip);
emu_push(pid,&regs,regs.rbx);
regs.rip = (unsigned long)shell.vm_start+2;
regs.rbx = (unsigned long)dlpn_addr;
#endif
ptrace(PTRACE_SETREGS,pid,0,&regs);
ex:
suspend_proc(pid,false);
free((void*)local_shell);
close_proc(pd);
return 0;
}

BIN
sh2load32 Normal file

Binary file not shown.

BIN
vm_shell32.bin Normal file

Binary file not shown.

14
vm_shell32.s Normal file
View file

@ -0,0 +1,14 @@
use32
push 1
jmp _text
_code:
call ebx
add esp,8
pop ebx
ret
_text:
call _code
db "/something/library/path",0 ;offset 0x10

BIN
vm_shell64.bin Normal file

Binary file not shown.

16
vm_shell64.s Normal file
View file

@ -0,0 +1,16 @@
use64
xor rsi,rsi
jmp _text
_code:
pop rdi
inc rsi
call rbx
pop rbx
ret
_text:
call _code
db "/something/library/path",0

60
vmap.c Normal file
View file

@ -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;
}

41
vmap.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef __VMAP_H
#define __VMAP_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
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