Skip to content
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
145 changes: 144 additions & 1 deletion src/30-sslsniff/sslsniff.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -217,4 +360,4 @@ int BPF_URETPROBE(probe_SSL_do_handshake_exit) {
return 0;
}

char LICENSE[] SEC("license") = "GPL";
char LICENSE[] SEC("license") = "GPL";
11 changes: 7 additions & 4 deletions src/30-sslsniff/sslsniff.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
#include <bpf/libbpf.h>
#include <ctype.h>
#include <errno.h>
#include <linux/types.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Expand Down Expand Up @@ -92,8 +90,8 @@ struct env {
.uid = INVALID_UID,
.pid = INVALID_PID,
.openssl = true,
.gnutls = true,
.nss = true,
.gnutls = false,
.nss = false,
.comm = NULL,
};

Expand Down Expand Up @@ -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);
Expand Down