Added more communication utils between userspace and kernel:

* Included maps and kernel ring buffer communication
* Extended the ebpf structure to include more modules
* New utils in both user and kernelspace
* Other changes
* This update precedes a great effort on researching and learning and linux kernel tracing and studing ebpfkit from defcon. More functionalities should come rather quickly now.
This commit is contained in:
h3xduck
2021-12-29 14:44:09 -05:00
parent 510fc89de0
commit d5478ed7a0
12 changed files with 1014 additions and 793 deletions

View File

@@ -1,5 +1,8 @@
{
"files.associations": {
"time.h": "c"
"time.h": "c",
"constants.h": "c",
"pkt_cls.h": "c",
"map_defs.h": "c"
}
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -9,7 +9,7 @@
#include <netdb.h>
#include <stdlib.h>
#include "../constants/constants.h"
#include "../common/constants.h"
// For printing with colors
#define KGRN "\x1B[32m"

36
src/common/map_defs.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef __MAP_DEFS_H
#define __MAP_DEFS_H
#define RB_EVENT_MAX_MESSAGE_SIZE 512
typedef enum {
INFO,
DEBUG,
EXIT,
ERROR
} event_type_t;
struct rb_event {
int pid;
char message[RB_EVENT_MAX_MESSAGE_SIZE];
int code;
event_type_t event_type;
};
//sched_process_exec tracepoint contents
struct trace_entry {
short unsigned int type;
unsigned char flags;
unsigned char preempt_count;
int pid;
};
struct trace_event_raw_sched_process_exec {
struct trace_entry ent;
unsigned int __data_loc_filename;
int pid;
int old_pid;
char __data[0];
};
#endif

68
src/ebpf/include/bpf/fs.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef __FS_H
#define __FS_H
#include <stdio.h>
#include <linux/types.h>
#include <unistd.h>
#include <string.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "../common/constants.h"
#include "../common/map_defs.h"
#define RING_BUFFER_MAX_ELEMS 256
//Ring buffer - For communication ebpf -> userspace
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, RING_BUFFER_MAX_ELEMS * 1024); //Multiple struct rb_event(s) must fit here
} rb_comm SEC(".maps");
//BPF map
/*struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, pid_t);
__type(value, char[5]);
} exec_start SEC(".maps");*/
/**
* @brief A kthread is started in the kernel (a new program)
* @ref https://elixir.bootlin.com/linux/latest/source/include/trace/events/sched.h#L397
*/
SEC("tp/sched/sched_process_exec")
int handle_exec(struct trace_event_raw_sched_process_exec *ctx){
struct task_struct *task;
unsigned fname_off;
struct rb_event *e;
pid_t pid;
int ts;
pid = bpf_get_current_pid_tgid() >> 32;
ts = bpf_ktime_get_ns();
/* reserve sample from BPF ringbuf */
e = bpf_ringbuf_reserve(&rb_comm, sizeof(*e), 0);
if (!e){
return 0;
}
e->pid = pid;
e->event_type = INFO;
e->code = 0;
char* message = "HOLA\0";
bpf_probe_read_str(&e->message, sizeof(message), message);
/* successfully submit it to user-space for post-processing */
bpf_ringbuf_submit(e, 0);
return 0;
}
#endif

View File

