Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enrich addr info with remote addr info #684

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion kern/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@

#define AF_INET 2
#define AF_INET6 10
#define SA_DATA_LEN 14
#define BASH_ERRNO_DEFAULT 128

#define BASH_EVENT_TYPE_READLINE 0
Expand Down
155 changes: 145 additions & 10 deletions kern/openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ struct connect_event_t {
u32 pid;
u32 tid;
u32 fd;
char sa_data[SA_DATA_LEN];
u16 sport;
u16 dport;
__be32 saddr;
__be32 daddr;
char comm[TASK_COMM_LEN];
};
} __attribute__((packed)); // NOTE: do not leave padding hole in this struct.

struct active_ssl_buf {
/*
Expand All @@ -59,6 +62,11 @@ struct active_ssl_buf {
const char* buf;
};

struct tcp_fd_info {
u64 file;
int fd;
};

/***********************************************************
* BPF MAPS
***********************************************************/
Expand Down Expand Up @@ -114,6 +122,14 @@ struct {
} ssl_st_fd SEC(".maps");


struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, u64);
__type(value, struct tcp_fd_info);
__uint(max_entries, 10240);
} tcp_fd_infos SEC(".maps");


/***********************************************************
* General helper functions
***********************************************************/
Expand Down Expand Up @@ -436,14 +452,67 @@ int probe_ret_SSL_read(struct pt_regs* ctx) {
return 0;
}


static __inline struct tcp_fd_info *find_fd_info(struct pt_regs *regs) {
u64 pid_tgid = bpf_get_current_pid_tgid();

return bpf_map_lookup_elem(&tcp_fd_infos, &pid_tgid);
}

static __inline struct tcp_fd_info *lookup_and_delete_fd_info(struct pt_regs *regs) {
struct tcp_fd_info *fd_info;
u64 pid_tgid;

pid_tgid = bpf_get_current_pid_tgid();
fd_info = bpf_map_lookup_elem(&tcp_fd_infos, &pid_tgid);
if (fd_info) {
bpf_map_delete_elem(&tcp_fd_infos, &pid_tgid);
}
return fd_info;
}

static __inline struct sock *tcp_sock_from_file(u64 ptr) {
struct socket *socket;
struct file *file;
struct sock *sk;

file = (struct file *)ptr;
bpf_probe_read_kernel(&socket, sizeof(socket), &file->private_data);
bpf_probe_read_kernel(&sk, sizeof(sk), &socket->sk);
return sk;
}

// libc : int __connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
// kernel : int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
SEC("kprobe/sys_connect")
int probe_connect(struct pt_regs* ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
struct tcp_fd_info fd_info = {};

fd_info.fd = PT_REGS_PARM1(ctx);
bpf_map_update_elem(&tcp_fd_infos, &pid_tgid, &fd_info, BPF_ANY);
return 0;
}

SEC("kprobe/__sys_connect_file")
int probe_connect_file(struct pt_regs* ctx) {
struct tcp_fd_info *fd_info;

fd_info = find_fd_info(ctx);
if (fd_info) {
fd_info->file = (u64)(void *) PT_REGS_PARM1(ctx);
}
return 0;
}

static __inline int kretprobe_connect(struct pt_regs *ctx, int fd, struct sock *sk, const bool active) {
u64 current_pid_tgid = bpf_get_current_pid_tgid();
u32 pid = current_pid_tgid >> 32;
u64 current_uid_gid = bpf_get_current_uid_gid();
u32 uid = current_uid_gid;
u16 address_family = 0;
u64 addrs;
u32 ports;

#ifndef KERNEL_LESS_5_2
// if target_ppid is 0 then we target all pids
Expand All @@ -455,16 +524,15 @@ int probe_connect(struct pt_regs* ctx) {
}
#endif

u32 fd = (u32)PT_REGS_PARM1(ctx);
struct sockaddr* saddr = (struct sockaddr*)PT_REGS_PARM2(ctx);
if (!saddr) {
bpf_probe_read_kernel(&address_family, sizeof(address_family), &sk->__sk_common.skc_family);
if (address_family != AF_INET) {
return 0;
}
sa_family_t address_family = 0;
bpf_probe_read_user(&address_family, sizeof(address_family),
&saddr->sa_family);

if (address_family != AF_INET) {
// if the connection hasn't been established yet, the ports or addrs are 0.
bpf_probe_read_kernel(&addrs, sizeof(addrs), &sk->__sk_common.skc_addrpair);
bpf_probe_read_kernel(&ports, sizeof(ports), &sk->__sk_common.skc_portpair);
if (ports == 0 || addrs == 0) {
return 0;
}

Expand All @@ -476,14 +544,81 @@ int probe_connect(struct pt_regs* ctx) {
conn.pid = pid;
conn.tid = current_pid_tgid;
conn.fd = fd;
bpf_probe_read_user(&conn.sa_data, SA_DATA_LEN, &saddr->sa_data);
if (active) {
conn.dport = bpf_ntohs((u16)ports);
conn.sport = ports >> 16;
conn.daddr = (__be32)addrs;
conn.saddr = (__be32)(addrs >> 32);
} else {
conn.sport = bpf_ntohs((u16)ports);
conn.dport = ports >> 16;
conn.saddr = (__be32)addrs;
conn.daddr = (__be32)(addrs >> 32);
}
bpf_get_current_comm(&conn.comm, sizeof(conn.comm));

bpf_perf_event_output(ctx, &connect_events, BPF_F_CURRENT_CPU, &conn,
sizeof(struct connect_event_t));
return 0;
}

SEC("kretprobe/sys_connect")
int retprobe_connect(struct pt_regs* ctx) {
struct tcp_fd_info *fd_info;
struct sock *sk;

fd_info = lookup_and_delete_fd_info(ctx);
if (fd_info) {
sk = tcp_sock_from_file(fd_info->file);
if (sk) {
return kretprobe_connect(ctx, fd_info->fd, sk, true);
}
}
return 0;
}

#ifndef IS_ERR_VALUE
#define MAX_ERRNO 4095
#define IS_ERR_VALUE(x) ((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)
#endif

SEC("kretprobe/do_accept")
int retprobe_do_accept(struct pt_regs* ctx) {
struct tcp_fd_info *fd_info;
struct file *file;

file = (struct file *)PT_REGS_RC(ctx);
if (IS_ERR_VALUE(file)) {
return 0;
}

fd_info = find_fd_info(ctx);
if (fd_info) {
fd_info->file = (u64)file;
}
return 0;
}

SEC("kretprobe/__sys_accept4")
int retprobe_accept4(struct pt_regs* ctx) {
struct tcp_fd_info *fd_info;
struct sock *sk;
int fd;

fd = PT_REGS_RC(ctx);
if (fd < 0) {
return 0;
}

fd_info = lookup_and_delete_fd_info(ctx);
if (fd_info) {
sk = tcp_sock_from_file(fd_info->file);
if (sk) {
return kretprobe_connect(ctx, fd, sk, false);
}
}
return 0;
}


// int SSL_set_fd(SSL *s, int fd)
Expand Down
3 changes: 1 addition & 2 deletions pkg/event_processor/base_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"bytes"
"encoding/binary"
"fmt"

"github.com/gojue/ecapture/user/event"
)

Expand All @@ -35,8 +36,6 @@ const ChunkSizeHalf = ChunkSize / 2

const MaxDataSize = 1024 * 4

//const SaDataLen = 14

const (
Ssl2Version = 0x0002
Ssl3Version = 0x0300
Expand Down
Loading
Loading