Modularized the ebpf program loading and attaching.

This commit is contained in:
h3xduck
2021-12-30 21:09:26 -05:00
parent 19a11da18f
commit d9a70f866c
12 changed files with 947 additions and 886 deletions

View File

@@ -3,6 +3,7 @@
"time.h": "c", "time.h": "c",
"constants.h": "c", "constants.h": "c",
"pkt_cls.h": "c", "pkt_cls.h": "c",
"map_defs.h": "c" "map_defs.h": "c",
"regex.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

@@ -29,14 +29,14 @@
* @ref https://elixir.bootlin.com/linux/latest/source/include/trace/events/sched.h#L397 * @ref https://elixir.bootlin.com/linux/latest/source/include/trace/events/sched.h#L397
*/ */
SEC("tp/sched/sched_process_exec") SEC("tp/sched/sched_process_exec")
int handle_exec(struct trace_event_raw_sched_process_exec *ctx){ int handle_sched_process_exec(struct trace_event_raw_sched_process_exec *ctx){
pid_t pid = bpf_get_current_pid_tgid() >> 32; pid_t pid = bpf_get_current_pid_tgid() >> 32;
char* message = "PROCESS ACTIVATED\0"; char message[] = "PROCESS ACTIVATED";
//Just deactivated for now, but working //Just deactivated for now, but working
/*if(ring_buffer_send(&rb_comm, pid, INFO, 0, message)<0){ if(ring_buffer_send(&rb_comm, pid, INFO, 0, message, sizeof(message))<0){
bpf_printk("ERROR printing in RB_COMM at fs module"); bpf_printk("ERROR printing in RB_COMM at fs module");
}*/ }
return 0; return 0;
} }

View File

