Initial commit
This commit is contained in:
commit
e675b26311
14 changed files with 405 additions and 0 deletions
89
proc.c
Normal file
89
proc.c
Normal 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
26
proc.h
Normal 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
|
||||||
1
shellcode/vm_hello.bin
Normal file
1
shellcode/vm_hello.bin
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
λ^H1ΐH1<48>H<EFBFBD>ΐH‰Η²
[Γθθ<CEB8><CEB8><EFBFBD>Hello World!
|
||||||
19
shellcode/vm_hello.s
Normal file
19
shellcode/vm_hello.s
Normal file
|
|
@ -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
|
||||||
2
shellcode/vm_hello32.bin
Normal file
2
shellcode/vm_hello32.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
1À1Û1Òë
|
||||||
|
Y°²
CÍ€[ÃèñÿÿÿHello World!
|
||||||
20
shellcode/vm_hello32.s
Normal file
20
shellcode/vm_hello32.s
Normal file
|
|
@ -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
|
||||||
BIN
shellcode/vm_load.bin
Normal file
BIN
shellcode/vm_load.bin
Normal file
Binary file not shown.
17
shellcode/vm_load.s
Normal file
17
shellcode/vm_load.s
Normal file
|
|
@ -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
|
||||||
BIN
shellcode/vm_load32.bin
Normal file
BIN
shellcode/vm_load32.bin
Normal file
Binary file not shown.
17
shellcode/vm_load32.s
Normal file
17
shellcode/vm_load32.s
Normal file
|
|
@ -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
|
||||||
60
vmap.c
Normal file
60
vmap.c
Normal 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
41
vmap.h
Normal 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
|
||||||
BIN
vtrace
Normal file
BIN
vtrace
Normal file
Binary file not shown.
113
vtrace.c
Normal file
113
vtrace.c
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.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 "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;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue