CVE-2016-2110: libcli/auth: pass server_timestamp to SMBNTLMv2encrypt_hash()
authorStefan Metzmacher <metze@samba.org>
Fri, 20 Nov 2015 08:31:35 +0000 (09:31 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 12 Apr 2016 17:25:23 +0000 (19:25 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
auth/credentials/credentials.h
auth/credentials/credentials_ntlm.c
libcli/auth/proto.h
libcli/auth/smbencrypt.c
source4/auth/ntlm/auth_util.c

index 78dd59d0158a1c777bed1e1bb349d16243573587..3779ec048e65a9b4b0c1143cd48e596b410a4e82 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef __CREDENTIALS_H__
 #define __CREDENTIALS_H__
 
+#include "../lib/util/time.h"
 #include "../lib/util/data_blob.h"
 #include "librpc/gen_ndr/misc.h"
 
index a69add02f5387dc033b9390f30560c5d745e51ff..0abbb5c020da878901167985f78133b1c3052b22 100644 (file)
@@ -104,7 +104,7 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred
                                           user, 
                                           domain, 
                                           nt_hash->hash, &challenge, 
-                                          &target_info, 
+                                          server_timestamp, &target_info,
                                           &lm_response, &nt_response, 
                                           NULL, &session_key)) {
                        return NT_STATUS_NO_MEMORY;
index c58a23f4e0a753e791f09150b021f2db67e894ad..acf39e152870ea2830a8a8f8d0894c554aa08f3a 100644 (file)
@@ -144,6 +144,7 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx,
 bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, 
                           const char *user, const char *domain, const uint8_t nt_hash[16],
                           const DATA_BLOB *server_chal, 
+                          const NTTIME *server_timestamp,
                           const DATA_BLOB *names_blob,
                           DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
                           DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ;
index e9eaadf48a7888275d1cf3e21ff4e2e4a5ea2450..7ad4654f2f7b793c18c378689f76e70a92919df6 100644 (file)
@@ -387,14 +387,13 @@ DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx,
        return names_blob;
 }
 
-static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob)
+static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx,
+                                            NTTIME nttime,
+                                            const DATA_BLOB *names_blob)
 {
        uint8_t client_chal[8];
        DATA_BLOB response = data_blob(NULL, 0);
        uint8_t long_date[8];
-       NTTIME nttime;
-
-       unix_to_nt_time(&nttime, time(NULL));
 
        generate_random_buffer(client_chal, sizeof(client_chal));
 
@@ -417,6 +416,7 @@ static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLO
 static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx,
                                          const uint8_t ntlm_v2_hash[16],
                                          const DATA_BLOB *server_chal,
+                                         NTTIME nttime,
                                          const DATA_BLOB *names_blob)
 {
        uint8_t ntlmv2_response[16];
@@ -433,7 +433,7 @@ static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx,
        /* NTLMv2 */
        /* generate some data to pass into the response function - including
           the hostname and domain name of the server */
-       ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob);
+       ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, nttime, names_blob);
 
        /* Given that data, and the challenge from the server, generate a response */
        SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);
@@ -479,6 +479,7 @@ static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx,
 bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
                           const char *user, const char *domain, const uint8_t nt_hash[16],
                           const DATA_BLOB *server_chal,
+                          const NTTIME *server_timestamp,
                           const DATA_BLOB *names_blob,
                           DATA_BLOB *lm_response, DATA_BLOB *nt_response,
                           DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key)
@@ -494,8 +495,19 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
        }
 
        if (nt_response) {
+               const NTTIME *nttime = server_timestamp;
+               NTTIME _now = 0;
+
+               if (nttime == NULL) {
+                       struct timeval tv_now = timeval_current();
+                       _now = timeval_to_nttime(&tv_now);
+                       nttime = &_now;
+               }
+
                *nt_response = NTLMv2_generate_response(mem_ctx,
-                                                       ntlm_v2_hash, server_chal,
+                                                       ntlm_v2_hash,
+                                                       server_chal,
+                                                       *nttime,
                                                        names_blob);
                if (user_session_key) {
                        *user_session_key = data_blob_talloc(mem_ctx, NULL, 16);
@@ -509,8 +521,13 @@ bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
        /* LMv2 */
 
        if (lm_response) {
-               *lm_response = LMv2_generate_response(mem_ctx,
-                                                     ntlm_v2_hash, server_chal);
+               if (server_timestamp != NULL) {
+                       *lm_response = data_blob_talloc_zero(mem_ctx, 24);
+               } else {
+                       *lm_response = LMv2_generate_response(mem_ctx,
+                                                             ntlm_v2_hash,
+                                                             server_chal);
+               }
                if (lm_session_key) {
                        *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
 
@@ -535,7 +552,8 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx,
        E_md4hash(password, nt_hash);
 
        return SMBNTLMv2encrypt_hash(mem_ctx,
-                                    user, domain, nt_hash, server_chal, names_blob,
+                                    user, domain, nt_hash,
+                                    server_chal, NULL, names_blob,
                                     lm_response, nt_response, lm_session_key, user_session_key);
 }
 
index 16977fa00a3b60f368bb3a2b2a4d61fa146c3964..3e5a0da59c2ebeab3f65d0792d9b4d8399b9074d 100644 (file)
@@ -350,7 +350,9 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_conte
                                if (!SMBNTLMv2encrypt_hash(user_info_temp,
                                                           user_info_in->client.account_name, 
                                                           user_info_in->client.domain_name, 
-                                                          user_info_in->password.hash.nt->hash, &chall_blob,
+                                                          user_info_in->password.hash.nt->hash,
+                                                          &chall_blob,
+                                                          NULL, /* server_timestamp */
                                                           &names_blob,
                                                           &lmv2_response, &ntlmv2_response, 
                                                           &lmv2_session_key, &ntlmv2_session_key)) {