Skip to content
Draft
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
2 changes: 0 additions & 2 deletions kern/bash_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ SEC("uretprobe/bash_retval")
int uretprobe_bash_retval(struct pt_regs *ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u64 current_uid_gid = bpf_get_current_uid_gid();
u32 uid = current_uid_gid;
int retval = (int)PT_REGS_RC(ctx);

if (!passes_filter(ctx)) {
Expand Down
6 changes: 3 additions & 3 deletions kern/go_argument.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@

#endif

void* go_get_argument_by_reg(struct pt_regs *ctx, int index) {
static __always_inline void* go_get_argument_by_reg(struct pt_regs *ctx, int index) {
switch (index) {
case 1:
return (void*)GO_PARAM1(ctx);
Expand All @@ -94,13 +94,13 @@ void* go_get_argument_by_reg(struct pt_regs *ctx, int index) {
}
}

void* go_get_argument_by_stack(struct pt_regs *ctx, int index) {
static __always_inline void* go_get_argument_by_stack(struct pt_regs *ctx, int index) {
void* ptr = 0;
bpf_probe_read(&ptr, sizeof(ptr), (void *)(PT_REGS_SP(ctx)+(index*8)));
return ptr;
}

void* go_get_argument(struct pt_regs *ctx,bool is_register_abi, int index) {
static __always_inline void* go_get_argument(struct pt_regs *ctx, bool is_register_abi, int index) {
if (is_register_abi) {
return go_get_argument_by_reg(ctx, index);
}
Expand Down
8 changes: 0 additions & 8 deletions kern/mysqld_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ int mysql56_query(struct pt_regs *ctx) {

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;

if (!passes_filter(ctx)) {
return 0;
Expand Down Expand Up @@ -109,8 +107,6 @@ int mysql56_query_return(struct pt_regs *ctx) {

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;

if (!passes_filter(ctx)) {
return 0;
Expand Down Expand Up @@ -180,8 +176,6 @@ int mysql57_query(struct pt_regs *ctx) {

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;

if (!passes_filter(ctx)) {
return 0;
Expand Down Expand Up @@ -217,8 +211,6 @@ SEC("uretprobe/dispatch_command_57")
int mysql57_query_return(struct pt_regs *ctx) {
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;

if (!passes_filter(ctx)) {
return 0;
Expand Down
114 changes: 114 additions & 0 deletions kern/nspr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2022 CFC4N <[email protected]>. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ECAPTURE_NSPR_H
#define ECAPTURE_NSPR_H

#include "ecapture.h"

/***********************************************************
* Internal structs and definitions
***********************************************************/

enum nspr_data_event_type { kNSPRRead, kNSPRWrite };

struct nspr_data_event_t {
enum nspr_data_event_type type;
u64 timestamp_ns;
u32 pid;
u32 tid;
char data[MAX_DATA_SIZE_OPENSSL];
s32 data_len;
char comm[TASK_COMM_LEN];
};

/***********************************************************
* BPF MAPS
***********************************************************/

struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u32));
__uint(max_entries, 1024);
} nspr_events SEC(".maps");

// Key is thread ID (from bpf_get_current_pid_tgid).
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, u64);
__type(value, const char*);
__uint(max_entries, 1024);
} active_nspr_read_args_map SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, u64);
__type(value, const char*);
__uint(max_entries, 1024);
} active_nspr_write_args_map SEC(".maps");

// BPF programs are limited to a 512-byte stack. We store this value per CPU
// and use it as a heap allocated value.
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, u32);
__type(value, struct nspr_data_event_t);
__uint(max_entries, 1);
} nspr_data_buffer_heap SEC(".maps");

/***********************************************************
* General helper functions
***********************************************************/

static __inline struct nspr_data_event_t* create_nspr_data_event(u64 current_pid_tgid) {
u32 kZero = 0;
struct nspr_data_event_t* event = bpf_map_lookup_elem(&nspr_data_buffer_heap, &kZero);
if (event == NULL) {
return NULL;
}

const u32 kMask32b = 0xffffffff;
event->timestamp_ns = bpf_ktime_get_ns();
event->pid = current_pid_tgid >> 32;
event->tid = current_pid_tgid & kMask32b;
return event;
}

/***********************************************************
* BPF syscall processing functions
***********************************************************/

static int process_nspr_data(struct pt_regs* ctx, u64 id, enum nspr_data_event_type type, const char* buf) {
int len = (int)PT_REGS_RC(ctx);
if (len < 0) {
return 0;
}

struct nspr_data_event_t* event = create_nspr_data_event(id);
if (event == NULL) {
return 0;
}

event->type = type;
// This is a max function, but it is written in such a way to keep older BPF
// verifiers happy.
event->data_len = (len < MAX_DATA_SIZE_OPENSSL ? (len & (MAX_DATA_SIZE_OPENSSL - 1)) : MAX_DATA_SIZE_OPENSSL);
bpf_probe_read_user(event->data, event->data_len, buf);
bpf_get_current_comm(&event->comm, sizeof(event->comm));
bpf_perf_event_output(ctx, &nspr_events, BPF_F_CURRENT_CPU, event, sizeof(struct nspr_data_event_t));
return 0;
}

#endif
122 changes: 10 additions & 112 deletions kern/nspr_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,182 +12,80 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "ecapture.h"

enum ssl_data_event_type { kSSLRead, kSSLWrite };

struct ssl_data_event_t {
enum ssl_data_event_type type;
u64 timestamp_ns;
u32 pid;
u32 tid;
char data[MAX_DATA_SIZE_OPENSSL];
s32 data_len;
char comm[TASK_COMM_LEN];
};

struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u32));
__uint(max_entries, 1024);
} nspr_events SEC(".maps");

/***********************************************************
* Internal structs and definitions
***********************************************************/

// Key is thread ID (from bpf_get_current_pid_tgid).
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, u64);
__type(value, const char*);
__uint(max_entries, 1024);
} active_ssl_read_args_map SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, u64);
__type(value, const char*);
__uint(max_entries, 1024);
} active_ssl_write_args_map SEC(".maps");

