1From 202d69267c8550b850438877fb51c3d2c992949d Mon Sep 17 00:00:00 2001 2From: Stefan Metzmacher <metze@samba.org> 3Date: Tue, 1 Dec 2015 08:46:45 +0100 4Subject: [PATCH 01/10] CVE-2016-2110: s3:ntlmssp: set and use 5 ntlmssp_state->allow_lm_key 6MIME-Version: 1.0 7Content-Type: text/plain; charset=UTF-8 8Content-Transfer-Encoding: 8bit 9 10BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 11 12Signed-off-by: Stefan Metzmacher <metze@samba.org> 13Reviewed-by: G��nther Deschner <gd@samba.org> 14--- 15 source3/libsmb/ntlmssp.c | 4 +++- 16 1 file changed, 3 insertions(+), 1 deletion(-) 17 18--- a/source3/libsmb/ntlmssp.c 19+++ b/source3/libsmb/ntlmssp.c 20@@ -176,17 +176,19 @@ void ntlmssp_want_feature_list(struct nt 21 * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. 22 */ 23 if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) { 24- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 25+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; 26 } 27 if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) { 28- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 29+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; 30 } 31 if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) { 32- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 33+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; 34 } 35 if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) { 36 ntlmssp_state->use_ccache = true; 37 } 38+ 39+ ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; 40 } 41 42 /** 43@@ -199,17 +201,20 @@ void ntlmssp_want_feature(struct ntlmssp 44 { 45 /* As per JRA's comment above */ 46 if (feature & NTLMSSP_FEATURE_SESSION_KEY) { 47- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 48+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; 49 } 50 if (feature & NTLMSSP_FEATURE_SIGN) { 51- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 52+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; 53 } 54 if (feature & NTLMSSP_FEATURE_SEAL) { 55- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 56+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN; 57+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL; 58 } 59 if (feature & NTLMSSP_FEATURE_CCACHE) { 60 ntlmssp_state->use_ccache = true; 61 } 62+ 63+ ntlmssp_state->neg_flags |= ntlmssp_state->required_flags; 64 } 65 66 /** 67@@ -387,7 +392,12 @@ static NTSTATUS ntlmssp_client_initial(s 68 } 69 70 if (ntlmssp_state->use_ntlmv2) { 71- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; 72+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2; 73+ ntlmssp_state->allow_lm_key = false; 74+ } 75+ 76+ if (ntlmssp_state->allow_lm_key) { 77+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; 78 } 79 80 /* generate the ntlmssp negotiate packet */ 81@@ -422,6 +432,86 @@ static NTSTATUS ntlmssp_client_initial(s 82 return NT_STATUS_MORE_PROCESSING_REQUIRED; 83 } 84 85+static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, 86+ uint32_t flags) 87+{ 88+ uint32_t missing_flags = ntlmssp_state->required_flags; 89+ 90+ if (flags & NTLMSSP_NEGOTIATE_UNICODE) { 91+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; 92+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; 93+ ntlmssp_state->unicode = true; 94+ } else { 95+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; 96+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; 97+ ntlmssp_state->unicode = false; 98+ } 99+ 100+ /* 101+ * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) 102+ * has priority over NTLMSSP_NEGOTIATE_LM_KEY 103+ */ 104+ if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) { 105+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; 106+ } 107+ 108+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 109+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; 110+ } 111+ 112+ if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) { 113+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; 114+ } 115+ 116+ if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { 117+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 118+ } 119+ 120+ if (!(flags & NTLMSSP_NEGOTIATE_128)) { 121+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; 122+ } 123+ 124+ if (!(flags & NTLMSSP_NEGOTIATE_56)) { 125+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56; 126+ } 127+ 128+ if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { 129+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; 130+ } 131+ 132+ if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) { 133+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; 134+ } 135+ 136+ if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) { 137+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; 138+ } 139+ 140+ if ((flags & NTLMSSP_REQUEST_TARGET)) { 141+ ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; 142+ } 143+ 144+ missing_flags &= ~ntlmssp_state->neg_flags; 145+ if (missing_flags != 0) { 146+ NTSTATUS status = NT_STATUS_RPC_SEC_PKG_ERROR; 147+ DEBUG(1, ("%s: Got challenge flags[0x%08x] " 148+ "- possible downgrade detected! " 149+ "missing_flags[0x%08x] - %s\n", 150+ __func__, 151+ (unsigned)flags, 152+ (unsigned)missing_flags, 153+ nt_errstr(status))); 154+ debug_ntlmssp_flags(missing_flags); 155+ DEBUGADD(4, ("neg_flags[0x%08x]\n", 156+ (unsigned)ntlmssp_state->neg_flags)); 157+ debug_ntlmssp_flags(ntlmssp_state->neg_flags); 158+ 159+ return status; 160+ } 161+ 162+ return NT_STATUS_OK; 163+} 164+ 165 /** 166 * Next state function for the Challenge Packet. Generate an auth packet. 167 * 168@@ -448,6 +538,26 @@ static NTSTATUS ntlmssp_client_challenge 169 DATA_BLOB encrypted_session_key = data_blob_null; 170 NTSTATUS nt_status = NT_STATUS_OK; 171 172+ if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", 173+ "NTLMSSP", 174+ &ntlmssp_command, 175+ &server_domain_blob, 176+ &chal_flags)) { 177+ DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); 178+ dump_data(2, reply.data, reply.length); 179+ 180+ return NT_STATUS_INVALID_PARAMETER; 181+ } 182+ data_blob_free(&server_domain_blob); 183+ 184+ DEBUG(3, ("Got challenge flags:\n")); 185+ debug_ntlmssp_flags(chal_flags); 186+ 187+ nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags); 188+ if (!NT_STATUS_IS_OK(nt_status)) { 189+ return nt_status; 190+ } 191+ 192 if (ntlmssp_state->use_ccache) { 193 struct wbcCredentialCacheParams params; 194 struct wbcCredentialCacheInfo *info = NULL; 195@@ -498,17 +608,6 @@ static NTSTATUS ntlmssp_client_challenge 196 197 noccache: 198 199- if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", 200- "NTLMSSP", 201- &ntlmssp_command, 202- &server_domain_blob, 203- &chal_flags)) { 204- DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); 205- dump_data(2, reply.data, reply.length); 206- 207- return NT_STATUS_INVALID_PARAMETER; 208- } 209- 210 if (DEBUGLEVEL >= 10) { 211 struct CHALLENGE_MESSAGE *challenge = talloc( 212 talloc_tos(), struct CHALLENGE_MESSAGE); 213@@ -525,13 +624,6 @@ noccache: 214 } 215 } 216 217- data_blob_free(&server_domain_blob); 218- 219- DEBUG(3, ("Got challenge flags:\n")); 220- debug_ntlmssp_flags(chal_flags); 221- 222- ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); 223- 224 if (ntlmssp_state->unicode) { 225 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { 226 chal_parse_string = "CdUdbddB"; 227@@ -769,6 +861,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX 228 ntlmssp_state->unicode = True; 229 230 ntlmssp_state->use_ntlmv2 = use_ntlmv2; 231+ ntlmssp_state->allow_lm_key = lp_client_lanman_auth(); 232 233 ntlmssp_state->expected_state = NTLMSSP_INITIAL; 234 235@@ -780,6 +873,10 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX 236 NTLMSSP_NEGOTIATE_KEY_EXCH | 237 NTLMSSP_REQUEST_TARGET; 238 239+ if (ntlmssp_state->use_ntlmv2) { 240+ ntlmssp_state->allow_lm_key = false; 241+ } 242+ 243 ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name); 244 if (!ntlmssp_state->client.netbios_name) { 245 talloc_free(ntlmssp_state); 246--- a/libcli/auth/ntlmssp.h 247+++ b/libcli/auth/ntlmssp.h 248@@ -83,6 +83,7 @@ struct ntlmssp_state 249 DATA_BLOB nt_resp; 250 DATA_BLOB session_key; 251 252+ uint32_t required_flags; 253 uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ 254 255 /** 256