you know what? this sort of thing makes me laugh. hmm, what functions
authorLuke Leighton <lkcl@samba.org>
Sun, 21 Nov 1999 19:24:01 +0000 (19:24 +0000)
committerLuke Leighton <lkcl@samba.org>
Sun, 21 Nov 1999 19:24:01 +0000 (19:24 +0000)
have we got.  and what data do we have.  hmm.. i wonder what the NTLMv2
user session key can be... hmmm... weell.... there's some hidden data
here, generated from the user password that doesn't go over-the-wire,
so that's _got_ to be involved.  and... that bit of data took a lot of
computation to produce, so it's probably _also_ involved... and md4 no, md5?
no, how about hmac_md5 yes let's try that one (the other's didn't work)
oh goodie, it worked!

i love it when this sort of thing happens.  took all of fifteen minutes to
guess it.  tried concatenating client and server challenges.  tried
concatenating _random_ bits of client and server challenges.  tried
md5 of the above.  tried hmac_md5 of the above.  eventually, it boils down
to this:

kr = MD4(NT#,username,domainname)
hmacntchal=hmac_md5(kr, nt server challenge)
sess_key = hmac_md5(kr, hmacntchal);

source/include/client.h
source/include/proto.h
source/libsmb/clientgen.c
source/libsmb/pwd_cache.c
source/libsmb/smbencrypt.c
source/rpc_client/cli_pipe.c
source/rpcclient/cmd_samr.c

index b06d87718154477b60ff4a927a8870328bcb2b68..7c5854b55694063ed330639005643e78a859d2a7 100644 (file)
@@ -74,6 +74,8 @@ struct pwd_info
        uchar lm_cli_chal[8];
        uchar nt_cli_chal[128];
        size_t nt_cli_chal_len;
+
+       uchar sess_key[16];
 };
 
 struct cli_state {
index a5348d4e880c4c7c871bae4779284e61387806d3..ac5022935a47920478c1feec449ce9e511ebb601 100644 (file)
@@ -821,7 +821,8 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
                const char *user, const char *server, const char *domain);
 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]);
 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
-                               uchar *nt_owf, size_t *nt_owf_len);
+                               uchar *nt_owf, size_t *nt_owf_len,
+                               uchar *sess_key);
 
 /*The following definitions come from  libsmb/smbdes.c  */
 
index b15365459179d1c688dbbb91a45b0409f7240876..26a5f25c7d2ad6123a709a75108be3badf0f4739 100644 (file)
@@ -1026,8 +1026,13 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli,
                        *ntpasslen = cli->nt_cli_chal_len + 16;
 
                        hmac_md5_init_limK_to_64(kr, 16, &ctx);
-                       hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, &ctx);
+                       hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len,
+                                       &ctx);
                        hmac_md5_final(cli->sess_key, &ctx);
+#if DEBUG_PASSWORD
+                       DEBUG(100,("session key:\n"));
+                       dump_data(100, cli->sess_key, sizeof(cli->sess_key));
+#endif
 
                }
                else
@@ -3262,7 +3267,7 @@ BOOL cli_establish_connection(struct cli_state *cli,
                }
 
                pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd,
-                                 &nt_sess_pwd_len);
+                                 &nt_sess_pwd_len, cli->sess_key);
 
                /* attempt encrypted session */
                if (!cli_session_setup_x(cli, cli->user_name,
index c8b0e6a4427473cc23dad9906817ad6c3a364dab..c404ccb83f3edf3ce321ba0db004c02d5afaefc3 100644 (file)
@@ -34,6 +34,7 @@ void pwd_init(struct pwd_info *pwd)
        bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
        bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
        bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
+       bzero(pwd->sess_key  , sizeof(pwd->sess_key  ));
        pwd->nt_owf_len = 0;
 
        pwd->null_pwd  = True; /* safest option... */
@@ -202,6 +203,8 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
                const char *user, const char *server, const char *domain)
 {
        uchar kr[16];
+       struct MD5Context ctx5;
+       HMACMD5Context ctx;
 
        DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
                user, server, domain));
@@ -230,6 +233,18 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
        memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
        pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
 
+       hmac_md5_init_limK_to_64(kr, 16, &ctx);
+       hmac_md5_update(pwd->smb_nt_owf, 16, &ctx);
+       hmac_md5_final(pwd->sess_key, &ctx);
+#if 0
+        MD5Init(&ctx5);
+        MD5Update(&ctx5, pwd->smb_nt_owf, 16);  
+        MD5Final(pwd->sess_key, &ctx5);          
+#endif
+
+#if DEBUG_PASSWORD
+#endif
+
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("server cryptkey: "));
        dump_data(100, srv_key, 8);
@@ -249,6 +264,9 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
        dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
        DEBUG(100,("lm_sess_pwd: "));
        dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+
+       DEBUG(100,("session key:\n"));
+       dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
 #endif
        pwd->crypted = True;
 
@@ -270,6 +288,11 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
        }
        pwd_deobfuscate(pwd);
 
+       /* generate session key */
+       mdfour(pwd->sess_key, pwd->smb_nt_pwd, 16);
+
+       /* generate 24-byte hashes */
+
        SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
        SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
        pwd->nt_owf_len = 24;
@@ -287,6 +310,9 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
        dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
        DEBUG(100,("lm_sess_pwd: "));
        dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+
+       DEBUG(100,("session key:\n"));
+       dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
 #endif
 
        pwd->crypted = True;
@@ -298,7 +324,8 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
  gets lm and nt crypts
  ****************************************************************************/
 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
-                               uchar *nt_owf, size_t *nt_owf_len)
+                               uchar *nt_owf, size_t *nt_owf_len,
+                               uchar *sess_key)
 {
        if (pwd->null_pwd)
        {
@@ -321,6 +348,10 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
        {
                memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
        }
+       if (sess_key != NULL)
+       {
+               memcpy(sess_key, pwd->sess_key, 16);
+       }
        if (nt_owf_len != NULL)
        {
                *nt_owf_len = pwd->nt_owf_len;
index 659dba6562588f02ac75231fdb82cb0d373533d6..6bc0e71f6f4cd5ff17a7de337ceb1257310bb704 100644 (file)
@@ -479,7 +479,7 @@ void create_ntlmssp_resp(struct pwd_info *pwd,
        unsigned char nt_owf[128];
        size_t nt_owf_len;
 
-       pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len);
+       pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len, NULL);
                        
        make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
                                 lm_owf, nt_owf, nt_owf_len,
index df09f023983622b2805a6a2f1fa4a4376e44d5ab..71670c0d842fde511cc3dc7b9de5cf50fbcda8a7 100644 (file)
@@ -973,7 +973,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum,
                                             rpc_call_id,
                                             &hdra, &hdr_autha, &auth_resp);
                                            
-                       pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL, NULL);
+                       pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL, NULL, NULL);
                        pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
                        NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
                        {
index 542c0ffe4156d79be641da3c459d0ff897e016aa..0f0a19f2d1b4dd2f5f5350dc5edc2a023c574123 100644 (file)
@@ -1891,6 +1891,9 @@ void cmd_sam_set_userinfo(struct client_info *info)
                {
                        encode_pw_buffer(pwbuf, password,
                                       strlen(password), True);
+#ifdef DEBUG_PASSWORD
+                       dump_data(100, smb_cli->sess_key, 16);
+#endif
                        SamOEMhash(pwbuf, smb_cli->sess_key, 1);
                }