// BPF programs are limited to a 512-byte stack. We store this value per CPU
// and use it as a heap allocated value.
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, u32);
__type(value, struct ssl_data_event_t);
__uint(max_entries, 1);
} data_buffer_heap SEC(".maps");

/***********************************************************
* General helper functions
***********************************************************/

static __inline struct ssl_data_event_t* create_ssl_data_event(u64 current_pid_tgid) {
u32 kZero = 0;
struct ssl_data_event_t* event = bpf_map_lookup_elem(&data_buffer_heap, &kZero);
if (event == NULL) {
return NULL;
}

const u32 kMask32b = 0xffffffff;
event->timestamp_ns = bpf_ktime_get_ns();
event->pid = current_pid_tgid >> 32;
event->tid = current_pid_tgid & kMask32b;
return event;
}

/***********************************************************
* BPF syscall processing functions
***********************************************************/

static int process_SSL_data(struct pt_regs* ctx, u64 id, enum ssl_data_event_type type, const char* buf) {
int len = (int)PT_REGS_RC(ctx);
if (len < 0) {
return 0;
}

struct ssl_data_event_t* event = create_ssl_data_event(id);
if (event == NULL) {
return 0;
}

event->type = type;
// This is a max function, but it is written in such a way to keep older BPF
// verifiers happy.
event->data_len = (len < MAX_DATA_SIZE_OPENSSL ? (len & (MAX_DATA_SIZE_OPENSSL - 1)) : MAX_DATA_SIZE_OPENSSL);
bpf_probe_read_user(event->data, event->data_len, buf);
bpf_get_current_comm(&event->comm, sizeof(event->comm));
bpf_perf_event_output(ctx, &nspr_events, BPF_F_CURRENT_CPU, event, sizeof(struct ssl_data_event_t));
return 0;
}
#include "nspr.h"

/***********************************************************
* BPF probe function entry-points
***********************************************************/
// https://www-archive.mozilla.org/projects/nspr/reference/html/priofnc.html#19250
//
//

