From dab1a1227873f1a88dc7a4b8f63edcccd60ada85 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:24:01 +0000 Subject: you know what? this sort of thing makes me laugh. hmm, what functions 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); (This used to be commit ab174759cd210fe1be888d0c589a5b2669f7ff1e) --- source3/include/client.h | 2 ++ source3/include/proto.h | 3 ++- source3/libsmb/clientgen.c | 9 +++++++-- source3/libsmb/pwd_cache.c | 33 ++++++++++++++++++++++++++++++++- source3/libsmb/smbencrypt.c | 2 +- source3/rpc_client/cli_pipe.c | 2 +- source3/rpcclient/cmd_samr.c | 3 +++ 7 files changed, 48 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/include/client.h b/source3/include/client.h index b06d877181..7c5854b556 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -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 { diff --git a/source3/include/proto.h b/source3/include/proto.h index a5348d4e88..ac5022935a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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 */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b153654591..26a5f25c7d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -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, diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index c8b0e6a442..c404ccb83f 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -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; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 659dba6562..6bc0e71f6f 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -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, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index df09f02398..71670c0d84 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -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); { diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 542c0ffe41..0f0a19f2d1 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -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); } -- cgit