@@ -1,4 +1,4 @@
//#include "newvmlinux.h"
//Linux system includes
#include <unistd.h>
#include <stdbool.h>
#include <linux/tcp.h>
@@ -15,36 +15,27 @@
#include <linux/ip.h>
#include <linux/udp.h>
//BPF & libbpf dependencies
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
//User-kernel dependencies
#include "../user/include/xdp_filter.h"
#include "../constants/constants.h"
#include "../common/constants.h"
//BPF exclusive includes
#include "packet/packet_manager.h"
#include "packet/protocol/tcp_helper.h"
#include "xdp/xdp_helper.h"
#include "common/common_utils.h"
//BPF modules to load
#include "include/bpf/fs.h"
char LICENSE[] SEC("license") = "Dual BSD/GPL";
//BPF map
/*struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, pid_t);
__type(value, char[5]);
} exec_start SEC(".maps");*/
//Ring buffer
/*struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");*/
//Ethernet frame struct
struct eth_hdr {
unsigned char h_dest[ETH_ALEN];

View File

@@ -58,8 +58,7 @@ int print_entry(const char *filepath, const struct stat *info, const int typefla
printf(" %s (dangling symlink)\n", filepath);*/
else
if (typeflag == FTW_F)
1+1;
//printf(" %s\n", filepath);
printf(" %s\n", filepath);
/*else
if (typeflag == FTW_D || typeflag == FTW_DP)
printf(" %s/\n", filepath);

View File

@@ -9,8 +9,10 @@
#include <unistd.h>
#include "xdp_filter.skel.h"
#include "include/xdp_filter.h"
#include "../constants/constants.h"
#include "../common/constants.h"
#include "../common/map_defs.h"
#include "include/utils/files/path.h"
#include "include/utils/strings/regex.h"
#include "include/utils/structures/fdlist.h"
@@ -63,39 +65,56 @@ static void sig_handler(int sig){
exiting = true;
}
/*static int handle_event(void *ctx, void *data, size_t data_sz){
const struct event *e = data;
/**
* @brief Manages an event received via the ring buffer
* It's a message from th ebpf program
*
* @param ctx
* @param data
* @param data_sz
* @return int
*/
static int handle_rb_event(void *ctx, void *data, size_t data_size){
const struct rb_event *e = data;
//For time displaying
struct tm *tm;
char ts[32];
time_t t;
time(&t);
tm = localtime(&t);
strftime(ts, sizeof(ts), "%H:%M:%S", tm);
printf("NEW: %s\n",
e->payload);
if(e->event_type == INFO){
printf("%s INFO pid:%d code:%i, msg:%s\n", ts, e->pid, e->code, e->message);
}else if(e->event_type == DEBUG){
}else if(e->event_type == ERROR){
}else if(e->event_type == EXIT){
}else{
printf("UNRECOGNIZED RB EVENT RECEIVED");
return -1;
}
return 0;
}*/
}
int main(int argc, char**argv){
//struct ring_buffer *rb = NULL;
struct ring_buffer *rb = NULL;
struct xdp_filter_bpf *skel;
int err;
for (int arg = 1; arg < argc; arg++) {
//Ready to be used
/*for (int arg = 1; arg < argc; arg++) {
if (load_fd_kmsg(argv[arg])) {
fprintf(stderr, "%s.\n", strerror(errno));
return EXIT_FAILURE;
}
}
//int res = regex_match_fd("/proc/12/fd/1");
//printf("Returned %i\n", res);
}*/
unsigned int ifindex;
@@ -159,23 +178,40 @@ int main(int argc, char**argv){
goto cleanup;
}
// Attach tracepoints
/*err = xdp_filter_bpf__attach(skel);
// Attach tracepoint for
err = xdp_filter_bpf__attach(skel);
if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup;
}*/
}
//Attack BPF program to network interface
int flags = XDP_FLAGS_SKB_MODE;
int fd = bpf_program__fd(skel->progs.xdp_receive);
err = bpf_set_link_xdp_fd(ifindex, fd, flags);
/* Set up ring buffer polling */
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb_comm), handle_rb_event, NULL, NULL);
if (!rb) {
err = -1;
fprintf(stderr, "Failed to create ring buffer\n");
goto cleanup;
}
//Now wait for messages from ebpf program
printf("Filter set and ready\n");
while (!exiting) {
/* trigger our BPF program */
fprintf(stderr, ".");
sleep(1);
err = ring_buffer__poll(rb, 100 /* timeout, ms */);
//Checking if a signal occured
if (err == -EINTR) {
err = 0;
break;
}
if (err < 0) {
printf("Error polling ring buffer: %d\n", err);
break;
}
}
//Received signal to stop, detach program from network interface
@@ -184,6 +220,7 @@ int main(int argc, char**argv){
cleanup:
ring_buffer__free(rb);
xdp_filter_bpf__destroy(skel);
return err < 0 ? -err : 0;