The Samba-Bugzilla – Attachment 16245 Details for
Bug 14497
[CVE-2020-1472] [SECURITY] Samba impact of "ZeroLogon"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch v4 for 4.12
CVE-2020-1472-ZeroLogon-v4-12-stable-v4.patch (text/plain), 63.28 KB, created by
Douglas Bagnall
on 2020-09-18 08:21:51 UTC
(
hide
)
Description:
patch v4 for 4.12
Filename:
MIME Type:
Creator:
Douglas Bagnall
Created:
2020-09-18 08:21:51 UTC
Size:
63.28 KB
patch
obsolete
>From 84b8910da08dfa26440405f5e3916f222801859e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:04:57 +0200 >Subject: [PATCH 01/19] CVE-2020-1472(ZeroLogon): libcli/auth: add > netlogon_creds_random_challenge() > >It's good to have just a single isolated function that will generate >random challenges, in future we can add some logic in order to >avoid weak values, which are likely to be rejected by a server. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > libcli/auth/credentials.c | 6 ++++++ > libcli/auth/proto.h | 2 ++ > 2 files changed, 8 insertions(+) > >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index c541eeff470..46259f39306 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -33,6 +33,12 @@ > #include <gnutls/gnutls.h> > #include <gnutls/crypto.h> > >+void netlogon_creds_random_challenge(struct netr_Credential *challenge) >+{ >+ ZERO_STRUCTP(challenge); >+ generate_random_buffer(challenge->data, sizeof(challenge->data)); >+} >+ > static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, > const struct netr_Credential *in, > struct netr_Credential *out) >diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h >index 88f4a7c6c50..396484a5437 100644 >--- a/libcli/auth/proto.h >+++ b/libcli/auth/proto.h >@@ -13,6 +13,8 @@ > > /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c */ > >+void netlogon_creds_random_challenge(struct netr_Credential *challenge); >+ > NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, > struct netr_LMSessionKey *key); > NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, >-- >2.20.1 > > >From 3d9e8bd6735272b528fc10c7d8289044870229d5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:07:30 +0200 >Subject: [PATCH 02/19] CVE-2020-1472(ZeroLogon): s4:torture/rpc: make use of > netlogon_creds_random_challenge() > >This will avoid getting flakey tests once our server starts to >reject weak challenges. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/torture/rpc/lsa.c | 2 +- > source4/torture/rpc/netlogon.c | 34 ++++++++++++---------------------- > 2 files changed, 13 insertions(+), 23 deletions(-) > >diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c >index 548ebf8a090..0b1346e055a 100644 >--- a/source4/torture/rpc/lsa.c >+++ b/source4/torture/rpc/lsa.c >@@ -2872,7 +2872,7 @@ static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), > "ServerReqChallenge failed"); >diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c >index 65188d2dc85..826793717e7 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -160,7 +160,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), > "ServerReqChallenge failed"); >@@ -229,7 +229,7 @@ bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tct > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), > "ServerReqChallenge failed"); >@@ -324,7 +324,7 @@ bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), > "ServerReqChallenge failed"); >@@ -396,7 +396,7 @@ bool test_SetupCredentialsDowngrade(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), > "ServerReqChallenge failed"); >@@ -1283,7 +1283,7 @@ static bool test_ServerReqChallengeGlobal(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1372,7 +1372,7 @@ static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1461,7 +1461,7 @@ static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1551,7 +1551,7 @@ static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1643,8 +1643,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx, > r.in.credentials = &credentials1_random; > r.out.return_credentials = &credentials_discard; > >- generate_random_buffer(credentials1_random.data, >- sizeof(credentials1_random.data)); >+ netlogon_creds_random_challenge(&credentials1_random); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1656,7 +1655,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1667,16 +1666,7 @@ static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx, > r.in.credentials = &credentials1_random; > r.out.return_credentials = &credentials_discard; > >- generate_random_buffer(credentials1_random.data, >- sizeof(credentials1_random.data)); >- >- r.in.server_name = NULL; >- r.in.computer_name = "CHALTEST3"; >- r.in.credentials = &credentials1_random; >- r.out.return_credentials = &credentials_discard; >- >- generate_random_buffer(credentials1_random.data, >- sizeof(credentials1_random.data)); >+ netlogon_creds_random_challenge(&credentials1_random); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r), > "ServerReqChallenge failed on b1"); >@@ -1752,7 +1742,7 @@ static bool test_ServerReqChallengeReuse(struct torture_context *tctx, > r.in.credentials = &credentials1; > r.out.return_credentials = &credentials2; > >- generate_random_buffer(credentials1.data, sizeof(credentials1.data)); >+ netlogon_creds_random_challenge(&credentials1); > > torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), > "ServerReqChallenge"); >-- >2.20.1 > > >From 8cf3efad0e15c3b001cc23d1e1280a91878f778d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:08:38 +0200 >Subject: [PATCH 03/19] CVE-2020-1472(ZeroLogon): libcli/auth: make use of > netlogon_creds_random_challenge() in netlogon_creds_cli.c > >This will avoid getting rejected by the server if we generate >a weak challenge. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > libcli/auth/netlogon_creds_cli.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c >index 407cb471cbc..12cb3149ff6 100644 >--- a/libcli/auth/netlogon_creds_cli.c >+++ b/libcli/auth/netlogon_creds_cli.c >@@ -1177,8 +1177,7 @@ static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req) > > TALLOC_FREE(state->creds); > >- generate_random_buffer(state->client_challenge.data, >- sizeof(state->client_challenge.data)); >+ netlogon_creds_random_challenge(&state->client_challenge); > > subreq = dcerpc_netr_ServerReqChallenge_send(state, state->ev, > state->binding_handle, >-- >2.20.1 > > >From 2f21d4bd6c68016b1e9c737dc6614131afa2181d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:10:53 +0200 >Subject: [PATCH 04/19] CVE-2020-1472(ZeroLogon): s3:rpc_server:netlogon: make > use of netlogon_creds_random_challenge() > >This is not strictly needed, but makes things more clear. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index 52b17c10e61..516bbd7f6a8 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -840,8 +840,7 @@ NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p, > > pipe_state->client_challenge = *r->in.credentials; > >- generate_random_buffer(pipe_state->server_challenge.data, >- sizeof(pipe_state->server_challenge.data)); >+ netlogon_creds_random_challenge(&pipe_state->server_challenge); > > *r->out.return_credentials = pipe_state->server_challenge; > >-- >2.20.1 > > >From b4df5225f750e686f742466e28f13c55a261674f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:10:53 +0200 >Subject: [PATCH 05/19] CVE-2020-1472(ZeroLogon): s4:rpc_server:netlogon: make > use of netlogon_creds_random_challenge() > >This is not strictly needed, but makes things more clear. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 0ab55afeab0..7d1b9db0b86 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -90,8 +90,7 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal > > pipe_state->client_challenge = *r->in.credentials; > >- generate_random_buffer(pipe_state->server_challenge.data, >- sizeof(pipe_state->server_challenge.data)); >+ netlogon_creds_random_challenge(&pipe_state->server_challenge); > > *r->out.return_credentials = pipe_state->server_challenge; > >-- >2.20.1 > > >From 18639a64e81866767eaf3e4ea118d932e1cf0d0c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:15:26 +0200 >Subject: [PATCH 06/19] CVE-2020-1472(ZeroLogon): libcli/auth: add > netlogon_creds_is_random_challenge() to avoid weak values > >This is the check Windows is using, so we won't generate challenges, >which are rejected by Windows DCs (and future Samba DCs). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > libcli/auth/credentials.c | 23 ++++++++++++++++++++++- > libcli/auth/proto.h | 1 + > 2 files changed, 23 insertions(+), 1 deletion(-) > >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index 46259f39306..54a20100b51 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -33,10 +33,31 @@ > #include <gnutls/gnutls.h> > #include <gnutls/crypto.h> > >+bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge) >+{ >+ /* >+ * If none of the first 5 bytes of the client challenge is unique, the >+ * server MUST fail session-key negotiation without further processing >+ * of the following steps. >+ */ >+ >+ if (challenge->data[1] == challenge->data[0] && >+ challenge->data[2] == challenge->data[0] && >+ challenge->data[3] == challenge->data[0] && >+ challenge->data[4] == challenge->data[0]) >+ { >+ return false; >+ } >+ >+ return true; >+} >+ > void netlogon_creds_random_challenge(struct netr_Credential *challenge) > { > ZERO_STRUCTP(challenge); >- generate_random_buffer(challenge->data, sizeof(challenge->data)); >+ while (!netlogon_creds_is_random_challenge(challenge)) { >+ generate_random_buffer(challenge->data, sizeof(challenge->data)); >+ } > } > > static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, >diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h >index 396484a5437..a62668f088f 100644 >--- a/libcli/auth/proto.h >+++ b/libcli/auth/proto.h >@@ -13,6 +13,7 @@ > > /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c */ > >+bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge); > void netlogon_creds_random_challenge(struct netr_Credential *challenge); > > NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, >-- >2.20.1 > > >From 2eb0f87de8c9d86fad4ca1bd74f05d15af98f56e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:17:29 +0200 >Subject: [PATCH 07/19] CVE-2020-1472(ZeroLogon): libcli/auth: reject weak > client challenges in netlogon_creds_server_init() > >This implements the note from MS-NRPC 3.1.4.1 Session-Key Negotiation: > > 7. If none of the first 5 bytes of the client challenge is unique, the > server MUST fail session-key negotiation without further processing of > the following steps. > >It lets ./zerologon_tester.py from >https://github.com/SecuraBV/CVE-2020-1472.git >report: "Attack failed. Target is probably patched." > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > libcli/auth/credentials.c | 17 ++++++++++++++++- > libcli/auth/wscript_build | 2 +- > 2 files changed, 17 insertions(+), 2 deletions(-) > >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index 54a20100b51..23339d98bfa 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -24,6 +24,7 @@ > #include "system/time.h" > #include "libcli/auth/libcli_auth.h" > #include "../libcli/security/dom_sid.h" >+#include "lib/util/util_str_escape.h" > > #ifndef HAVE_GNUTLS_AES_CFB8 > #include "lib/crypto/aes.h" >@@ -704,7 +705,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me > > struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); > NTSTATUS status; >- >+ bool ok; > > if (!creds) { > return NULL; >@@ -717,6 +718,20 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me > dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); > dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); > >+ ok = netlogon_creds_is_random_challenge(client_challenge); >+ if (!ok) { >+ DBG_WARNING("CVE-2020-1472(ZeroLogon): " >+ "non-random client challenge rejected for " >+ "client_account[%s] client_computer_name[%s]\n", >+ log_escape(mem_ctx, client_account), >+ log_escape(mem_ctx, client_computer_name)); >+ dump_data(DBGLVL_WARNING, >+ client_challenge->data, >+ sizeof(client_challenge->data)); >+ talloc_free(creds); >+ return NULL; >+ } >+ > creds->computer_name = talloc_strdup(creds, client_computer_name); > if (!creds->computer_name) { > talloc_free(creds); >diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build >index 41937623630..2a6a7468e45 100644 >--- a/libcli/auth/wscript_build >+++ b/libcli/auth/wscript_build >@@ -18,7 +18,7 @@ bld.SAMBA_SUBSYSTEM('NTLM_CHECK', > > bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH', > source='credentials.c session.c smbencrypt.c smbdes.c', >- public_deps='MSRPC_PARSE gnutls GNUTLS_HELPERS', >+ public_deps='MSRPC_PARSE gnutls GNUTLS_HELPERS util_str_escape', > public_headers='credentials.h:domain_credentials.h' > ) > >-- >2.20.1 > > >From 592e8e9acdca472115fdf69a3d0904f1740f4fb0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 19:20:25 +0200 >Subject: [PATCH 08/19] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: > protect netr_ServerPasswordSet2 against unencrypted passwords > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 60 ++++++++++++++++++- > 1 file changed, 59 insertions(+), 1 deletion(-) > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 7d1b9db0b86..4aa6f256a07 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -724,7 +724,10 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal > struct NL_PASSWORD_VERSION version = {}; > const uint32_t *new_version = NULL; > NTSTATUS nt_status; >- DATA_BLOB new_password; >+ DATA_BLOB new_password = data_blob_null; >+ size_t confounder_len; >+ DATA_BLOB dec_blob = data_blob_null; >+ DATA_BLOB enc_blob = data_blob_null; > int ret; > struct samr_CryptPassword password_buf; > >@@ -790,6 +793,61 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal > return NT_STATUS_WRONG_PASSWORD; > } > >+ /* >+ * Make sure the length field was encrypted, >+ * otherwise we are under attack. >+ */ >+ if (new_password.length == r->in.new_password->length) { >+ DBG_WARNING("Length[%zu] field not encrypted\n", >+ new_password.length); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * We don't allow empty passwords for machine accounts. >+ */ >+ if (new_password.length < 2) { >+ DBG_WARNING("Empty password Length[%zu]\n", >+ new_password.length); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * Make sure the confounder part of CryptPassword >+ * buffer was encrypted, otherwise we are under attack. >+ */ >+ confounder_len = 512 - new_password.length; >+ enc_blob = data_blob_const(r->in.new_password->data, confounder_len); >+ dec_blob = data_blob_const(password_buf.data, confounder_len); >+ if (data_blob_cmp(&dec_blob, &enc_blob) == 0) { >+ DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n", >+ confounder_len); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * Check that the password part was actually encrypted, >+ * otherwise we are under attack. >+ */ >+ enc_blob = data_blob_const(r->in.new_password->data + confounder_len, >+ new_password.length); >+ dec_blob = data_blob_const(password_buf.data + confounder_len, >+ new_password.length); >+ if (data_blob_cmp(&dec_blob, &enc_blob) == 0) { >+ DBG_WARNING("Password buffer not encrypted Length[%zu]\n", >+ new_password.length); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * don't allow zero buffers >+ */ >+ if (all_zero(new_password.data, new_password.length)) { >+ DBG_WARNING("Password zero buffer Length[%zu]\n", >+ new_password.length); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ > /* fetch the old password hashes (at least one of both has to exist) */ > > ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, >-- >2.20.1 > > >From ff66560357d3eb23ce71f6667443e47a0c491833 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 16 Sep 2020 12:48:21 -0700 >Subject: [PATCH 09/19] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: Fix > mem leak onto p->mem_ctx in error path of _netr_ServerPasswordSet2(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index 516bbd7f6a8..b26efb78bab 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -1385,6 +1385,7 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, > 516); > } > if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(creds); > return status; > } > >-- >2.20.1 > > >From aa57f084ca2cf16e323d172634eacf34db3ff0d7 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 16 Sep 2020 12:53:50 -0700 >Subject: [PATCH 10/19] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: > protect netr_ServerPasswordSet2 against unencrypted passwords > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Jeremy Allison <jra@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 98 +++++++++++++++++++-- > 1 file changed, 92 insertions(+), 6 deletions(-) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index b26efb78bab..693e254b051 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -1343,9 +1343,14 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, > { > NTSTATUS status; > struct netlogon_creds_CredentialState *creds = NULL; >- DATA_BLOB plaintext; >+ DATA_BLOB plaintext = data_blob_null; >+ DATA_BLOB new_password = data_blob_null; >+ size_t confounder_len; >+ DATA_BLOB dec_blob = data_blob_null; >+ DATA_BLOB enc_blob = data_blob_null; > struct samr_CryptPassword password_buf; > struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}}; >+ bool ok; > > become_root(); > status = netr_creds_server_step_check(p, p->mem_ctx, >@@ -1389,18 +1394,99 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, > return status; > } > >- if (!decode_pw_buffer(p->mem_ctx, >- password_buf.data, >- (char**) &plaintext.data, >- &plaintext.length, >- CH_UTF16)) { >+ if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &new_password)) { > DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password " > "from a buffer. Rejecting auth request as a wrong password\n")); > TALLOC_FREE(creds); > return NT_STATUS_WRONG_PASSWORD; > } > >+ /* >+ * Make sure the length field was encrypted, >+ * otherwise we are under attack. >+ */ >+ if (new_password.length == r->in.new_password->length) { >+ DBG_WARNING("Length[%zu] field not encrypted\n", >+ new_password.length); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * We don't allow empty passwords for machine accounts. >+ */ >+ if (new_password.length < 2) { >+ DBG_WARNING("Empty password Length[%zu]\n", >+ new_password.length); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * Make sure the confounder part of CryptPassword >+ * buffer was encrypted, otherwise we are under attack. >+ */ >+ confounder_len = 512 - new_password.length; >+ enc_blob = data_blob_const(r->in.new_password->data, confounder_len); >+ dec_blob = data_blob_const(password_buf.data, confounder_len); >+ if (data_blob_cmp(&dec_blob, &enc_blob) == 0) { >+ DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n", >+ confounder_len); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * Check that the password part was actually encrypted, >+ * otherwise we are under attack. >+ */ >+ enc_blob = data_blob_const(r->in.new_password->data + confounder_len, >+ new_password.length); >+ dec_blob = data_blob_const(password_buf.data + confounder_len, >+ new_password.length); >+ if (data_blob_cmp(&dec_blob, &enc_blob) == 0) { >+ DBG_WARNING("Password buffer not encrypted Length[%zu]\n", >+ new_password.length); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * don't allow zero buffers >+ */ >+ if (all_zero(new_password.data, new_password.length)) { >+ DBG_WARNING("Password zero buffer Length[%zu]\n", >+ new_password.length); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* Convert from UTF16 -> plaintext. */ >+ ok = convert_string_talloc(p->mem_ctx, >+ CH_UTF16, >+ CH_UNIX, >+ new_password.data, >+ new_password.length, >+ (void *)&plaintext.data, >+ &plaintext.length); >+ if (!ok) { >+ DBG_WARNING("unable to extract password from a buffer. " >+ "Rejecting auth request as a wrong password\n"); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ >+ /* >+ * We don't allow empty passwords for machine accounts. >+ */ >+ > cr.creds.password = (const char*) plaintext.data; >+ if (strlen(cr.creds.password) == 0) { >+ DBG_WARNING("Empty plaintext password\n"); >+ TALLOC_FREE(creds); >+ return NT_STATUS_WRONG_PASSWORD; >+ } >+ > status = netr_set_machine_account_password(p->mem_ctx, > p->session_info, > p->msg_ctx, >-- >2.20.1 > > >From 1c8234f6da6979a063c96c0eb32ddb55a51ce548 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 10:18:45 +0200 >Subject: [PATCH 11/19] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: > refactor dcesrv_netr_creds_server_step_check() > >We should debug more details about the failing request. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 45 ++++++++++++++----- > 1 file changed, 33 insertions(+), 12 deletions(-) > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 4aa6f256a07..7ccf46ae79b 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -624,26 +624,47 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc > NTSTATUS nt_status; > int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); > bool schannel_global_required = (schannel == true); >+ struct netlogon_creds_CredentialState *creds = NULL; >+ enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; >+ uint16_t opnum = dce_call->pkt.u.request.opnum; >+ const char *opname = "<unknown>"; > >- if (schannel_global_required) { >- enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; >- >- dcesrv_call_auth_info(dce_call, &auth_type, NULL); >- >- if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { >- DBG_ERR("[%s] is not using schannel\n", >- computer_name); >- return NT_STATUS_ACCESS_DENIED; >- } >+ if (opnum < ndr_table_netlogon.num_calls) { >+ opname = ndr_table_netlogon.calls[opnum].name; > } > >+ dcesrv_call_auth_info(dce_call, &auth_type, NULL); >+ > nt_status = schannel_check_creds_state(mem_ctx, > dce_call->conn->dce_ctx->lp_ctx, > computer_name, > received_authenticator, > return_authenticator, >- creds_out); >- return nt_status; >+ &creds); >+ if (!NT_STATUS_IS_OK(nt_status)) { >+ ZERO_STRUCTP(return_authenticator); >+ return nt_status; >+ } >+ >+ if (schannel_global_required) { >+ if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { >+ *creds_out = creds; >+ return NT_STATUS_OK; >+ } >+ >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) without schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ TALLOC_FREE(creds); >+ ZERO_STRUCTP(return_authenticator); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ *creds_out = creds; >+ return NT_STATUS_OK; > } > > /* >-- >2.20.1 > > >From d8e520870c5c8943c289b3f373b1a4bcceefc174 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 10:56:53 +0200 >Subject: [PATCH 12/19] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: > support "server require schannel:WORKSTATION$ = no" > >This allows to add expections for individual workstations, when using "server schannel = yes". >"server schannel = auto" is very insecure and will be removed soon. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 7ccf46ae79b..7994cb904b7 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -624,6 +624,7 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc > NTSTATUS nt_status; > int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); > bool schannel_global_required = (schannel == true); >+ bool schannel_required = schannel_global_required; > struct netlogon_creds_CredentialState *creds = NULL; > enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; > uint16_t opnum = dce_call->pkt.u.request.opnum; >@@ -646,7 +647,13 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc > return nt_status; > } > >- if (schannel_global_required) { >+ schannel_required = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, >+ NULL, >+ "server require schannel", >+ creds->account_name, >+ schannel_global_required); >+ >+ if (schannel_required) { > if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { > *creds_out = creds; > return NT_STATUS_OK; >-- >2.20.1 > > >From 629aeb89877ca7d8aef53b5ea2c507d2f146a23b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 17 Sep 2020 13:37:26 +0200 >Subject: [PATCH 13/19] CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: log > warnings about unsecure configurations >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This should give admins wawrnings until they have a secure >configuration. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Günther Deschner <gd@samba.org> >--- > source4/rpc_server/netlogon/dcerpc_netlogon.c | 66 ++++++++++++++++++- > 1 file changed, 63 insertions(+), 3 deletions(-) > >diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c >index 7994cb904b7..9972138dbde 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -625,10 +625,12 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc > int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); > bool schannel_global_required = (schannel == true); > bool schannel_required = schannel_global_required; >+ const char *explicit_opt = NULL; > struct netlogon_creds_CredentialState *creds = NULL; > enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; > uint16_t opnum = dce_call->pkt.u.request.opnum; > const char *opname = "<unknown>"; >+ static bool warned_global_once = false; > > if (opnum < ndr_table_netlogon.num_calls) { > opname = ndr_table_netlogon.calls[opnum].name; >@@ -647,11 +649,18 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc > return nt_status; > } > >- schannel_required = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, >+ /* >+ * We don't use lpcfg_parm_bool(), as we >+ * need the explicit_opt pointer in order to >+ * adjust the debug messages. >+ */ >+ explicit_opt = lpcfg_get_parametric(dce_call->conn->dce_ctx->lp_ctx, > NULL, > "server require schannel", >- creds->account_name, >- schannel_global_required); >+ creds->account_name); >+ if (explicit_opt != NULL) { >+ schannel_required = lp_bool(explicit_opt); >+ } > > if (schannel_required) { > if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { >@@ -665,11 +674,62 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc > opname, opnum, > log_escape(mem_ctx, creds->account_name), > log_escape(mem_ctx, creds->computer_name)); >+ DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option " >+ "'server require schannel:%s = no' is needed! \n", >+ log_escape(mem_ctx, creds->account_name)); > TALLOC_FREE(creds); > ZERO_STRUCTP(return_authenticator); > return NT_STATUS_ACCESS_DENIED; > } > >+ if (!schannel_global_required && !warned_global_once) { >+ /* >+ * We want admins to notice their misconfiguration! >+ */ >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "Please configure 'server schannel = yes', " >+ "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n"); >+ warned_global_once = true; >+ } >+ >+ if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) WITH schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "Option 'server require schannel:%s = no' not needed!?\n", >+ log_escape(mem_ctx, creds->account_name)); >+ >+ *creds_out = creds; >+ return NT_STATUS_OK; >+ } >+ >+ >+ if (explicit_opt != NULL) { >+ DBG_INFO("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) without schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ DBG_INFO("CVE-2020-1472(ZeroLogon): " >+ "Option 'server require schannel:%s = no' still needed!\n", >+ log_escape(mem_ctx, creds->account_name)); >+ } else { >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) without schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option " >+ "'server require schannel:%s = no' might be needed!\n", >+ log_escape(mem_ctx, creds->account_name)); >+ } >+ > *creds_out = creds; > return NT_STATUS_OK; > } >-- >2.20.1 > > >From eab8661ef16856eb0926fe3426f7fe6ac870faae Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 17 Sep 2020 14:57:22 +0200 >Subject: [PATCH 14/19] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: > refactor dcesrv_netr_creds_server_step_check() >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We should debug more details about the failing request. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Günther Deschner <gd@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 43 +++++++++++++++++---- > 1 file changed, 35 insertions(+), 8 deletions(-) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index 693e254b051..c134e07573c 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -47,6 +47,7 @@ > #include "../lib/tsocket/tsocket.h" > #include "lib/param/param.h" > #include "libsmb/dsgetdcname.h" >+#include "lib/util/util_str_escape.h" > > extern userdom_struct current_user_info; > >@@ -1073,19 +1074,21 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > NTSTATUS status; > bool schannel_global_required = (lp_server_schannel() == true) ? true:false; > struct loadparm_context *lp_ctx; >+ struct netlogon_creds_CredentialState *creds = NULL; >+ enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; >+ uint16_t opnum = p->opnum; >+ const char *opname = "<unknown>"; > > if (creds_out != NULL) { > *creds_out = NULL; > } > >- if (schannel_global_required) { >- if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { >- DBG_ERR("[%s] is not using schannel\n", >- computer_name); >- return NT_STATUS_ACCESS_DENIED; >- } >+ if (opnum < ndr_table_netlogon.num_calls) { >+ opname = ndr_table_netlogon.calls[opnum].name; > } > >+ auth_type = p->auth.auth_type; >+ > lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers()); > if (lp_ctx == NULL) { > DEBUG(0, ("loadparm_init_s3 failed\n")); >@@ -1094,9 +1097,33 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > > status = schannel_check_creds_state(mem_ctx, lp_ctx, > computer_name, received_authenticator, >- return_authenticator, creds_out); >+ return_authenticator, &creds); > talloc_unlink(mem_ctx, lp_ctx); >- return status; >+ >+ if (!NT_STATUS_IS_OK(status)) { >+ ZERO_STRUCTP(return_authenticator); >+ return status; >+ } >+ >+ if (schannel_global_required) { >+ if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { >+ *creds_out = creds; >+ return NT_STATUS_OK; >+ } >+ >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) without schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ TALLOC_FREE(creds); >+ ZERO_STRUCTP(return_authenticator); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ *creds_out = creds; >+ return NT_STATUS_OK; > } > > >-- >2.20.1 > > >From db2580705011c996a4feb01c4b6f069a4e013135 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 17 Sep 2020 14:23:16 +0200 >Subject: [PATCH 15/19] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: > support "server require schannel:WORKSTATION$ = no" >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This allows to add expections for individual workstations, when using "server schannel = yes". >"server schannel = auto" is very insecure and will be removed soon. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Günther Deschner <gd@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index c134e07573c..3327f4bc0a0 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -1073,6 +1073,7 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > { > NTSTATUS status; > bool schannel_global_required = (lp_server_schannel() == true) ? true:false; >+ bool schannel_required = schannel_global_required; > struct loadparm_context *lp_ctx; > struct netlogon_creds_CredentialState *creds = NULL; > enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; >@@ -1105,7 +1106,11 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > return status; > } > >- if (schannel_global_required) { >+ schannel_required = lp_parm_bool(GLOBAL_SECTION_SNUM, >+ "server require schannel", >+ creds->account_name, >+ schannel_global_required); >+ if (schannel_required) { > if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { > *creds_out = creds; > return NT_STATUS_OK; >-- >2.20.1 > > >From fa5fc293263150238755fbb8310653550f57049a Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 17 Sep 2020 14:42:52 +0200 >Subject: [PATCH 16/19] CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: log > warnings about unsecure configurations >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Günther Deschner <gd@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 70 +++++++++++++++++++-- > 1 file changed, 66 insertions(+), 4 deletions(-) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index 3327f4bc0a0..9ef74447b84 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -1074,11 +1074,13 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > NTSTATUS status; > bool schannel_global_required = (lp_server_schannel() == true) ? true:false; > bool schannel_required = schannel_global_required; >+ const char *explicit_opt = NULL; > struct loadparm_context *lp_ctx; > struct netlogon_creds_CredentialState *creds = NULL; > enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE; > uint16_t opnum = p->opnum; > const char *opname = "<unknown>"; >+ static bool warned_global_once = false; > > if (creds_out != NULL) { > *creds_out = NULL; >@@ -1106,10 +1108,20 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > return status; > } > >- schannel_required = lp_parm_bool(GLOBAL_SECTION_SNUM, >- "server require schannel", >- creds->account_name, >- schannel_global_required); >+ /* >+ * We don't use lp_parm_bool(), as we >+ * need the explicit_opt pointer in order to >+ * adjust the debug messages. >+ */ >+ >+ explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM, >+ "server require schannel", >+ creds->account_name, >+ NULL); >+ if (explicit_opt != NULL) { >+ schannel_required = lp_bool(explicit_opt); >+ } >+ > if (schannel_required) { > if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { > *creds_out = creds; >@@ -1122,11 +1134,61 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > opname, opnum, > log_escape(mem_ctx, creds->account_name), > log_escape(mem_ctx, creds->computer_name)); >+ DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option " >+ "'server require schannel:%s = no' is needed! \n", >+ log_escape(mem_ctx, creds->account_name)); > TALLOC_FREE(creds); > ZERO_STRUCTP(return_authenticator); > return NT_STATUS_ACCESS_DENIED; > } > >+ if (!schannel_global_required && !warned_global_once) { >+ /* >+ * We want admins to notice their misconfiguration! >+ */ >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "Please configure 'server schannel = yes', " >+ "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n"); >+ warned_global_once = true; >+ } >+ >+ if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) WITH schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "Option 'server require schannel:%s = no' not needed!?\n", >+ log_escape(mem_ctx, creds->account_name)); >+ >+ *creds_out = creds; >+ return NT_STATUS_OK; >+ } >+ >+ if (explicit_opt != NULL) { >+ DBG_INFO("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) without schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ DBG_INFO("CVE-2020-1472(ZeroLogon): " >+ "Option 'server require schannel:%s = no' still needed!\n", >+ log_escape(mem_ctx, creds->account_name)); >+ } else { >+ DBG_ERR("CVE-2020-1472(ZeroLogon): " >+ "%s request (opnum[%u]) without schannel from " >+ "client_account[%s] client_computer_name[%s]\n", >+ opname, opnum, >+ log_escape(mem_ctx, creds->account_name), >+ log_escape(mem_ctx, creds->computer_name)); >+ DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option " >+ "'server require schannel:%s = no' might be needed!\n", >+ log_escape(mem_ctx, creds->account_name)); >+ } >+ > *creds_out = creds; > return NT_STATUS_OK; > } >-- >2.20.1 > > >From 296a62d1589dbf33aa751e8346ba5721f6314215 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 17 Sep 2020 17:27:54 +0200 >Subject: [PATCH 17/19] CVE-2020-1472(ZeroLogon): docs-xml: document 'server > require schannel:COMPUTERACCOUNT' > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > .../smbdotconf/security/serverschannel.xml | 69 +++++++++++++++---- > 1 file changed, 54 insertions(+), 15 deletions(-) > >diff --git a/docs-xml/smbdotconf/security/serverschannel.xml b/docs-xml/smbdotconf/security/serverschannel.xml >index 489492d79b1..b682d086f76 100644 >--- a/docs-xml/smbdotconf/security/serverschannel.xml >+++ b/docs-xml/smbdotconf/security/serverschannel.xml >@@ -7,26 +7,65 @@ > <description> > > <para> >- This option is deprecated with Samba 4.8 and will be removed in future. >- At the same time the default changed to yes, which will be the >- hardcoded behavior in future. If you have the need for the behavior of "auto" >- to be kept, please file a bug at https://bugzilla.samba.org. >+ This option is deprecated and will be removed in future, >+ as it is a security problem if not set to "yes" (which will be >+ the hardcoded behavior in future). > </para> > > <para> >- This controls whether the server offers or even demands the use of the netlogon schannel. >- <smbconfoption name="server schannel">no</smbconfoption> does not offer the schannel, <smbconfoption >- name="server schannel">auto</smbconfoption> offers the schannel but does not enforce it, and <smbconfoption >- name="server schannel">yes</smbconfoption> denies access if the client is not able to speak netlogon schannel. >- This is only the case for Windows NT4 before SP4. >- </para> >- >+ Samba will complain in the log files at log level 0, >+ about the security problem if the option is not set to "yes". >+ </para> > <para> >- Please note that with this set to <literal>no</literal>, you will have to apply the WindowsXP >- <filename>WinXP_SignOrSeal.reg</filename> registry patch found in the docs/registry subdirectory of the Samba distribution tarball. >- </para> >+ See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497 >+ </para> >+ >+ <para>If you still have legacy domain members use the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option. >+ </para> >+ >+ <para>This option yields precedence to the <smbconfoption name="server require schannel:COMPUTERACCOUNT"/> option.</para> >+ > </description> > > <value type="default">yes</value> >-<value type="example">auto</value> >+</samba:parameter> >+ >+<samba:parameter name="server require schannel:COMPUTERACCOUNT" >+ context="G" >+ type="string" >+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> >+<description> >+ >+ <para>If you still have legacy domain members, which required "server schannel = auto" before, >+ it is possible to specify explicit expection per computer account >+ by using 'server require schannel:COMPUTERACCOUNT = no' as option. >+ Note that COMPUTERACCOUNT has to be the sAMAccountName value of >+ the computer account (including the trailing '$' sign). >+ </para> >+ >+ <para> >+ Samba will complain in the log files at log level 0, >+ about the security problem if the option is not set to "no", >+ but the related computer is actually using the netlogon >+ secure channel (schannel) feature. >+ </para> >+ >+ <para> >+ Samba will warn in the log files at log level 5, >+ if a setting is still needed for the specified computer account. >+ </para> >+ >+ <para> >+ See CVE-2020-1472(ZeroLogon) https://bugzilla.samba.org/show_bug.cgi?id=14497 >+ </para> >+ >+ <para>This option takes precedence to the <smbconfoption name="server schannel"/> option.</para> >+ >+ <programlisting> >+ server require schannel:LEGACYCOMPUTER1$ = no >+ server require schannel:NASBOX$ = no >+ server require schannel:LEGACYCOMPUTER2$ = no >+ </programlisting> >+</description> >+ > </samba:parameter> >-- >2.20.1 > > >From 3110ca45379309c55f96e97df5d6d010390cd8c6 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Fri, 18 Sep 2020 12:39:54 +1200 >Subject: [PATCH 18/19] CVE-2020-1472(ZeroLogon): s4 torture rpc: Test empty > machine acct pwd > >Ensure that an empty machine account password can't be set by >netr_ServerPasswordSet2 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >--- > source4/torture/rpc/netlogon.c | 64 +++++++++++++++------------------- > 1 file changed, 29 insertions(+), 35 deletions(-) > >diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c >index 826793717e7..af9d94b99ff 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -725,45 +725,39 @@ static bool test_SetPassword2_with_flags(struct torture_context *tctx, > > cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED); > >- if (!torture_setting_bool(tctx, "dangerous", false)) { >- torture_comment(tctx, >- "Not testing ability to set password to '', enable dangerous tests to perform this test\n"); >+ /* >+ * As a consequence of CVE-2020-1472(ZeroLogon) >+ * Samba explicitly disallows the setting of an empty machine account >+ * password. >+ * >+ * Note that this may fail against Windows, and leave a machine account >+ * with an empty password. >+ */ >+ password = ""; >+ encode_pw_buffer(password_buf.data, password, STR_UNICODE); >+ if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { >+ netlogon_creds_aes_encrypt(creds, password_buf.data, 516); > } else { >- /* by changing the machine password to "" >- * we check if the server uses password restrictions >- * for ServerPasswordSet2 >- * (win2k3 accepts "") >- */ >- password = ""; >- encode_pw_buffer(password_buf.data, password, STR_UNICODE); >- if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { >- netlogon_creds_aes_encrypt(creds, password_buf.data, 516); >- } else { >- netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); >- } >- memcpy(new_password.data, password_buf.data, 512); >- new_password.length = IVAL(password_buf.data, 512); >- >- torture_comment(tctx, >- "Testing ServerPasswordSet2 on machine account\n"); >- torture_comment(tctx, >- "Changing machine account password to '%s'\n", password); >- >- netlogon_creds_client_authenticator(creds, &credential); >- >- torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r), >- "ServerPasswordSet2 failed"); >- torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed"); >+ netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); >+ } >+ memcpy(new_password.data, password_buf.data, 512); >+ new_password.length = IVAL(password_buf.data, 512); > >- if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { >- torture_comment(tctx, "Credential chaining failed\n"); >- } >+ torture_comment(tctx, >+ "Testing ServerPasswordSet2 on machine account\n"); >+ torture_comment(tctx, >+ "Changing machine account password to '%s'\n", password); > >- cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED); >- } >+ netlogon_creds_client_authenticator(creds, &credential); > >- torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds), >- "ServerPasswordSet failed to actually change the password"); >+ torture_assert_ntstatus_ok( >+ tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r), >+ "ServerPasswordSet2 failed"); >+ torture_assert_ntstatus_equal( >+ tctx, >+ r.out.result, >+ NT_STATUS_WRONG_PASSWORD, >+ "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD"); > > /* now try a random password */ > password = generate_random_password(tctx, 8, 255); >-- >2.20.1 > > >From a13ddb0fe6ddf29642976f4caff9c2391676645c Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Fri, 18 Sep 2020 15:57:34 +1200 >Subject: [PATCH 19/19] CVE-2020-1472(ZeroLogon): s4 torture rpc: repeated > bytes in client challenge > >Ensure that client challenges with the first 5 bytes identical are >rejected. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 > >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> > >[abartlet@samba.org: backported from master as test order was flipped] >--- > source4/torture/rpc/netlogon.c | 335 +++++++++++++++++++++++++++++++++ > 1 file changed, 335 insertions(+) > >diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c >index af9d94b99ff..c9e614fda30 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -486,6 +486,325 @@ bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1, > return true; > } > >+static bool test_ServerReqChallenge( >+ struct torture_context *tctx, >+ struct dcerpc_pipe *p, >+ struct cli_credentials *credentials) >+{ >+ struct netr_ServerReqChallenge r; >+ struct netr_Credential credentials1, credentials2, credentials3; >+ const char *machine_name; >+ struct dcerpc_binding_handle *b = p->binding_handle; >+ struct netr_ServerAuthenticate2 a; >+ uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; >+ uint32_t out_negotiate_flags = 0; >+ const struct samr_Password *mach_password = NULL; >+ enum netr_SchannelType sec_chan_type = 0; >+ struct netlogon_creds_CredentialState *creds = NULL; >+ const char *account_name = NULL; >+ >+ machine_name = cli_credentials_get_workstation(credentials); >+ mach_password = cli_credentials_get_nt_hash(credentials, tctx); >+ account_name = cli_credentials_get_username(credentials); >+ sec_chan_type = cli_credentials_get_secure_channel_type(credentials); >+ >+ torture_comment(tctx, "Testing ServerReqChallenge\n"); >+ >+ r.in.server_name = NULL; >+ r.in.computer_name = machine_name; >+ r.in.credentials = &credentials1; >+ r.out.return_credentials = &credentials2; >+ >+ netlogon_creds_random_challenge(&credentials1); >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), >+ "ServerReqChallenge failed"); >+ torture_assert_ntstatus_ok( >+ tctx, >+ r.out.result, >+ "ServerReqChallenge failed"); >+ a.in.server_name = NULL; >+ a.in.account_name = account_name; >+ a.in.secure_channel_type = sec_chan_type; >+ a.in.computer_name = machine_name; >+ a.in.negotiate_flags = &in_negotiate_flags; >+ a.out.negotiate_flags = &out_negotiate_flags; >+ a.in.credentials = &credentials3; >+ a.out.return_credentials = &credentials3; >+ >+ creds = netlogon_creds_client_init(tctx, a.in.account_name, >+ a.in.computer_name, >+ a.in.secure_channel_type, >+ &credentials1, &credentials2, >+ mach_password, &credentials3, >+ in_negotiate_flags); >+ >+ torture_assert(tctx, creds != NULL, "memory allocation"); >+ >+ torture_comment(tctx, "Testing ServerAuthenticate2\n"); >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a), >+ "ServerAuthenticate2 failed"); >+ torture_assert_ntstatus_equal( >+ tctx, >+ a.out.result, >+ NT_STATUS_OK, >+ "ServerAuthenticate2 unexpected"); >+ >+ return true; >+} >+ >+static bool test_ServerReqChallenge_zero_challenge( >+ struct torture_context *tctx, >+ struct dcerpc_pipe *p, >+ struct cli_credentials *credentials) >+{ >+ struct netr_ServerReqChallenge r; >+ struct netr_Credential credentials1, credentials2, credentials3; >+ const char *machine_name; >+ struct dcerpc_binding_handle *b = p->binding_handle; >+ struct netr_ServerAuthenticate2 a; >+ uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; >+ uint32_t out_negotiate_flags = 0; >+ const struct samr_Password *mach_password = NULL; >+ enum netr_SchannelType sec_chan_type = 0; >+ struct netlogon_creds_CredentialState *creds = NULL; >+ const char *account_name = NULL; >+ >+ machine_name = cli_credentials_get_workstation(credentials); >+ mach_password = cli_credentials_get_nt_hash(credentials, tctx); >+ account_name = cli_credentials_get_username(credentials); >+ sec_chan_type = cli_credentials_get_secure_channel_type(credentials); >+ >+ torture_comment(tctx, "Testing ServerReqChallenge\n"); >+ >+ r.in.server_name = NULL; >+ r.in.computer_name = machine_name; >+ r.in.credentials = &credentials1; >+ r.out.return_credentials = &credentials2; >+ >+ /* >+ * Set the client challenge to zero, this should fail >+ * CVE-2020-1472(ZeroLogon) >+ * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 >+ */ >+ ZERO_STRUCT(credentials1); >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), >+ "ServerReqChallenge failed"); >+ torture_assert_ntstatus_ok( >+ tctx, >+ r.out.result, >+ "ServerReqChallenge failed"); >+ a.in.server_name = NULL; >+ a.in.account_name = account_name; >+ a.in.secure_channel_type = sec_chan_type; >+ a.in.computer_name = machine_name; >+ a.in.negotiate_flags = &in_negotiate_flags; >+ a.out.negotiate_flags = &out_negotiate_flags; >+ a.in.credentials = &credentials3; >+ a.out.return_credentials = &credentials3; >+ >+ creds = netlogon_creds_client_init(tctx, a.in.account_name, >+ a.in.computer_name, >+ a.in.secure_channel_type, >+ &credentials1, &credentials2, >+ mach_password, &credentials3, >+ in_negotiate_flags); >+ >+ torture_assert(tctx, creds != NULL, "memory allocation"); >+ >+ torture_comment(tctx, "Testing ServerAuthenticate2\n"); >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a), >+ "ServerAuthenticate2 failed"); >+ torture_assert_ntstatus_equal( >+ tctx, >+ a.out.result, >+ NT_STATUS_ACCESS_DENIED, >+ "ServerAuthenticate2 unexpected"); >+ >+ return true; >+} >+ >+static bool test_ServerReqChallenge_5_repeats( >+ struct torture_context *tctx, >+ struct dcerpc_pipe *p, >+ struct cli_credentials *credentials) >+{ >+ struct netr_ServerReqChallenge r; >+ struct netr_Credential credentials1, credentials2, credentials3; >+ const char *machine_name; >+ struct dcerpc_binding_handle *b = p->binding_handle; >+ struct netr_ServerAuthenticate2 a; >+ uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; >+ uint32_t out_negotiate_flags = 0; >+ const struct samr_Password *mach_password = NULL; >+ enum netr_SchannelType sec_chan_type = 0; >+ struct netlogon_creds_CredentialState *creds = NULL; >+ const char *account_name = NULL; >+ >+ machine_name = cli_credentials_get_workstation(credentials); >+ mach_password = cli_credentials_get_nt_hash(credentials, tctx); >+ account_name = cli_credentials_get_username(credentials); >+ sec_chan_type = cli_credentials_get_secure_channel_type(credentials); >+ >+ torture_comment(tctx, "Testing ServerReqChallenge\n"); >+ >+ r.in.server_name = NULL; >+ r.in.computer_name = machine_name; >+ r.in.credentials = &credentials1; >+ r.out.return_credentials = &credentials2; >+ >+ /* >+ * Set the first 5 bytes of the client challenge to the same value, >+ * this should fail CVE-2020-1472(ZeroLogon) >+ * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 >+ */ >+ credentials1.data[0] = 'A'; >+ credentials1.data[1] = 'A'; >+ credentials1.data[2] = 'A'; >+ credentials1.data[3] = 'A'; >+ credentials1.data[4] = 'A'; >+ credentials1.data[5] = 'B'; >+ credentials1.data[6] = 'C'; >+ credentials1.data[7] = 'D'; >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), >+ "ServerReqChallenge failed"); >+ torture_assert_ntstatus_ok( >+ tctx, >+ r.out.result, >+ "ServerReqChallenge failed"); >+ a.in.server_name = NULL; >+ a.in.account_name = account_name; >+ a.in.secure_channel_type = sec_chan_type; >+ a.in.computer_name = machine_name; >+ a.in.negotiate_flags = &in_negotiate_flags; >+ a.out.negotiate_flags = &out_negotiate_flags; >+ a.in.credentials = &credentials3; >+ a.out.return_credentials = &credentials3; >+ >+ creds = netlogon_creds_client_init(tctx, a.in.account_name, >+ a.in.computer_name, >+ a.in.secure_channel_type, >+ &credentials1, &credentials2, >+ mach_password, &credentials3, >+ in_negotiate_flags); >+ >+ torture_assert(tctx, creds != NULL, "memory allocation"); >+ >+ torture_comment(tctx, "Testing ServerAuthenticate2\n"); >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a), >+ "ServerAuthenticate2 failed"); >+ torture_assert_ntstatus_equal( >+ tctx, >+ a.out.result, >+ NT_STATUS_ACCESS_DENIED, >+ "ServerAuthenticate2 unexpected"); >+ >+ return true; >+} >+ >+static bool test_ServerReqChallenge_4_repeats( >+ struct torture_context *tctx, >+ struct dcerpc_pipe *p, >+ struct cli_credentials *credentials) >+{ >+ struct netr_ServerReqChallenge r; >+ struct netr_Credential credentials1, credentials2, credentials3; >+ const char *machine_name; >+ struct dcerpc_binding_handle *b = p->binding_handle; >+ struct netr_ServerAuthenticate2 a; >+ uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; >+ uint32_t out_negotiate_flags = 0; >+ const struct samr_Password *mach_password = NULL; >+ enum netr_SchannelType sec_chan_type = 0; >+ struct netlogon_creds_CredentialState *creds = NULL; >+ const char *account_name = NULL; >+ >+ machine_name = cli_credentials_get_workstation(credentials); >+ mach_password = cli_credentials_get_nt_hash(credentials, tctx); >+ account_name = cli_credentials_get_username(credentials); >+ sec_chan_type = cli_credentials_get_secure_channel_type(credentials); >+ >+ torture_comment(tctx, "Testing ServerReqChallenge\n"); >+ >+ r.in.server_name = NULL; >+ r.in.computer_name = machine_name; >+ r.in.credentials = &credentials1; >+ r.out.return_credentials = &credentials2; >+ >+ /* >+ * Set the first 4 bytes of the client challenge to the same >+ * value, this should pass as 5 bytes identical are needed to >+ * fail for CVE-2020-1472(ZeroLogon) >+ * >+ * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497 >+ */ >+ credentials1.data[0] = 'A'; >+ credentials1.data[1] = 'A'; >+ credentials1.data[2] = 'A'; >+ credentials1.data[3] = 'A'; >+ credentials1.data[4] = 'B'; >+ credentials1.data[5] = 'C'; >+ credentials1.data[6] = 'D'; >+ credentials1.data[7] = 'E'; >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerReqChallenge_r(b, tctx, &r), >+ "ServerReqChallenge failed"); >+ torture_assert_ntstatus_ok( >+ tctx, >+ r.out.result, >+ "ServerReqChallenge failed"); >+ a.in.server_name = NULL; >+ a.in.account_name = account_name; >+ a.in.secure_channel_type = sec_chan_type; >+ a.in.computer_name = machine_name; >+ a.in.negotiate_flags = &in_negotiate_flags; >+ a.out.negotiate_flags = &out_negotiate_flags; >+ a.in.credentials = &credentials3; >+ a.out.return_credentials = &credentials3; >+ >+ creds = netlogon_creds_client_init(tctx, a.in.account_name, >+ a.in.computer_name, >+ a.in.secure_channel_type, >+ &credentials1, &credentials2, >+ mach_password, &credentials3, >+ in_negotiate_flags); >+ >+ torture_assert(tctx, creds != NULL, "memory allocation"); >+ >+ torture_comment(tctx, "Testing ServerAuthenticate2\n"); >+ >+ torture_assert_ntstatus_ok( >+ tctx, >+ dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a), >+ "ServerAuthenticate2 failed"); >+ torture_assert_ntstatus_equal( >+ tctx, >+ a.out.result, >+ NT_STATUS_OK, >+ "ServerAuthenticate2 unexpected"); >+ >+ return true; >+} >+ > /* > try a change password for our machine account > */ >@@ -4954,6 +5273,22 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx) > torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon); > torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade); > >+ torture_rpc_tcase_add_test_creds( >+ tcase, >+ "ServerReqChallenge", >+ test_ServerReqChallenge); >+ torture_rpc_tcase_add_test_creds( >+ tcase, >+ "ServerReqChallenge_zero_challenge", >+ test_ServerReqChallenge_zero_challenge); >+ torture_rpc_tcase_add_test_creds( >+ tcase, >+ "ServerReqChallenge_5_repeats", >+ test_ServerReqChallenge_5_repeats); >+ torture_rpc_tcase_add_test_creds( >+ tcase, >+ "ServerReqChallenge_4_repeats", >+ test_ServerReqChallenge_4_repeats); > return suite; > } > >-- >2.20.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
metze
:
review+
metze
:
ci-passed+
Actions:
View
Attachments on
bug 14497
:
16228
|
16229
|
16230
|
16231
|
16232
|
16233
|
16234
|
16235
|
16236
|
16237
|
16238
|
16239
|
16240
|
16241
|
16242
|
16243
|
16244
| 16245 |
16246
|
16247
|
16248
|
16249
|
16250
|
16251
|
16268
|
16269