From 85123e4ad02b8e1c085beea43574417b9cc761d6 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 19 Jul 2025 14:54:10 +0200 Subject: [PATCH] libcli/smb2: dump encryption key in format for Wireshark ~/.wireshark/smb2_seskey_list This allows dumping the keys and quickly feeding them into Wireshark by adding them to ~/.wireshark/smb2_seskey_list. Example: debug encryption: dumping generated session keys Session Id [0000] 7D 00 00 E8 57 E0 31 01 }...W.1. Session Key [0000] 71 54 77 50 C1 DD 66 68 A8 51 D8 DE 23 F4 91 01 qTwP..fh .Q..#... Signing Key [0000] B1 29 AC EF 41 30 AE D2 43 00 1F 67 87 29 BF DB .)..A0.. C..g.).. App Key [0000] 6A 88 5C 51 51 22 FF 5C 25 95 A2 5C E2 2C FC 5D j.\QQ".\ %..\.,.] ServerIn Key [0000] 20 08 EB A2 14 99 17 03 9C A5 9A BB B8 48 88 3C ....... .....H.< ServerOut Key [0000] 15 AA C2 0D 19 AB 4C 26 64 E8 FC 94 B1 FE 27 5A ......L& d.....'Z Wireshark configuration line 7d0000e857e03101,71547750c1dd6668a851d8de23f49101,15aac20d19ab4c2664e8fc94b1fe275a,2008eba2149917039ca59abbb848883c When setting debug encryption = yes debug encryption:wireshark keyfile = /home/slow/.wireshark/smb2_seskey_list the keys are appended directly to Wireshark's keyfile. Wireshark has to be restarted to pick them up. Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke --- libcli/smb/smbXcli_base.c | 46 ++++++++++++++++++++++++++++++++++- libcli/smb/smbXcli_base.h | 3 ++- source3/libsmb/cliconnect.c | 8 +++++- source4/libcli/smb2/session.c | 9 ++++--- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index dd1fdb38a5f..4c6c61bf862 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -7606,8 +7606,16 @@ void smbXcli_session_dump_keys(uint64_t session_id, DATA_BLOB *signing_key, DATA_BLOB *application_key, DATA_BLOB *encryption_key, - DATA_BLOB *decryption_key) + DATA_BLOB *decryption_key, + const char *wireshark_keyfile) { + DATA_BLOB sidb = { + .data = (uint8_t *)&session_id, .length = sizeof(session_id) + }; + char *line = NULL; + int fd = -1; + ssize_t written; + DEBUG(0, ("debug encryption: dumping generated session keys\n")); DEBUGADD(0, ("Session Id ")); dump_data(0, (uint8_t*)&session_id, sizeof(session_id)); @@ -7625,4 +7633,40 @@ void smbXcli_session_dump_keys(uint64_t session_id, dump_data(0, encryption_key->data, encryption_key->length); DEBUGADD(0, ("ServerOut Key ")); dump_data(0, decryption_key->data, decryption_key->length); + + DEBUGADD(0, ("Wireshark configuration line:\n")); + line = talloc_asprintf( + talloc_tos(), + "%s,%s,%s,%s\n", + data_blob_hex_string_lower(talloc_tos(), &sidb), + data_blob_hex_string_lower(talloc_tos(), session_key), + data_blob_hex_string_lower(talloc_tos(), decryption_key), + data_blob_hex_string_lower(talloc_tos(), encryption_key)); + if (line == NULL) { + return; + } + DEBUGADD(0, ("%s", line)); + + if (wireshark_keyfile == NULL) { + goto done; + } + fd = open(wireshark_keyfile, O_WRONLY | O_APPEND); + if (fd == -1) { + DBG_ERR("Failed to open '%s': %s\n", + wireshark_keyfile, strerror(errno)); + goto done; + } + + written = write(fd, line, strlen(line)); + if (written != strlen(line)) { + DBG_ERR("Failed to write '%s' to '%s', only wrote: %zd\n", + line, wireshark_keyfile, written); + goto done; + } + +done: + TALLOC_FREE(line); + if (fd != -1) { + close(fd); + } } diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index f6e1332822f..0e6bc468a18 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -536,7 +536,8 @@ void smbXcli_session_dump_keys(uint64_t session_id, DATA_BLOB *signing_key, DATA_BLOB *application_key, DATA_BLOB *encryption_key, - DATA_BLOB *decryption_key); + DATA_BLOB *decryption_key, + const char *wireshark_keyfile); NTSTATUS smb2cli_session_signing_key(struct smbXcli_session *session, TALLOC_CTX *mem_ctx, DATA_BLOB *key); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 13ee5bb905a..116f746d37e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1064,6 +1064,11 @@ static void cli_session_setup_gensec_ready(struct tevent_req *req) && lp_debug_encryption()) { DATA_BLOB sig, app, enc, dec; + const char *wireshark_keyfile = lp_parm_const_string( + GLOBAL_SECTION_SNUM, + "debug encryption", + "wireshark keyfile", + NULL); status = smb2cli_session_signing_key(session, state, &sig); if (tevent_req_nterror(req, status)) { @@ -1088,7 +1093,8 @@ static void cli_session_setup_gensec_ready(struct tevent_req *req) &sig, &app, &enc, - &dec); + &dec, + wireshark_keyfile); } } else { struct smbXcli_session *session = state->cli->smb1.session; diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 5038aeb4d91..2e9d32a98e5 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -433,9 +433,9 @@ static void smb2_session_setup_spnego_both_ready(struct tevent_req *req) if (tevent_req_nterror(req, status)) { return; } - if ((smbXcli_conn_protocol(session->transport->conn) - >= PROTOCOL_SMB3_00) && - session->debug_encryption) + if ((smbXcli_conn_protocol(session->transport->conn) >= + PROTOCOL_SMB3_00) + && session->debug_encryption) { DATA_BLOB sig, app, enc, dec; @@ -468,7 +468,8 @@ static void smb2_session_setup_spnego_both_ready(struct tevent_req *req) &sig, &app, &enc, - &dec); + &dec, + session->wireshark_keyfile); } } tevent_req_done(req); -- 2.47.2