@@ -25,7 +25,7 @@ struct ring_buffer rb_comm SEC(".maps");
* *
* @return 0 if ok, -1 if error * @return 0 if ok, -1 if error
*/ */
static __always_inline int ring_buffer_send(struct ring_buffer *rb, int pid, event_type_t event_type, int code, char* message){ static __always_inline int ring_buffer_send(struct ring_buffer *rb, int pid, event_type_t event_type, int code, char* message, __u32 message_len){
struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0); struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0);
if(!event){ if(!event){
return -1; return -1;
@@ -34,7 +34,7 @@ static __always_inline int ring_buffer_send(struct ring_buffer *rb, int pid, eve
event->code = code; event->code = code;
event->event_type = event_type; event->event_type = event_type;
event->pid = pid; event->pid = pid;
bpf_probe_read_kernel_str(&event->message, sizeof(message), message); bpf_probe_read_kernel_str(&event->message, message_len, message);
bpf_ringbuf_submit(event, 0); bpf_ringbuf_submit(event, 0);
return 0; return 0;

View File

@@ -0,0 +1,10 @@
#ifndef __MOD_MANAGER_H
#define __MOD_MANAGER_H
#include <unistd.h>
struct module_config{
//TODO
};
#endif

View File

View File

@@ -0,0 +1,5 @@
#ifndef __MOD_XDP_H
#define __MOD_XDP_H
#endif

View File

@@ -1,11 +1,4 @@
#ifndef __XDP_FILTER_H #ifndef __XDP_FILTER_H
#define __XDP_FILTER_H #define __XDP_FILTER_H
#define MAX_PAYLOAD_LEN 127
struct event {
char payload[MAX_PAYLOAD_LEN];
//bool exit_event;
};
#endif #endif

View File

@@ -7,6 +7,7 @@
#include <linux/if_link.h> #include <linux/if_link.h>
#include <net/if.h> #include <net/if.h>
#include <unistd.h> #include <unistd.h>
#include <bpf/bpf.h>
#include "xdp_filter.skel.h" #include "xdp_filter.skel.h"
@@ -106,7 +107,7 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
int main(int argc, char**argv){ int main(int argc, char**argv){
struct ring_buffer *rb = NULL; struct ring_buffer *rb = NULL;
struct xdp_filter_bpf *skel; struct xdp_filter_bpf *skel;
int err; __u32 err;
//Ready to be used //Ready to be used
/*for (int arg = 1; arg < argc; arg++) { /*for (int arg = 1; arg < argc; arg++) {
@@ -116,7 +117,7 @@ int main(int argc, char**argv){
} }
}*/ }*/
unsigned int ifindex; __u32 ifindex;
/* Parse command line arguments */ /* Parse command line arguments */
int opt; int opt;
@@ -164,35 +165,74 @@ int main(int argc, char**argv){
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler); signal(SIGTERM, sig_handler);
// Load and verify BPF application //Open and create BPF application in the kernel
skel = xdp_filter_bpf__open(); skel = xdp_filter_bpf__open();
if (!skel) { if (!skel) {
fprintf(stderr, "Failed to open and load BPF skeleton\n"); fprintf(stderr, "Failed to open and load BPF skeleton\n");
return 1; return 1;
} }
// Load & verify BPF programs */ //Load & verify BPF program
err = xdp_filter_bpf__load(skel); err = xdp_filter_bpf__load(skel);
if (err) { if (err) {
fprintf(stderr, "Failed to load and verify BPF skeleton\n"); fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto cleanup; goto cleanup;
} }
// Attach tracepoint for
err = xdp_filter_bpf__attach(skel); //Attack BPF program to network interface
//New way of doing it: it allows for future addition of multiple
//XDP programs attached to same interface if needed
//Also done this way to modularize attaching the different tracepoints
//of the rootkit
/** @ref Test suite by readhat ebpf devs on XDP
* https://git.zx2c4.com/linux/plain/tools/testing/selftests/bpf/prog_tests/xdp_link.c
*/
struct bpf_prog_info prog_info;
__u32 bpf_prog_info_size = sizeof(prog_info);
__u32 xdp_prog_fd = bpf_program__fd(skel->progs.xdp_receive);
__u32 xdp_prog_id_old = 0;
__u32 xdp_prog_id_new;
DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = -1);
int flags = XDP_FLAGS_REPLACE;
memset(&prog_info, 0, bpf_prog_info_size);
err = bpf_obj_get_info_by_fd(xdp_prog_fd, &prog_info, &bpf_prog_info_size);
if(err<0){
fprintf(stderr, "Failed to setup xdp link\n");
goto cleanup;
}
xdp_prog_id_new = prog_info.id;
//Check whether there exists previously loaded XDP program
err = bpf_get_link_xdp_id(ifindex, &xdp_prog_id_old, 0);
if(err<0 || (xdp_prog_id_old!=0 && xdp_prog_id_old!=xdp_prog_id_new)){
fprintf(stderr, "Xdp program found id--> old:%u != new:%u\n", xdp_prog_id_old, xdp_prog_id_new);
fprintf(stderr,"This should not happen, since our xdp program is removed automatically between calls\nRun `ip link set dev lo xdpgeneric off` to detach whichever program is running");
//TODO automatically force the reattach
goto cleanup;
}
// Attach loaded xdp program
skel->links.xdp_receive = bpf_program__attach_xdp(skel->progs.xdp_receive, ifindex);
err = libbpf_get_error(skel->links.xdp_receive);
if (err) { if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n"); fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup; goto cleanup;
} }
//Attack BPF program to network interface //Attach sched module (testing)
int flags = XDP_FLAGS_SKB_MODE; skel->links.handle_sched_process_exec = bpf_program__attach(skel->progs.handle_sched_process_exec);
int fd = bpf_program__fd(skel->progs.xdp_receive); err = libbpf_get_error(skel->links.handle_sched_process_exec);
err = bpf_set_link_xdp_fd(ifindex, fd, flags); if (err<0) {
fprintf(stderr, "Failed to attach sched module\n");
goto cleanup;
}
/* Set up ring buffer polling */
// Set up ring buffer polling --> Main communication buffer kernel->user
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb_comm), handle_rb_event, NULL, NULL); rb = ring_buffer__new(bpf_map__fd(skel->maps.rb_comm), handle_rb_event, NULL, NULL);
if (!rb) { if (rb==NULL) {
err = -1; err = -1;
fprintf(stderr, "Failed to create ring buffer\n"); fprintf(stderr, "Failed to create ring buffer\n");
goto cleanup; goto cleanup;
@@ -215,7 +255,7 @@ int main(int argc, char**argv){
} }
//Received signal to stop, detach program from network interface //Received signal to stop, detach program from network interface
fd = -1; __u32 fd = -1;
err = bpf_set_link_xdp_fd(ifindex, fd, flags); err = bpf_set_link_xdp_fd(ifindex, fd, flags);