SEC("uprobe/PR_Write")
int probe_entry_SSL_write(struct pt_regs* ctx) {
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;
debug_bpf_printk("nspr uprobe/PR_Write pid :%d\n", pid);

if (!passes_filter(ctx)) {
return 0;
}

const char* buf = (const char*)PT_REGS_PARM2(ctx);
bpf_map_update_elem(&active_ssl_write_args_map, &current_pid_tgid, &buf, BPF_ANY);
bpf_map_update_elem(&active_nspr_write_args_map, &current_pid_tgid, &buf, BPF_ANY);
return 0;
}

SEC("uretprobe/PR_Write")
int probe_ret_SSL_write(struct pt_regs* ctx) {
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;
debug_bpf_printk("nspr uretprobe/PR_Write pid :%d\n", pid);

if (!passes_filter(ctx)) {
return 0;
}

const char** buf = bpf_map_lookup_elem(&active_ssl_write_args_map, &current_pid_tgid);
const char** buf = bpf_map_lookup_elem(&active_nspr_write_args_map, &current_pid_tgid);
if (buf != NULL) {
process_SSL_data(ctx, current_pid_tgid, kSSLWrite, *buf);
process_nspr_data(ctx, current_pid_tgid, kNSPRWrite, *buf);
}

bpf_map_delete_elem(&active_ssl_write_args_map, &current_pid_tgid);
bpf_map_delete_elem(&active_nspr_write_args_map, &current_pid_tgid);
return 0;
}

// Function signature being probed:
// int SSL_read(SSL *s, void *buf, int num)
// ssize_t gnutls_record_recv (gnutls_session session, void * data, size_t
// sizeofdata)
// PRInt32 PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount)

SEC("uprobe/PR_Read")
int probe_entry_SSL_read(struct pt_regs* ctx) {
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;
debug_bpf_printk("nspr uprobe/PR_Read pid :%d\n", pid);

if (!passes_filter(ctx)) {
return 0;
}

const char* buf = (const char*)PT_REGS_PARM2(ctx);
bpf_map_update_elem(&active_ssl_read_args_map, &current_pid_tgid, &buf, BPF_ANY);
bpf_map_update_elem(&active_nspr_read_args_map, &current_pid_tgid, &buf, BPF_ANY);
return 0;
}

SEC("uretprobe/PR_Read")
int probe_ret_SSL_read(struct pt_regs* ctx) {
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;
debug_bpf_printk("nspr uretprobe/PR_Read pid :%d\n", pid);

if (!passes_filter(ctx)) {
return 0;
}

const char** buf = bpf_map_lookup_elem(&active_ssl_read_args_map, &current_pid_tgid);
const char** buf = bpf_map_lookup_elem(&active_nspr_read_args_map, &current_pid_tgid);
if (buf != NULL) {
process_SSL_data(ctx, current_pid_tgid, kSSLRead, *buf);
process_nspr_data(ctx, current_pid_tgid, kNSPRRead, *buf);
}

bpf_map_delete_elem(&active_ssl_read_args_map, &current_pid_tgid);
bpf_map_delete_elem(&active_nspr_read_args_map, &current_pid_tgid);
return 0;
}
7 changes: 0 additions & 7 deletions kern/openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,6 @@ int probe_inet_stream_connect(struct pt_regs* ctx) {
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;
unsigned __int128 saddr;
unsigned __int128 daddr;
Expand Down Expand Up @@ -530,11 +528,6 @@ int probe_tcp_v4_destroy_sock(struct pt_regs* ctx) {
// int SSL_set_wfd(SSL *s, int fd)
SEC("uprobe/SSL_set_fd")
int probe_SSL_set_fd(struct pt_regs* ctx) {
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;

u64 ssl_addr = (u64)PT_REGS_PARM1(ctx);
u64 fd = (u64)PT_REGS_PARM2(ctx);
bpf_map_update_elem(&ssl_st_fd, &ssl_addr, &fd, BPF_ANY);
Expand Down
Loading
Loading