libsmb,s3/smbd: dump SMB3+ session keys if debug parm is set
authorAurelien Aptel <aaptel@suse.com>
Fri, 8 Feb 2019 11:13:25 +0000 (12:13 +0100)
committerDavid Disseldorp <ddiss@samba.org>
Sat, 9 Feb 2019 20:43:25 +0000 (21:43 +0100)
Use of previously added smb.conf global param.

Sample usage:

$ smbclient //localhost/scratch --option='debugencryption=yes' \
                                 -e -mSMB3 -U aaptel%aaptel -c quit
debug encryption: dumping generated session keys
Session Id    [0000] 26 48 BF FD 00 00 00 00                             &H......
Session Key   [0000] 63 D6 CA BC 08 C8 4A D2   45 F6 AE 35 AB 4A B3 3B   c.....J. E..5.J.;
Signing Key   [0000] 4E FE 35 92 AC 13 14 FC   C9 17 62 B1 82 20 A4 12   N.5..... ..b.. ..
App Key       [0000] A5 0F F4 8B 2F FB 0D FF   F2 BF EE 39 E6 6D F5 0A   ..../... ...9.m..
ServerIn Key  [0000] 2A 02 7E E1 D3 58 D8 12   4C 63 76 AE 59 17 5A E4   *.~..X.. Lcv.Y.Z.
ServerOut Key [0000] 59 F2 5B 7F 66 8F 31 A0   A5 E4 A8 D8 2F BA 00 38   Y.[.f.1. ..../..8

We can now simply pass -ouat:smb2_seskey_list:<sesid>,<seskey> to
wireshark or tshark:

$ tshark -ouat:smb2_seskey_list:2648BFFD00000000,63D6CABC08C84AD245F6AE35AB4AB33B \
          -Y smb2 -r capture.pcap -Tfields -e _ws.col.Info
Negotiate Protocol Response
Negotiate Protocol Request
Negotiate Protocol Response
Session Setup Request, NTLMSSP_NEGOTIATE
Session Setup Response, Error: STATUS_MORE_PROCESSING_REQUIRED, NTLMSSP_CHALLENGE
Session Setup Request, NTLMSSP_AUTH, User: WORKGROUP\aaptel
Session Setup Response
Tree Connect Request Tree: \\localhost\IPC$
Tree Connect Response
Decrypted SMB3;Ioctl Request FSCTL_DFS_GET_REFERRALS, File: \localhost\scratch
Decrypted SMB3;Ioctl Response, Error: STATUS_NOT_FOUND
Decrypted SMB3;Tree Disconnect Request
Decrypted SMB3;Tree Disconnect Response
Decrypted SMB3;Tree Connect Request Tree: \\localhost\scratch
Decrypted SMB3;Tree Connect Response
Decrypted SMB3;Tree Disconnect Request
Decrypted SMB3;Tree Disconnect Response

For more info on Wireshark decryption support see
https://wiki.samba.org/index.php/Wireshark_Decryption

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Reviewed-by: Noel Power <npower@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Autobuild-User(master): David Disseldorp <ddiss@samba.org>
Autobuild-Date(master): Sat Feb  9 21:43:25 CET 2019 on sn-devel-144

source3/libsmb/cliconnect.c
source3/smbd/smb2_sesssetup.c

index 0a54d47227a6222bd353a69918927e4c120701de..fcc8e0b67b8a0475ed51b43657e14e42cb543e51 100644 (file)
@@ -1132,6 +1132,58 @@ static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
        cli_session_setup_gensec_local_next(req);
 }
 
+static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
+                                 struct smbXcli_session *session,
+                                 DATA_BLOB session_key)
+{
+       NTSTATUS status;
+       DATA_BLOB sig = data_blob_null;
+       DATA_BLOB app = data_blob_null;
+       DATA_BLOB enc = data_blob_null;
+       DATA_BLOB dec = data_blob_null;
+       uint64_t sid = smb2cli_session_current_id(session);
+
+       status = smb2cli_session_signing_key(session, mem_ctx, &sig);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       status = smbXcli_session_application_key(session, mem_ctx, &app);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       DEBUG(0, ("debug encryption: dumping generated session keys\n"));
+       DEBUGADD(0, ("Session Id    "));
+       dump_data(0, (uint8_t*)&sid, sizeof(sid));
+       DEBUGADD(0, ("Session Key   "));
+       dump_data(0, session_key.data, session_key.length);
+       DEBUGADD(0, ("Signing Key   "));
+       dump_data(0, sig.data, sig.length);
+       DEBUGADD(0, ("App Key       "));
+       dump_data(0, app.data, app.length);
+
+       /* In client code, ServerIn is the encryption key */
+
+       DEBUGADD(0, ("ServerIn Key  "));
+       dump_data(0, enc.data, enc.length);
+       DEBUGADD(0, ("ServerOut Key "));
+       dump_data(0, dec.data, dec.length);
+
+out:
+       data_blob_clear_free(&sig);
+       data_blob_clear_free(&app);
+       data_blob_clear_free(&enc);
+       data_blob_clear_free(&dec);
+}
+
 static void cli_session_setup_gensec_ready(struct tevent_req *req)
 {
        struct cli_session_setup_gensec_state *state =
@@ -1199,6 +1251,11 @@ static void cli_session_setup_gensec_ready(struct tevent_req *req)
                if (tevent_req_nterror(req, status)) {
                        return;
                }
+               if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
+                   && lp_debug_encryption())
+               {
+                       cli_session_dump_keys(state, session, state->session_key);
+               }
        } else {
                struct smbXcli_session *session = state->cli->smb1.session;
                bool active;
index 2c24e7a1abcb66d823c2981cdabaefc0cd2b10b0..d34951a4eef32a563294ca22ac977b790ca40fdd 100644 (file)
@@ -407,6 +407,31 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
                                    d->context.data, d->context.length,
                                    x->global->application_key.data);
        }
+
+       if (xconn->protocol >= PROTOCOL_SMB3_00 && lp_debug_encryption()) {
+               DEBUG(0, ("debug encryption: dumping generated session keys\n"));
+               DEBUGADD(0, ("Session Id    "));
+               dump_data(0, (uint8_t*)&session->global->session_wire_id,
+                         sizeof(session->global->session_wire_id));
+               DEBUGADD(0, ("Session Key   "));
+               dump_data(0, session_key, sizeof(session_key));
+               DEBUGADD(0, ("Signing Key   "));
+               dump_data(0, x->global->signing_key.data,
+                         x->global->signing_key.length);
+               DEBUGADD(0, ("App Key       "));
+               dump_data(0, x->global->application_key.data,
+                         x->global->application_key.length);
+
+               /* In server code, ServerIn is the decryption key */
+
+               DEBUGADD(0, ("ServerIn Key  "));
+               dump_data(0, x->global->decryption_key.data,
+                         x->global->decryption_key.length);
+               DEBUGADD(0, ("ServerOut Key "));
+               dump_data(0, x->global->encryption_key.data,
+                         x->global->encryption_key.length);
+       }
+
        ZERO_STRUCT(session_key);
 
        x->global->channels[0].signing_key = data_blob_dup_talloc(x->global->channels,