From 8d1d4f30194a6cf33549e6fc3bd1d29f9296b215 Mon Sep 17 00:00:00 2001 From: CFC4N Date: Thu, 20 Oct 2022 21:55:55 +0800 Subject: [PATCH 1/4] utils : add openssl 3.0 utils. Signed-off-by: CFC4N --- kern/openssl_masterkey_3.0.h | 263 +++++++++++++++++++++++++++++++++++ utils/openssl_3_0_offset.c | 54 +++++++ utils/openssl_offset_3.0.sh | 69 +++++++++ 3 files changed, 386 insertions(+) create mode 100644 kern/openssl_masterkey_3.0.h create mode 100644 utils/openssl_3_0_offset.c create mode 100755 utils/openssl_offset_3.0.sh diff --git a/kern/openssl_masterkey_3.0.h b/kern/openssl_masterkey_3.0.h new file mode 100644 index 000000000..f98e8f88e --- /dev/null +++ b/kern/openssl_masterkey_3.0.h @@ -0,0 +1,263 @@ +#include "ecapture.h" + +// https://wiki.openssl.org/index.php/TLS1.3 +// 仅openssl 1.1.1 后才支持 TLS 1.3 协议 + +// openssl 1.1.1.X 版本相关的常量 +#define SSL3_RANDOM_SIZE 32 +#define MASTER_SECRET_MAX_LEN 48 +#define EVP_MAX_MD_SIZE 64 + +struct mastersecret_t { + // TLS 1.2 or older + s32 version; + u8 client_random[SSL3_RANDOM_SIZE]; + u8 master_key[MASTER_SECRET_MAX_LEN]; + + // TLS 1.3 + u32 cipher_id; + u8 handshake_secret[EVP_MAX_MD_SIZE]; + u8 master_secret[EVP_MAX_MD_SIZE]; + u8 server_finished_hash[EVP_MAX_MD_SIZE]; + u8 handshake_traffic_hash[EVP_MAX_MD_SIZE]; + u8 exporter_master_secret[EVP_MAX_MD_SIZE]; +}; + +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 +#define TLS1_3_VERSION 0x0304 + +/////////////////////////BPF MAPS //////////////////////////////// + +// bpf map +struct { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); +} mastersecret_events SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_LRU_HASH); + __type(key, u64); + __type(value, struct mastersecret_t); + __uint(max_entries, 2048); +} bpf_context SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, u32); + __type(value, struct mastersecret_t); + __uint(max_entries, 1); +} bpf_context_gen SEC(".maps"); + +/////////////////////////COMMON FUNCTIONS //////////////////////////////// +//这个函数用来规避512字节栈空间限制,通过在堆上创建内存的方式,避开限制 +static __always_inline struct mastersecret_t *make_event() { + u32 key_gen = 0; + struct mastersecret_t *bpf_ctx = + bpf_map_lookup_elem(&bpf_context_gen, &key_gen); + if (!bpf_ctx) return 0; + u64 id = bpf_get_current_pid_tgid(); + bpf_map_update_elem(&bpf_context, &id, bpf_ctx, BPF_ANY); + return bpf_map_lookup_elem(&bpf_context, &id); +} + +/////////////////////////BPF FUNCTIONS //////////////////////////////// +SEC("uprobe/SSL_write_key") +int probe_ssl_master_key(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 >> 32; + +#ifndef KERNEL_LESS_5_2 + // if target_ppid is 0 then we target all pids + if (target_pid != 0 && target_pid != pid) { + return 0; + } + if (target_uid != 0 && target_uid != uid) { + return 0; + } +#endif + debug_bpf_printk("openssl uprobe/SSL_write masterKey PID :%d\n", pid); + + // mastersecret_t sent to userspace + struct mastersecret_t *mastersecret = make_event(); + // Get a ssl_st pointer + void *ssl_st_ptr = (void *)PT_REGS_PARM1(ctx); + if (!mastersecret) { + debug_bpf_printk("mastersecret is null\n"); + return 0; + } + + // Get SSL->version pointer + u64 *ssl_version_ptr = (u64 *)(ssl_st_ptr + SSL_ST_VERSION); + int version; + u64 address; + int ret = + bpf_probe_read_user(&version, sizeof(version), (void *)ssl_version_ptr); + if (ret) { + debug_bpf_printk("bpf_probe_read tls_version failed, ret :%d\n", ret); + return 0; + } + mastersecret->version = version; // int version; + debug_bpf_printk("TLS version :%d\n", mastersecret->version); + + u64 *ssl_client_random_ptr = (u64 *)(ssl_st_ptr + SSL_ST_S3_CLIENT_RANDOM); + // get SSL_ST_S3_CLIENT_RANDOM + unsigned char client_random[SSL3_RANDOM_SIZE]; + ret = bpf_probe_read_user(&client_random, sizeof(client_random), (void *)ssl_client_random_ptr); + if (ret) { + debug_bpf_printk( +"bpf_probe_read ssl3_ssl_client_random_ptr_st failed, ret :%d\n", ret); + return 0; + } + debug_bpf_printk("client_random: %x %x %x\n", client_random[0], + client_random[1], client_random[2]); + ret = bpf_probe_read_kernel(&mastersecret->client_random, + sizeof(mastersecret->client_random), + (void *)&client_random); + if (ret) { + debug_bpf_printk( + "bpf_probe_read_kernel ssl3_stat.client_random failed, ret :%d\n", + ret); + return 0; + } + + // Get ssl_session_st pointer + u64 *ssl_session_st_ptr; + u64 ssl_session_st_addr; + + ssl_session_st_ptr = (u64 *)(ssl_st_ptr + SSL_ST_SESSION); + ret = bpf_probe_read_user(&ssl_session_st_addr, sizeof(ssl_session_st_addr), + ssl_session_st_ptr); + if (ret) { + debug_bpf_printk( + "(OPENSSL) bpf_probe_read ssl_session_st_ptr failed, ret :%d\n", + ret); + return 0; + } + + ///////////////////////// get TLS 1.2 master secret //////////////////// + if (mastersecret->version != TLS1_3_VERSION) { + void *ms_ptr = (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); + ret = bpf_probe_read_user(&mastersecret->master_key, + sizeof(mastersecret->master_key), ms_ptr); + if (ret) { + debug_bpf_printk( + "bpf_probe_read MASTER_KEY_OFFSET failed, ms_ptr:%llx, ret " + ":%d\n", + ms_ptr, ret); + return 0; + } + + debug_bpf_printk("master_key: %x %x %x\n", mastersecret->master_key[0], + mastersecret->master_key[1], + mastersecret->master_key[2]); + + bpf_perf_event_output(ctx, &mastersecret_events, BPF_F_CURRENT_CPU, + mastersecret, sizeof(struct mastersecret_t)); + return 0; + } + + ///////////////////////// get TLS 1.3 master secret //////////////////// + // Get SSL_SESSION->cipher pointer + u64 *ssl_cipher_st_ptr = + (u64 *)(ssl_session_st_addr + SSL_SESSION_ST_CIPHER); + + // get cipher_suite_st pointer + debug_bpf_printk("cipher_suite_st pointer: %x\n", ssl_cipher_st_ptr); + ret = bpf_probe_read_user(&address, sizeof(address), ssl_cipher_st_ptr); + if (ret || address == 0) { + debug_bpf_printk( + "bpf_probe_read ssl_cipher_st_ptr failed, ret :%d, address:%x\n", + ret, address); + // return 0; + void *cipher_id_ptr = + (void *)(ssl_session_st_addr + SSL_SESSION_ST_CIPHER_ID); + ret = + bpf_probe_read_user(&mastersecret->cipher_id, + sizeof(mastersecret->cipher_id), cipher_id_ptr); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_SESSION_ST_CIPHER_ID failed from " + "SSL_SESSION->cipher_id, ret :%d\n", + ret); + return 0; + } + } else { + debug_bpf_printk("cipher_suite_st value: %x\n", address); + void *cipher_id_ptr = (void *)(address + SSL_CIPHER_ST_ID); + ret = + bpf_probe_read_user(&mastersecret->cipher_id, + sizeof(mastersecret->cipher_id), cipher_id_ptr); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_CIPHER_ST_ID failed from " + "ssl_cipher_st->id, ret :%d\n", + ret); + return 0; + } + } + + debug_bpf_printk("cipher_id: %d\n", mastersecret->cipher_id); + + //////////////////// TLS 1.3 master secret //////////////////////// + + void *hs_ptr_tls13 = (void *)(ssl_st_ptr + SSL_ST_HANDSHAKE_SECRET); + ret = bpf_probe_read_user(&mastersecret->handshake_secret, + sizeof(mastersecret->handshake_secret), + (void *)hs_ptr_tls13); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_ST_HANDSHAKE_SECRET failed, ret :%d\n", ret); + return 0; + } + + void *ms_ptr_tls13 = (void *)(ssl_st_ptr + SSL_ST_MASTER_SECRET); + ret = bpf_probe_read_user(&mastersecret->master_secret, + sizeof(mastersecret->master_secret), + (void *)ms_ptr_tls13); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_ST_MASTER_SECRET failed, ret :%d\n", ret); + return 0; + } + + void *sf_ptr_tls13 = (void *)(ssl_st_ptr + SSL_ST_SERVER_FINISHED_HASH); + ret = bpf_probe_read_user(&mastersecret->server_finished_hash, + sizeof(mastersecret->server_finished_hash), + (void *)sf_ptr_tls13); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_ST_SERVER_FINISHED_HASH failed, ret :%d\n", + ret); + return 0; + } + + void *hth_ptr_tls13 = (void *)(ssl_st_ptr + SSL_ST_HANDSHAKE_TRAFFIC_HASH); + ret = bpf_probe_read_user(&mastersecret->handshake_traffic_hash, + sizeof(mastersecret->handshake_traffic_hash), + (void *)hth_ptr_tls13); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_ST_HANDSHAKE_TRAFFIC_HASH failed, ret :%d\n", + ret); + return 0; + } + + void *ems_ptr_tls13 = (void *)(ssl_st_ptr + SSL_ST_EXPORTER_MASTER_SECRET); + ret = bpf_probe_read_user(&mastersecret->exporter_master_secret, + sizeof(mastersecret->exporter_master_secret), + (void *)ems_ptr_tls13); + if (ret) { + debug_bpf_printk( + "bpf_probe_read SSL_ST_EXPORTER_MASTER_SECRET failed, ret :%d\n", + ret); + return 0; + } + debug_bpf_printk( + "*****master_secret*****: %x %x %x\n", mastersecret->master_secret[0], + mastersecret->master_secret[1], mastersecret->master_secret[2]); + bpf_perf_event_output(ctx, &mastersecret_events, BPF_F_CURRENT_CPU, + mastersecret, sizeof(struct mastersecret_t)); + return 0; +} \ No newline at end of file diff --git a/utils/openssl_3_0_offset.c b/utils/openssl_3_0_offset.c new file mode 100644 index 000000000..5ef6ba672 --- /dev/null +++ b/utils/openssl_3_0_offset.c @@ -0,0 +1,54 @@ +// clang -I include/ -I . offset.c -o offset + +#include +#include +#include +#include + +#define SSL_STRUCT_OFFSETS \ + X(ssl_st, version) \ + X(ssl_st, session) \ + X(ssl_st, s3) \ + X(ssl_session_st, master_key) \ + X(ssl_st, s3.client_random) \ + X(ssl_session_st, cipher) \ + X(ssl_session_st, cipher_id) \ + X(ssl_cipher_st, id) \ + X(ssl_st, handshake_secret) \ + X(ssl_st, master_secret) \ + X(ssl_st, server_finished_hash) \ + X(ssl_st, handshake_traffic_hash) \ + X(ssl_st, exporter_master_secret) + +void toUpper(char *s) { + int i = 0; + while (s[i] != '\0') { + if (s[i] == '.') { + putchar('_'); + } else { + putchar(toupper(s[i])); + } + i++; + } +} + +void format(char *struct_name, char *field_name, size_t offset) { + printf("// %s->%s\n", struct_name, field_name); + printf("#define "); + toUpper(struct_name); + printf("_"); + toUpper(field_name); + printf(" 0x%lx\n\n", offset); +} + +int main() { + printf("/* OPENSSL_VERSION_TEXT: %s, OPENSSL_VERSION_NUMBER: %ld */\n\n", + OPENSSL_VERSION_TEXT, OPENSSL_VERSION_NUMBER); + +#define X(struct_name, field_name) \ + format(#struct_name, #field_name, offsetof(struct struct_name, field_name)); + SSL_STRUCT_OFFSETS +#undef X + + return 0; +} diff --git a/utils/openssl_offset_3.0.sh b/utils/openssl_offset_3.0.sh new file mode 100755 index 000000000..b097f563d --- /dev/null +++ b/utils/openssl_offset_3.0.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +set -e + +PROJECT_ROOT_DIR=$(pwd) +OPENSSL_DIR="${PROJECT_ROOT_DIR}/deps/openssl" +OUTPUT_DIR="${PROJECT_ROOT_DIR}/kern" + +if [[ ! -f "go.mod" ]]; then + echo "Run the script from the project root directory" + exit 1 +fi + +# skip cloning if the header file of the max supported version is already generated +if [[ ! -f "${OUTPUT_DIR}/openssl_3_0_0_kern.c" ]]; then + # skip cloning if the openssl directory already exists + if [[ ! -d "${OPENSSL_DIR}" ]]; then + git clone https://github.com/openssl/openssl.git ${OPENSSL_DIR} + fi +fi + +function run() { + git fetch --tags + cp -f ${PROJECT_ROOT_DIR}/utils/openssl_3_0_offset.c ${OPENSSL_DIR}/offset.c + + for ver in {0..6}; do + tag="openssl-3.0.${ver}" + header_file="${OUTPUT_DIR}/openssl_3_0_${ver}_kern.c" + header_define="OPENSSL_3_0_$(echo ${ver} | tr "[:lower:]" "[:upper:]")_KERN_H" + + if [[ -f ${header_file} ]]; then + echo "Skip ${header_file}" + continue + fi + + git checkout ${tag} + echo "Generating ${header_file}" + + + # config and make openssl/opensslconf.h + ./config + +# make reconfigure reconf + make include/openssl/opensslconf.h + make include/openssl/configuration.h + make build_generated + + # set flag to include ssl/ssl_locl.h in openssl-3.0{0..6} + + clang -I include/ -I . offset.c -o offset $flag + + echo -e "#ifndef ECAPTURE_${header_define}" >${header_file} + echo -e "#define ECAPTURE_${header_define}\n" >>${header_file} + ./offset >>${header_file} + echo -e "#include \"openssl.h\"" >>${header_file} + echo -e "#include \"openssl_masterkey_3.0.h\"" >>${header_file} + echo -e "\n#endif\n" >>${header_file} + + # clean up + make clean + + done + + rm offset.c +} + +pushd ${OPENSSL_DIR} +(run) +[[ "$?" != 0 ]] && popd +popd From 9029e72a9f4ad25c32c9591354631264e3f8de89 Mon Sep 17 00:00:00 2001 From: CFC4N Date: Thu, 20 Oct 2022 21:59:33 +0800 Subject: [PATCH 2/4] kern : add offset files of openssl 3.0.* versions. Signed-off-by: CFC4N --- Makefile | 1 + kern/openssl_3_0_0_kern.c | 49 ++++++++++++++++++++++++++++++++ kern/openssl_3_0_1_kern.c | 49 ++++++++++++++++++++++++++++++++ kern/openssl_3_0_2_kern.c | 49 ++++++++++++++++++++++++++++++++ kern/openssl_3_0_3_kern.c | 49 ++++++++++++++++++++++++++++++++ kern/openssl_3_0_4_kern.c | 49 ++++++++++++++++++++++++++++++++ kern/openssl_3_0_5_kern.c | 49 ++++++++++++++++++++++++++++++++ kern/openssl_3_0_6_kern.c | 49 ++++++++++++++++++++++++++++++++ user/module/const.go | 4 --- user/module/probe_openssl.go | 3 ++ user/module/probe_openssl_lib.go | 11 ++++++- 11 files changed, 357 insertions(+), 5 deletions(-) create mode 100644 kern/openssl_3_0_0_kern.c create mode 100644 kern/openssl_3_0_1_kern.c create mode 100644 kern/openssl_3_0_2_kern.c create mode 100644 kern/openssl_3_0_3_kern.c create mode 100644 kern/openssl_3_0_4_kern.c create mode 100644 kern/openssl_3_0_5_kern.c create mode 100644 kern/openssl_3_0_6_kern.c diff --git a/Makefile b/Makefile index 8fda2d9fa..2ea8a6936 100644 --- a/Makefile +++ b/Makefile @@ -188,6 +188,7 @@ BPF_NOCORE_TAG = $(subst .,_,$(KERN_RELEASE)).$(subst .,_,$(VERSION)) # TARGETS := $(foreach var,$(shell echo {a..r}),kern/openssl_1_1_1$(var)) +TARGETS += $(foreach var,$(shell echo {0..6}),kern/openssl_3_0_$(var)) TARGETS += kern/boringssl_1_1_1 TARGETS += kern/bash TARGETS += kern/gnutls diff --git a/kern/openssl_3_0_0_kern.c b/kern/openssl_3_0_0_kern.c new file mode 100644 index 000000000..7877c2951 --- /dev/null +++ b/kern/openssl_3_0_0_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_0_KERN_H +#define ECAPTURE_OPENSSL_3_0_0_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.0 7 sep 2021, OPENSSL_VERSION_NUMBER: 805306368 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/kern/openssl_3_0_1_kern.c b/kern/openssl_3_0_1_kern.c new file mode 100644 index 000000000..a5ab92f06 --- /dev/null +++ b/kern/openssl_3_0_1_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_1_KERN_H +#define ECAPTURE_OPENSSL_3_0_1_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.1 14 Dec 2021, OPENSSL_VERSION_NUMBER: 805306384 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/kern/openssl_3_0_2_kern.c b/kern/openssl_3_0_2_kern.c new file mode 100644 index 000000000..76d8c2df9 --- /dev/null +++ b/kern/openssl_3_0_2_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_2_KERN_H +#define ECAPTURE_OPENSSL_3_0_2_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.2 15 Mar 2022, OPENSSL_VERSION_NUMBER: 805306400 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/kern/openssl_3_0_3_kern.c b/kern/openssl_3_0_3_kern.c new file mode 100644 index 000000000..be24cbde4 --- /dev/null +++ b/kern/openssl_3_0_3_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_3_KERN_H +#define ECAPTURE_OPENSSL_3_0_3_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.3 3 May 2022, OPENSSL_VERSION_NUMBER: 805306416 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/kern/openssl_3_0_4_kern.c b/kern/openssl_3_0_4_kern.c new file mode 100644 index 000000000..b9aab6c9f --- /dev/null +++ b/kern/openssl_3_0_4_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_4_KERN_H +#define ECAPTURE_OPENSSL_3_0_4_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.4 21 Jun 2022, OPENSSL_VERSION_NUMBER: 805306432 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/kern/openssl_3_0_5_kern.c b/kern/openssl_3_0_5_kern.c new file mode 100644 index 000000000..74c50395b --- /dev/null +++ b/kern/openssl_3_0_5_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_5_KERN_H +#define ECAPTURE_OPENSSL_3_0_5_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.5 5 Jul 2022, OPENSSL_VERSION_NUMBER: 805306448 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/kern/openssl_3_0_6_kern.c b/kern/openssl_3_0_6_kern.c new file mode 100644 index 000000000..2e14812b6 --- /dev/null +++ b/kern/openssl_3_0_6_kern.c @@ -0,0 +1,49 @@ +#ifndef ECAPTURE_OPENSSL_3_0_6_KERN_H +#define ECAPTURE_OPENSSL_3_0_6_KERN_H + +/* OPENSSL_VERSION_TEXT: OpenSSL 3.0.6 11 Oct 2022, OPENSSL_VERSION_NUMBER: 805306464 */ + +// ssl_st->version +#define SSL_ST_VERSION 0x0 + +// ssl_st->session +#define SSL_ST_SESSION 0x918 + +// ssl_st->s3 +#define SSL_ST_S3 0xa8 + +// ssl_session_st->master_key +#define SSL_SESSION_ST_MASTER_KEY 0x50 + +// ssl_st->s3.client_random +#define SSL_ST_S3_CLIENT_RANDOM 0x160 + +// ssl_session_st->cipher +#define SSL_SESSION_ST_CIPHER 0x2f8 + +// ssl_session_st->cipher_id +#define SSL_SESSION_ST_CIPHER_ID 0x300 + +// ssl_cipher_st->id +#define SSL_CIPHER_ST_ID 0x18 + +// ssl_st->handshake_secret +#define SSL_ST_HANDSHAKE_SECRET 0x584 + +// ssl_st->master_secret +#define SSL_ST_MASTER_SECRET 0x5c4 + +// ssl_st->server_finished_hash +#define SSL_ST_SERVER_FINISHED_HASH 0x6c4 + +// ssl_st->handshake_traffic_hash +#define SSL_ST_HANDSHAKE_TRAFFIC_HASH 0x704 + +// ssl_st->exporter_master_secret +#define SSL_ST_EXPORTER_MASTER_SECRET 0x7c4 + +#include "openssl.h" +#include "openssl_masterkey_3.0.h" + +#endif + diff --git a/user/module/const.go b/user/module/const.go index 1119e52ae..5c74f75e6 100644 --- a/user/module/const.go +++ b/user/module/const.go @@ -20,7 +20,3 @@ const ( const ( BASH_ERRNO_DEFAULT int = 128 ) - -const ( - MaxSupportedOpenSSL111Version = 'r' -) diff --git a/user/module/probe_openssl.go b/user/module/probe_openssl.go index fc96fbd5d..a5f843754 100644 --- a/user/module/probe_openssl.go +++ b/user/module/probe_openssl.go @@ -167,6 +167,9 @@ func (this *MOpenSSLProbe) start() error { this.logger.Printf("%s\tUPROBE MODEL\n", this.Name()) err = this.setupManagersUprobe() } + if err != nil { + return err + } // fetch ebpf assets // user/bytecode/openssl_kern.o diff --git a/user/module/probe_openssl_lib.go b/user/module/probe_openssl_lib.go index f3ab1bf60..83c721b73 100644 --- a/user/module/probe_openssl_lib.go +++ b/user/module/probe_openssl_lib.go @@ -10,6 +10,11 @@ import ( "strings" ) +const ( + MaxSupportedOpenSSL111Version = 'r' + MaxSupportedOpenSSL30Version = '6' +) + // initOpensslOffset initial BpfMap func (this *MOpenSSLProbe) initOpensslOffset() { this.sslVersionBpfMap = map[string]string{ @@ -27,6 +32,10 @@ func (this *MOpenSSLProbe) initOpensslOffset() { for ch := 'a'; ch <= MaxSupportedOpenSSL111Version; ch++ { this.sslVersionBpfMap["OpenSSL 1.1.1"+string(ch)] = "openssl_1_1_1" + string(ch) + "_kern.o" } + + for ch := '0'; ch <= MaxSupportedOpenSSL30Version; ch++ { + this.sslVersionBpfMap["OpenSSL 3.0."+string(ch)] = "openssl_3_0_" + string(ch) + "_kern.o" + } } func (this *MOpenSSLProbe) detectOpenssl(soPath string) error { @@ -89,7 +98,7 @@ func (this *MOpenSSLProbe) detectOpenssl(soPath string) error { } // e.g : OpenSSL 1.1.1j 16 Feb 2021 - rex, err := regexp.Compile(`(OpenSSL\s1\.1\.1[a-z]+)`) + rex, err := regexp.Compile(`(OpenSSL\s\d\.\d\.[0-9a-z]+)`) if err != nil { return nil } From 37a043a8981ec2896d370f6d4e55b79874d2520c Mon Sep 17 00:00:00 2001 From: CFC4N Date: Thu, 20 Oct 2022 22:05:00 +0800 Subject: [PATCH 3/4] make format Signed-off-by: CFC4N --- Makefile | 4 +++- kern/boringssl_masterkey.h | 3 ++- kern/common.h | 1 - kern/openssl_masterkey.h | 3 ++- kern/openssl_masterkey_3.0.h | 9 ++++++--- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 2ea8a6936..f52b0b000 100644 --- a/Makefile +++ b/Makefile @@ -369,7 +369,9 @@ format: @echo " -> Formatting code" @clang-format -i -style=$(STYLE) kern/*.c @clang-format -i -style=$(STYLE) kern/common.h - @clang-format -i -style=$(STYLE) kern/masterkey_kern.h + @clang-format -i -style=$(STYLE) kern/openssl_masterkey.h + @clang-format -i -style=$(STYLE) kern/openssl_masterkey_3.0.h + @clang-format -i -style=$(STYLE) kern/boringssl_masterkey.h @clang-format -i -style=$(STYLE) kern/openssl_tc.h autogen: .checkver_$(CMD_BPFTOOL) diff --git a/kern/boringssl_masterkey.h b/kern/boringssl_masterkey.h index 6fa7b03af..386aa3a50 100644 --- a/kern/boringssl_masterkey.h +++ b/kern/boringssl_masterkey.h @@ -281,7 +281,8 @@ int probe_ssl_master_key(struct pt_regs *ctx) { ///////////////////////// get TLS 1.2 master secret //////////////////// if (mastersecret->version != TLS1_3_VERSION) { - void *ms_ptr = (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); + void *ms_ptr = + (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); ret = bpf_probe_read_user(&mastersecret->master_key, sizeof(mastersecret->master_key), ms_ptr); if (ret) { diff --git a/kern/common.h b/kern/common.h index 68acf3b71..605fa1da5 100644 --- a/kern/common.h +++ b/kern/common.h @@ -31,7 +31,6 @@ #define ETH_P_IP 0x0800 /* Internet Protocol packet */ #define SKB_MAX_DATA_SIZE 2048 - // .rodata section bug via : https://github.com/ehids/ecapture/issues/39 #ifndef KERNEL_LESS_5_2 // alawyse, we used it in openssl_tc.h diff --git a/kern/openssl_masterkey.h b/kern/openssl_masterkey.h index 90c7634ed..a659b7138 100644 --- a/kern/openssl_masterkey.h +++ b/kern/openssl_masterkey.h @@ -158,7 +158,8 @@ int probe_ssl_master_key(struct pt_regs *ctx) { ///////////////////////// get TLS 1.2 master secret //////////////////// if (mastersecret->version != TLS1_3_VERSION) { - void *ms_ptr = (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); + void *ms_ptr = + (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); ret = bpf_probe_read_user(&mastersecret->master_key, sizeof(mastersecret->master_key), ms_ptr); if (ret) { diff --git a/kern/openssl_masterkey_3.0.h b/kern/openssl_masterkey_3.0.h index f98e8f88e..6bb168856 100644 --- a/kern/openssl_masterkey_3.0.h +++ b/kern/openssl_masterkey_3.0.h @@ -104,10 +104,12 @@ int probe_ssl_master_key(struct pt_regs *ctx) { u64 *ssl_client_random_ptr = (u64 *)(ssl_st_ptr + SSL_ST_S3_CLIENT_RANDOM); // get SSL_ST_S3_CLIENT_RANDOM unsigned char client_random[SSL3_RANDOM_SIZE]; - ret = bpf_probe_read_user(&client_random, sizeof(client_random), (void *)ssl_client_random_ptr); + ret = bpf_probe_read_user(&client_random, sizeof(client_random), + (void *)ssl_client_random_ptr); if (ret) { debug_bpf_printk( -"bpf_probe_read ssl3_ssl_client_random_ptr_st failed, ret :%d\n", ret); + "bpf_probe_read ssl3_ssl_client_random_ptr_st failed, ret :%d\n", + ret); return 0; } debug_bpf_printk("client_random: %x %x %x\n", client_random[0], @@ -138,7 +140,8 @@ int probe_ssl_master_key(struct pt_regs *ctx) { ///////////////////////// get TLS 1.2 master secret //////////////////// if (mastersecret->version != TLS1_3_VERSION) { - void *ms_ptr = (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); + void *ms_ptr = + (void *)(ssl_session_st_addr + SSL_SESSION_ST_MASTER_KEY); ret = bpf_probe_read_user(&mastersecret->master_key, sizeof(mastersecret->master_key), ms_ptr); if (ret) { From 5d087b07fd52cac38b71e03559f46671769bd706 Mon Sep 17 00:00:00 2001 From: CFC4N Date: Fri, 21 Oct 2022 21:15:49 +0800 Subject: [PATCH 4/4] user/module: set default bpf bytecode file for openssl 3.0 Signed-off-by: CFC4N --- user/module/probe_openssl.go | 14 ++++---------- user/module/probe_openssl_lib.go | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/user/module/probe_openssl.go b/user/module/probe_openssl.go index a5f843754..63f5b6205 100644 --- a/user/module/probe_openssl.go +++ b/user/module/probe_openssl.go @@ -23,9 +23,10 @@ import ( ) const ( - ConnNotFound = "[ADDR_NOT_FOUND]" - LinuxDefauleFilename = "linux_default" - AndroidDefauleFilename = "android_default" + ConnNotFound = "[ADDR_NOT_FOUND]" + LinuxDefauleFilename_1_1_1 = "linux_default_1_1_1" + LinuxDefauleFilename_3_0 = "linux_default_3_0" + AndroidDefauleFilename = "android_default" ) type Tls13MasterSecret struct { @@ -67,7 +68,6 @@ type MOpenSSLProbe struct { masterKeyBuffer *bytes.Buffer tcPacketLocker *sync.Mutex - bpfFileKey string sslVersionBpfMap map[string]string // bpf map key: ssl version, value: bpf map key sslBpfFile string // ssl bpf file } @@ -120,12 +120,6 @@ func (this *MOpenSSLProbe) Init(ctx context.Context, logger *log.Logger, conf co this.tcPacketLocker = &sync.Mutex{} this.masterKeyBuffer = bytes.NewBuffer([]byte{}) - var isAndroid = this.conf.(*config.OpensslConfig).IsAndroid - if isAndroid { - this.bpfFileKey = AndroidDefauleFilename - } else { - this.bpfFileKey = LinuxDefauleFilename - } this.initOpensslOffset() return nil } diff --git a/user/module/probe_openssl_lib.go b/user/module/probe_openssl_lib.go index 83c721b73..a96aec577 100644 --- a/user/module/probe_openssl_lib.go +++ b/user/module/probe_openssl_lib.go @@ -5,6 +5,7 @@ import ( "debug/elf" "ecapture/user/config" "errors" + "fmt" "os" "regexp" "strings" @@ -20,9 +21,10 @@ func (this *MOpenSSLProbe) initOpensslOffset() { this.sslVersionBpfMap = map[string]string{ // openssl 1.1.1* - LinuxDefauleFilename: "openssl_1_1_1" + string(MaxSupportedOpenSSL111Version) + "_kern.o", + LinuxDefauleFilename_1_1_1: "openssl_1_1_1" + string(MaxSupportedOpenSSL111Version) + "_kern.o", // openssl 3.0.* + LinuxDefauleFilename_3_0: "openssl_3_0_" + string(MaxSupportedOpenSSL30Version) + "_kern.o", // boringssl "BoringSSL 1.1.1": "boringssl_1_1_1_kern.o", @@ -48,6 +50,13 @@ func (this *MOpenSSLProbe) detectOpenssl(soPath string) error { return errors.New("failed to parse the ELF file succesfully") } + switch r.FileHeader.Machine { + case elf.EM_X86_64: + case elf.EM_AARCH64: + default: + return fmt.Errorf("unsupported arch library ,ELF Header Machine is :%s", r.FileHeader.Machine.String()) + } + s := r.Section(".rodata") if s == nil { // not found @@ -134,8 +143,13 @@ func (this *MOpenSSLProbe) detectOpenssl(soPath string) error { bpfFile, _ = this.sslVersionBpfMap[AndroidDefauleFilename] this.logger.Printf("%s\tOpenSSL/BoringSSL version not found, used default version :%s\n", this.Name(), AndroidDefauleFilename) } else { - bpfFile, _ = this.sslVersionBpfMap[LinuxDefauleFilename] - this.logger.Printf("%s\tOpenSSL/BoringSSL version not found from shared library file, used default version:%s\n", this.Name(), LinuxDefauleFilename) + if strings.Contains(soPath, "libssl.so.3") { + bpfFile, _ = this.sslVersionBpfMap[LinuxDefauleFilename_3_0] + this.logger.Printf("%s\tOpenSSL/BoringSSL version not found from shared library file, used default version:%s\n", this.Name(), LinuxDefauleFilename_3_0) + } else { + bpfFile, _ = this.sslVersionBpfMap[LinuxDefauleFilename_1_1_1] + this.logger.Printf("%s\tOpenSSL/BoringSSL version not found from shared library file, used default version:%s\n", this.Name(), LinuxDefauleFilename_1_1_1) + } } this.sslBpfFile = bpfFile return nil