The Samba-Bugzilla – Attachment 16242 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 v3 including tests for 4.10
CVE-2020-1472-ZeroLogon-v4-10-stable.patch (text/plain), 62.55 KB, created by
Andrew Bartlett
on 2020-09-18 05:27:59 UTC
(
hide
)
Description:
patch v3 including tests for 4.10
Filename:
MIME Type:
Creator:
Andrew Bartlett
Created:
2020-09-18 05:27:59 UTC
Size:
62.55 KB
patch
obsolete
>From 8f3743811dca0e08175d0d144e192f80646c25d8 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/18] 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 | 8 ++++++++ > libcli/auth/proto.h | 2 ++ > 2 files changed, 10 insertions(+) > >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index b6c8ba281ba..dbbef9e7a3c 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -26,9 +26,17 @@ > #include "libcli/auth/libcli_auth.h" > #include "../libcli/security/dom_sid.h" > >+ >+void netlogon_creds_random_challenge(struct netr_Credential *challenge) >+{ >+ ZERO_STRUCTP(challenge); >+ generate_random_buffer(challenge->data, sizeof(challenge->data)); >+} >+ > static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, > const struct netr_Credential *in, > struct netr_Credential *out) >+ > { > if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { > AES_KEY key; >diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h >index 82febe74440..82797d453ed 100644 >--- a/libcli/auth/proto.h >+++ b/libcli/auth/proto.h >@@ -11,6 +11,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); >+ > void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); > void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); > void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass); >-- >2.25.1 > > >From 6a9721a8a4ae603862e6c587709af8bc4780c97c 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/18] 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 21cc16afbaf..7bdc0cf679a 100644 >--- a/source4/torture/rpc/lsa.c >+++ b/source4/torture/rpc/lsa.c >@@ -2847,7 +2847,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 026d86d50e4..e11014922f8 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"); >@@ -318,7 +318,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"); >@@ -390,7 +390,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"); >@@ -1278,7 +1278,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"); >@@ -1367,7 +1367,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"); >@@ -1456,7 +1456,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"); >@@ -1546,7 +1546,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"); >@@ -1638,8 +1638,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"); >@@ -1651,7 +1650,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"); >@@ -1662,16 +1661,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"); >@@ -1747,7 +1737,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.25.1 > > >From 6c29cfd059201004e260c6607f52a41adcd08024 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/18] 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 817d2cd041a..0f6ca11ff96 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.25.1 > > >From e61eb0d263887f2eae88d4c4adca584749d253e9 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/18] 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 d799ba4feef..61169fff17b 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.25.1 > > >From 1c3d8f38cd6675e1e551a9efe69814335bce8552 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/18] 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 023adfd99e9..de260d8051d 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.25.1 > > >From 551f95eb138febef89fb7930e34497ad28df6632 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/18] 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 dbbef9e7a3c..64b424c099f 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -27,10 +27,31 @@ > #include "../libcli/security/dom_sid.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 void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, >diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h >index 82797d453ed..ad768682b9f 100644 >--- a/libcli/auth/proto.h >+++ b/libcli/auth/proto.h >@@ -11,6 +11,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); > > void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); >-- >2.25.1 > > >From 85470e040a15d035bf03e187a0a9db5b2063697c 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/18] 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 | 16 ++++++++++++++++ > libcli/auth/wscript_build | 2 +- > 2 files changed, 17 insertions(+), 1 deletion(-) > >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index 64b424c099f..e2bc82809b7 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -25,6 +25,7 @@ > #include "../lib/crypto/crypto.h" > #include "libcli/auth/libcli_auth.h" > #include "../libcli/security/dom_sid.h" >+#include "lib/util/util_str_escape.h" > > > bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge) >@@ -451,6 +452,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); >+ bool ok; > > if (!creds) { > return NULL; >@@ -463,6 +465,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 d319d9b879e..394505d166d 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', >+ public_deps='MSRPC_PARSE util_str_escape', > public_headers='credentials.h:domain_credentials.h' > ) > >-- >2.25.1 > > >From 2f740247f578d2d6941a004b5747a2b18ad06e44 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/18] 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 de260d8051d..acbf077c6c7 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -722,7 +722,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; > >@@ -780,6 +783,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.25.1 > > >From 0a2c46505b05968e7c094b6c9e1877f061226996 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 16 Sep 2020 12:53:50 -0700 >Subject: [PATCH 09/18] 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 61169fff17b..989770bd0ae 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -1326,9 +1326,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, >@@ -1364,18 +1369,99 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, > netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); > } > >- 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.25.1 > > >From b8faeb148a9087cff8e868da7db52360e0a37bb3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 10:18:45 +0200 >Subject: [PATCH 10/18] 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 acbf077c6c7..b4326a4ecaa 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -623,26 +623,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.25.1 > > >From 22660062db569d121e7393fb2c69893a26dad0d7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 10:56:53 +0200 >Subject: [PATCH 11/18] 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 b4326a4ecaa..e7bafb31e83 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -623,6 +623,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; >@@ -645,7 +646,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.25.1 > > >From 728b548eb4ac0bce84a7f0806827d5aff4b533c0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 17 Sep 2020 13:37:26 +0200 >Subject: [PATCH 12/18] 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 e7bafb31e83..7668a9eb923 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -624,10 +624,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; >@@ -646,11 +648,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) { >@@ -664,11 +673,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.25.1 > > >From 81b8f19476c64661d93cd3f1b967fe4d67ec2bc4 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 13/18] 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 989770bd0ae..50455ee4bce 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -48,6 +48,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.25.1 > > >From ecdec5e9c7357902fd13eb8255f41a7d8837c21a 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 14/18] 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 50455ee4bce..28381405ebd 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.25.1 > > >From 975dfab9a8a22fe1fc62903c624e02323719ca1d 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 15/18] 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 28381405ebd..c36c247c55c 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.25.1 > > >From 3aa55ed5c036ea49cfcb086dd36ae79aef622e62 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 17 Sep 2020 17:27:54 +0200 >Subject: [PATCH 16/18] 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.25.1 > > >From 6d4957aaed200f537a09a9b4760da3ae7b5c8f7f 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 17/18] 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 e11014922f8..0ba45f0c1da 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -719,45 +719,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.25.1 > > >From f01b2f6bb2c4c6de2e8cd26e73090d29c55c07c2 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 18/18] 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 | 333 +++++++++++++++++++++++++++++++++ > 1 file changed, 333 insertions(+) > >diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c >index 0ba45f0c1da..e0968e10f05 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -480,6 +480,323 @@ 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 fail pass, 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 > */ >@@ -4949,6 +5266,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.25.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
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