diff --git a/src/30-sslsniff/sslsniff.bpf.c b/src/30-sslsniff/sslsniff.bpf.c index 4ed51736..1b0a8866 100644 --- a/src/30-sslsniff/sslsniff.bpf.c +++ b/src/30-sslsniff/sslsniff.bpf.c @@ -16,6 +16,13 @@ struct { __uint(value_size, sizeof(__u32)); } perf_SSL_events SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 10240); + __type(key, __u32); + __type(value, size_t*); +} readbytes_ptrs SEC(".maps"); + #define BASE_EVENT_SIZE ((size_t)(&((struct probe_SSL_data_t *)0)->buf)) #define EVENT_SIZE(X) (BASE_EVENT_SIZE + ((size_t)(X))) #define MAX_ENTRIES 10240 @@ -153,6 +160,142 @@ int BPF_URETPROBE(probe_SSL_write_exit) { return (SSL_exit(ctx, 1)); } +SEC("uprobe/SSL_write_ex") +int BPF_UPROBE(probe_SSL_write_ex_enter, void *ssl, void *buf, size_t num, size_t *readbytes) { + u64 pid_tgid = bpf_get_current_pid_tgid(); + u32 pid = pid_tgid >> 32; + u32 tid = (u32)pid_tgid; + u32 uid = bpf_get_current_uid_gid(); + u64 ts = bpf_ktime_get_ns(); + + if (!trace_allowed(uid, pid)) { + return 0; + } + + bpf_map_update_elem(&bufs, &tid, &buf, BPF_ANY); + bpf_map_update_elem(&start_ns, &tid, &ts, BPF_ANY); + + bpf_map_update_elem(&readbytes_ptrs, &tid, &readbytes, BPF_ANY); + + return 0; +} + +SEC("uprobe/SSL_read_ex") +int BPF_UPROBE(probe_SSL_read_ex_enter, void *ssl, void *buf, size_t num, size_t *readbytes) { + u64 pid_tgid = bpf_get_current_pid_tgid(); + u32 pid = pid_tgid >> 32; + u32 tid = (u32)pid_tgid; + u32 uid = bpf_get_current_uid_gid(); + u64 ts = bpf_ktime_get_ns(); + + if (!trace_allowed(uid, pid)) { + return 0; + } + + bpf_map_update_elem(&bufs, &tid, &buf, BPF_ANY); + bpf_map_update_elem(&start_ns, &tid, &ts, BPF_ANY); + + bpf_map_update_elem(&readbytes_ptrs, &tid, &readbytes, BPF_ANY); + + return 0; +} + +static int ex_SSL_exit(struct pt_regs *ctx, int rw, int len) { + int ret = 0; + u32 zero = 0; + u64 pid_tgid = bpf_get_current_pid_tgid(); + u32 pid = pid_tgid >> 32; + u32 tid = (u32)pid_tgid; + u32 uid = bpf_get_current_uid_gid(); + u64 ts = bpf_ktime_get_ns(); + + if (!trace_allowed(uid, pid)) { + return 0; + } + + /* store arg info for later lookup */ + u64 *bufp = bpf_map_lookup_elem(&bufs, &tid); + if (bufp == 0) + return 0; + + u64 *tsp = bpf_map_lookup_elem(&start_ns, &tid); + if (!tsp) + return 0; + u64 delta_ns = ts - *tsp; + + if (len <= 0) // no data + return 0; + + struct probe_SSL_data_t *data = bpf_map_lookup_elem(&ssl_data, &zero); + if (!data) + return 0; + + data->timestamp_ns = ts; + data->delta_ns = delta_ns; + data->pid = pid; + data->tid = tid; + data->uid = uid; + data->len = (u32)len; + data->buf_filled = 0; + data->rw = rw; + data->is_handshake = false; + u32 buf_copy_size = min((size_t)MAX_BUF_SIZE, (size_t)len); + + bpf_get_current_comm(&data->comm, sizeof(data->comm)); + + if (bufp != 0) + ret = bpf_probe_read_user(&data->buf, buf_copy_size, (char *)*bufp); + + bpf_map_delete_elem(&bufs, &tid); + bpf_map_delete_elem(&start_ns, &tid); + + if (!ret) + data->buf_filled = 1; + else + buf_copy_size = 0; + + bpf_perf_event_output(ctx, &perf_SSL_events, BPF_F_CURRENT_CPU, data, + EVENT_SIZE(buf_copy_size)); + + return 0; +} + +SEC("uretprobe/SSL_write_ex") +int BPF_URETPROBE(probe_SSL_write_ex_exit) +{ + u32 tid = (u32)bpf_get_current_pid_tgid(); + size_t **readbytes_ptr = bpf_map_lookup_elem(&readbytes_ptrs, &tid); + if (!readbytes_ptr) + return 0; + + size_t written = 0; + bpf_probe_read_user(&written, sizeof(written), *readbytes_ptr); + bpf_map_delete_elem(&readbytes_ptrs, &tid); + + int ret = PT_REGS_RC(ctx); + int len = (ret == 1) ? written : 0; + + return ex_SSL_exit(ctx, 1, len); +} + +SEC("uretprobe/SSL_read_ex") +int BPF_URETPROBE(probe_SSL_read_ex_exit) +{ + u32 tid = (u32)bpf_get_current_pid_tgid(); + size_t **readbytes_ptr = bpf_map_lookup_elem(&readbytes_ptrs, &tid); + if (!readbytes_ptr) + return 0; + + size_t written = 0; + bpf_probe_read_user(&written, sizeof(written), *readbytes_ptr); + bpf_map_delete_elem(&readbytes_ptrs, &tid); + + int ret = PT_REGS_RC(ctx); + int len = (ret == 1) ? written : 0; + + return ex_SSL_exit(ctx, 1, len); +} + SEC("uprobe/do_handshake") int BPF_UPROBE(probe_SSL_do_handshake_enter, void *ssl) { u64 pid_tgid = bpf_get_current_pid_tgid(); @@ -217,4 +360,4 @@ int BPF_URETPROBE(probe_SSL_do_handshake_exit) { return 0; } -char LICENSE[] SEC("license") = "GPL"; +char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/src/30-sslsniff/sslsniff.c b/src/30-sslsniff/sslsniff.c index a9e27c9a..29949119 100644 --- a/src/30-sslsniff/sslsniff.c +++ b/src/30-sslsniff/sslsniff.c @@ -8,9 +8,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -92,8 +90,8 @@ struct env { .uid = INVALID_UID, .pid = INVALID_PID, .openssl = true, - .gnutls = true, - .nss = true, + .gnutls = false, + .nss = false, .comm = NULL, }; @@ -197,6 +195,11 @@ int attach_openssl(struct sslsniff_bpf *skel, const char *lib) { ATTACH_UPROBE_CHECKED(skel, lib, SSL_read, probe_SSL_rw_enter); ATTACH_URETPROBE_CHECKED(skel, lib, SSL_read, probe_SSL_read_exit); + ATTACH_UPROBE_CHECKED(skel, lib, SSL_write_ex, probe_SSL_write_ex_enter); + ATTACH_URETPROBE_CHECKED(skel, lib, SSL_write_ex, probe_SSL_write_ex_exit); + ATTACH_UPROBE_CHECKED(skel, lib, SSL_read_ex, probe_SSL_read_ex_enter); + ATTACH_URETPROBE_CHECKED(skel, lib, SSL_read_ex, probe_SSL_read_ex_exit); + if (env.latency && env.handshake) { ATTACH_UPROBE_CHECKED(skel, lib, SSL_do_handshake, probe_SSL_do_handshake_enter);