123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- From 202d69267c8550b850438877fb51c3d2c992949d Mon Sep 17 00:00:00 2001
- From: Stefan Metzmacher <metze@samba.org>
- Date: Tue, 1 Dec 2015 08:46:45 +0100
- Subject: [PATCH 01/10] CVE-2016-2110: s3:ntlmssp: set and use
- ntlmssp_state->allow_lm_key
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- 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>
- ---
- source3/libsmb/ntlmssp.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
- --- a/source3/libsmb/ntlmssp.c
- +++ b/source3/libsmb/ntlmssp.c
- @@ -176,17 +176,19 @@ void ntlmssp_want_feature_list(struct nt
- * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
- */
- if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
- }
- if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
- }
- if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
- }
- if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
- ntlmssp_state->use_ccache = true;
- }
- +
- + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
- }
-
- /**
- @@ -199,17 +201,20 @@ void ntlmssp_want_feature(struct ntlmssp
- {
- /* As per JRA's comment above */
- if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
- }
- if (feature & NTLMSSP_FEATURE_SIGN) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
- }
- if (feature & NTLMSSP_FEATURE_SEAL) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
- }
- if (feature & NTLMSSP_FEATURE_CCACHE) {
- ntlmssp_state->use_ccache = true;
- }
- +
- + ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
- }
-
- /**
- @@ -387,7 +392,12 @@ static NTSTATUS ntlmssp_client_initial(s
- }
-
- if (ntlmssp_state->use_ntlmv2) {
- - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
- + ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
- + ntlmssp_state->allow_lm_key = false;
- + }
- +
- + if (ntlmssp_state->allow_lm_key) {
- + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
- }
-
- /* generate the ntlmssp negotiate packet */
- @@ -422,6 +432,86 @@ static NTSTATUS ntlmssp_client_initial(s
- return NT_STATUS_MORE_PROCESSING_REQUIRED;
- }
-
- +static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
- + uint32_t flags)
- +{
- + uint32_t missing_flags = ntlmssp_state->required_flags;
- +
- + if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
- + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
- + ntlmssp_state->unicode = true;
- + } else {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
- + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
- + ntlmssp_state->unicode = false;
- + }
- +
- + /*
- + * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
- + * has priority over NTLMSSP_NEGOTIATE_LM_KEY
- + */
- + if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
- + }
- +
- + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_128)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_56)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
- + }
- +
- + if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
- + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
- + }
- +
- + if ((flags & NTLMSSP_REQUEST_TARGET)) {
- + ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
- + }
- +
- + missing_flags &= ~ntlmssp_state->neg_flags;
- + if (missing_flags != 0) {
- + NTSTATUS status = NT_STATUS_RPC_SEC_PKG_ERROR;
- + DEBUG(1, ("%s: Got challenge flags[0x%08x] "
- + "- possible downgrade detected! "
- + "missing_flags[0x%08x] - %s\n",
- + __func__,
- + (unsigned)flags,
- + (unsigned)missing_flags,
- + nt_errstr(status)));
- + debug_ntlmssp_flags(missing_flags);
- + DEBUGADD(4, ("neg_flags[0x%08x]\n",
- + (unsigned)ntlmssp_state->neg_flags));
- + debug_ntlmssp_flags(ntlmssp_state->neg_flags);
- +
- + return status;
- + }
- +
- + return NT_STATUS_OK;
- +}
- +
- /**
- * Next state function for the Challenge Packet. Generate an auth packet.
- *
- @@ -448,6 +538,26 @@ static NTSTATUS ntlmssp_client_challenge
- DATA_BLOB encrypted_session_key = data_blob_null;
- NTSTATUS nt_status = NT_STATUS_OK;
-
- + if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
- + "NTLMSSP",
- + &ntlmssp_command,
- + &server_domain_blob,
- + &chal_flags)) {
- + DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
- + dump_data(2, reply.data, reply.length);
- +
- + return NT_STATUS_INVALID_PARAMETER;
- + }
- + data_blob_free(&server_domain_blob);
- +
- + DEBUG(3, ("Got challenge flags:\n"));
- + debug_ntlmssp_flags(chal_flags);
- +
- + nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
- + if (!NT_STATUS_IS_OK(nt_status)) {
- + return nt_status;
- + }
- +
- if (ntlmssp_state->use_ccache) {
- struct wbcCredentialCacheParams params;
- struct wbcCredentialCacheInfo *info = NULL;
- @@ -498,17 +608,6 @@ static NTSTATUS ntlmssp_client_challenge
-
- noccache:
-
- - if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
- - "NTLMSSP",
- - &ntlmssp_command,
- - &server_domain_blob,
- - &chal_flags)) {
- - DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
- - dump_data(2, reply.data, reply.length);
- -
- - return NT_STATUS_INVALID_PARAMETER;
- - }
- -
- if (DEBUGLEVEL >= 10) {
- struct CHALLENGE_MESSAGE *challenge = talloc(
- talloc_tos(), struct CHALLENGE_MESSAGE);
- @@ -525,13 +624,6 @@ noccache:
- }
- }
-
- - data_blob_free(&server_domain_blob);
- -
- - DEBUG(3, ("Got challenge flags:\n"));
- - debug_ntlmssp_flags(chal_flags);
- -
- - ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
- -
- if (ntlmssp_state->unicode) {
- if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
- chal_parse_string = "CdUdbddB";
- @@ -769,6 +861,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
- ntlmssp_state->unicode = True;
-
- ntlmssp_state->use_ntlmv2 = use_ntlmv2;
- + ntlmssp_state->allow_lm_key = lp_client_lanman_auth();
-
- ntlmssp_state->expected_state = NTLMSSP_INITIAL;
-
- @@ -780,6 +873,10 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
- NTLMSSP_NEGOTIATE_KEY_EXCH |
- NTLMSSP_REQUEST_TARGET;
-
- + if (ntlmssp_state->use_ntlmv2) {
- + ntlmssp_state->allow_lm_key = false;
- + }
- +
- ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
- if (!ntlmssp_state->client.netbios_name) {
- talloc_free(ntlmssp_state);
- --- a/libcli/auth/ntlmssp.h
- +++ b/libcli/auth/ntlmssp.h
- @@ -83,6 +83,7 @@ struct ntlmssp_state
- DATA_BLOB nt_resp;
- DATA_BLOB session_key;
-
- + uint32_t required_flags;
- uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
-
- /**
|