The Samba-Bugzilla – Attachment 16268 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]
Backport for V4.4
CVE-2020-1472-V4-5.patch (text/plain), 48.88 KB, created by
Gary Lockyer
on 2020-10-02 01:42:38 UTC
(
hide
)
Description:
Backport for V4.4
Filename:
MIME Type:
Creator:
Gary Lockyer
Created:
2020-10-02 01:42:38 UTC
Size:
48.88 KB
patch
obsolete
>From adf80f43dc75dae20532b72750e478bed1a24396 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(backported from commit b813cdcac377210c3ab18e0d0a0c1a76870b1d74) >--- > libcli/auth/credentials.c | 6 ++++++ > libcli/auth/proto.h | 1 + > 2 files changed, 7 insertions(+) > >diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c >index 91f37b770c6..c7062b014d6 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -26,6 +26,12 @@ > #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) >diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h >index a03f45ed7f3..2f51708e465 100644 >--- a/libcli/auth/proto.h >+++ b/libcli/auth/proto.h >@@ -18,6 +18,7 @@ void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, st > void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); > void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); > void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); >+void netlogon_creds_random_challenge(struct netr_Credential *challenge); > > /***************************************************************** > The above functions are common to the client and server interface >-- >2.17.1 > > >From 33ab6ea41a4759b6fca97047b22cb190b75512f7 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(backported from commit 355efadc6a18ffaaef2e4786e35e89780b10bccc) >--- > source4/torture/rpc/lsa.c | 2 +- > source4/torture/rpc/netlogon.c | 8 ++++---- > 2 files changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c >index fa884fb17ee..7e6ed89a660 100644 >--- a/source4/torture/rpc/lsa.c >+++ b/source4/torture/rpc/lsa.c >@@ -2833,7 +2833,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 c8e864d00a7..836d5349d88 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -158,7 +158,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"); >@@ -227,7 +227,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"); >@@ -314,7 +314,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"); >@@ -1183,7 +1183,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"); >-- >2.17.1 > > >From d2d8af4bce7bc89a310e2ee609a23de9423932f8 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 46642fd32d91b008615b859cfdf946f63b1ca0aa) >--- > 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 29baae40524..1f6e900b30b 100644 >--- a/libcli/auth/netlogon_creds_cli.c >+++ b/libcli/auth/netlogon_creds_cli.c >@@ -1098,8 +1098,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.17.1 > > >From 9325831243da185527a58525d7c7c40826683535 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit caba2d8082d4b038aa59954b6e812612c2ecc0e1) >--- > 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 176769f3bbe..c21174a6af8 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -836,8 +836,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.17.1 > > >From ed9c6a7a42dd2e5eef280bb28ee114e058af5e76 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 74eb448adf7fb638fe925eab87a2dbfe9c002cc0) >--- > 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 73ac8741012..e85ffeb8c0b 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -97,8 +97,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.17.1 > > >From a106b76f3ce0f8f65bde5eaeb7d62531ed0f2b21 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(backported from commit 53528c71ffdb3377c4e73ac596c8507bc3898e83) >--- > 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 c7062b014d6..e866c9de0f1 100644 >--- a/libcli/auth/credentials.c >+++ b/libcli/auth/credentials.c >@@ -26,10 +26,31 @@ > #include "libcli/auth/libcli_auth.h" > #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 2f51708e465..d7d333b2df2 100644 >--- a/libcli/auth/proto.h >+++ b/libcli/auth/proto.h >@@ -18,6 +18,7 @@ void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, st > void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); > void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); > void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); >+bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge); > void netlogon_creds_random_challenge(struct netr_Credential *challenge); > > /***************************************************************** >-- >2.17.1 > > >From b2155274ca34f1f526f6fcd14211d5ec9dc6f465 Mon Sep 17 00:00:00 2001 >From: Gary Lockyer <gary@catalyst.net.nz> >Date: Wed, 1 Mar 2017 11:10:29 +1300 >Subject: [PATCH 07/12] lib/util: Add functions to escape log lines but not > break all non-ascii > >We do not want to turn every non-ascii username into a pile of hex, so we instead focus >on avoding newline insertion attacks and other low control chars > >Pair-programmed-by: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >(backported from commit eacb5aead71299b6bebbddbaf7c9a3d545f9151b) >--- > lib/util/tests/util_str_escape.c | 90 ++++++++++++++++++++ > lib/util/util_str_escape.c | 126 ++++++++++++++++++++++++++++ > lib/util/util_str_escape.h | 27 ++++++ > lib/util/wscript_build | 5 ++ > source4/torture/local/local.c | 1 + > source4/torture/local/wscript_build | 3 +- > 6 files changed, 251 insertions(+), 1 deletion(-) > create mode 100644 lib/util/tests/util_str_escape.c > create mode 100644 lib/util/util_str_escape.c > create mode 100644 lib/util/util_str_escape.h > >diff --git a/lib/util/tests/util_str_escape.c b/lib/util/tests/util_str_escape.c >new file mode 100644 >index 00000000000..82e2209ef55 >--- /dev/null >+++ b/lib/util/tests/util_str_escape.c >@@ -0,0 +1,90 @@ >+/* >+ >+ util_str_escape testing >+ >+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017 >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include "torture/torture.h" >+#include "torture/local/proto.h" >+#include "lib/util/util_str_escape.h" >+ >+static bool test_log_escape_empty_string(struct torture_context *tctx) >+{ >+ char *result = log_escape( tctx, ""); >+ torture_assert_str_equal(tctx, result, "", "Empty string handling"); >+ return true; >+} >+ >+static bool test_log_escape_null_string(struct torture_context *tctx) >+{ >+ char *result = log_escape( tctx, NULL); >+ torture_assert(tctx, (result == NULL), "Empty string handling"); >+ return true; >+} >+ >+static bool test_log_escape_plain_string(struct torture_context *tctx) >+{ >+ const char *input = "a plain string with no escapable characters"; >+ const char *expected = "a plain string with no escapable characters"; >+ >+ char *result = log_escape( tctx, input); >+ torture_assert_str_equal(tctx, result, expected, >+ "Plain string handling"); >+ return true; >+} >+ >+static bool test_log_escape_string(struct torture_context *tctx) >+{ >+ const char *input = "\a\b\f\n\r\t\v\\\x01"; >+ const char *expected = "\\a\\b\\f\\n\\r\\t\\v\\\\\\x01"; >+ >+ char *result = log_escape( tctx, input); >+ torture_assert_str_equal(tctx, result, expected, >+ "Escapable characters in string"); >+ return true; >+} >+ >+static bool test_log_escape_hex_string(struct torture_context *tctx) >+{ >+ const char *input = "\x01\x1F "; >+ const char *expected = "\\x01\\x1F "; >+ >+ char *result = log_escape( tctx, input); >+ torture_assert_str_equal(tctx, result, expected, >+ "hex escaping"); >+ return true; >+} >+struct torture_suite *torture_local_util_str_escape(TALLOC_CTX *mem_ctx) >+{ >+ struct torture_suite *suite = torture_suite_create(mem_ctx, >+ "util_str_escape"); >+ >+ torture_suite_add_simple_test(suite, "log_escape_empty_string", >+ test_log_escape_empty_string); >+ torture_suite_add_simple_test(suite, "log_escape_null_string", >+ test_log_escape_null_string); >+ torture_suite_add_simple_test(suite, "log_escape_plain_string", >+ test_log_escape_plain_string); >+ torture_suite_add_simple_test(suite, "log_escape_string", >+ test_log_escape_string); >+ torture_suite_add_simple_test(suite, "log_escape_hex_string", >+ test_log_escape_hex_string); >+ >+ >+ return suite; >+} >diff --git a/lib/util/util_str_escape.c b/lib/util/util_str_escape.c >new file mode 100644 >index 00000000000..93cdd8de4a8 >--- /dev/null >+++ b/lib/util/util_str_escape.c >@@ -0,0 +1,126 @@ >+/* >+ Samba string escaping routines >+ >+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017 >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include "lib/util/util_str_escape.h" >+ >+ >+/* >+ * Calculate the encoded length of a character for log_escape >+ * >+ */ >+static size_t encoded_length(char c) >+{ >+ if (c != '\\' && c > 0x1F) { >+ return 1; >+ } else { >+ switch (c) { >+ case '\a': >+ case '\b': >+ case '\f': >+ case '\n': >+ case '\r': >+ case '\t': >+ case '\v': >+ case '\\': >+ return 2; /* C escape sequence */ >+ default: >+ return 4; /* hex escape \xhh */ >+ } >+ } >+} >+ >+/* >+ * Escape any control characters in the inputs to prevent them from >+ * interfering with the log output. >+ */ >+char *log_escape(TALLOC_CTX *frame, const char *in) >+{ >+ size_t size = 0; /* Space to allocate for the escaped data */ >+ char *encoded = NULL; /* The encoded string */ >+ const char *c; >+ char *e; >+ >+ if (in == NULL) { >+ return NULL; >+ } >+ >+ /* Calculate the size required for the escaped array */ >+ c = in; >+ while (*c) { >+ size += encoded_length( *c); >+ c++; >+ } >+ size++; >+ >+ encoded = talloc_array( frame, char, size); >+ if (encoded == NULL) { >+ DBG_ERR( "Out of memory allocating encoded string"); >+ return NULL; >+ } >+ >+ c = in; >+ e = encoded; >+ while (*c) { >+ if (*c != '\\' && *c > 0x1F) { >+ *e++ = *c++; >+ } else { >+ switch (*c) { >+ case '\a': >+ *e++ = '\\'; >+ *e++ = 'a'; >+ break; >+ case '\b': >+ *e++ = '\\'; >+ *e++ = 'b'; >+ break; >+ case '\f': >+ *e++ = '\\'; >+ *e++ = 'f'; >+ break; >+ case '\n': >+ *e++ = '\\'; >+ *e++ = 'n'; >+ break; >+ case '\r': >+ *e++ = '\\'; >+ *e++ = 'r'; >+ break; >+ case '\t': >+ *e++ = '\\'; >+ *e++ = 't'; >+ break; >+ case '\v': >+ *e++ = '\\'; >+ *e++ = 'v'; >+ break; >+ case '\\': >+ *e++ = '\\'; >+ *e++ = '\\'; >+ break; >+ default: >+ snprintf(e, 5, "\\x%02X", *c); >+ e += 4; >+ } >+ c++; >+ } >+ } >+ *e = '\0'; >+ return encoded; >+} >diff --git a/lib/util/util_str_escape.h b/lib/util/util_str_escape.h >new file mode 100644 >index 00000000000..0b4c5964c14 >--- /dev/null >+++ b/lib/util/util_str_escape.h >@@ -0,0 +1,27 @@ >+/* >+ Samba string escaping routines >+ >+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017 >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#ifndef _SAMBA_UTIL_STR_ESCAPE_H >+#define _SAMBA_UTIL_STR_ESCAPE_H >+ >+#include <talloc.h> >+ >+char *log_escape(TALLOC_CTX *frame, const char *in); >+ >+#endif >diff --git a/lib/util/wscript_build b/lib/util/wscript_build >index 6d2ab4ac27f..8ae61849538 100755 >--- a/lib/util/wscript_build >+++ b/lib/util/wscript_build >@@ -199,3 +199,8 @@ else: > deps='talloc tdb strv util_tdb tdb-wrap samba-util', > local_include=False, > private_library=True) >+ >+ bld.SAMBA_SUBSYSTEM('util_str_escape', >+ source='util_str_escape.c', >+ deps='talloc', >+ local_include=False) >diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c >index 6641f211cff..89066c5f52f 100644 >--- a/source4/torture/local/local.c >+++ b/source4/torture/local/local.c >@@ -74,6 +74,7 @@ > torture_local_verif_trailer, > torture_local_nss, > torture_local_fsrvp, >+ torture_local_util_str_escape, > NULL > }; > >diff --git a/source4/torture/local/wscript_build b/source4/torture/local/wscript_build >index 3a12b6bcd27..c8e8fde63fc 100644 >--- a/source4/torture/local/wscript_build >+++ b/source4/torture/local/wscript_build >@@ -20,11 +20,12 @@ TORTURE_LOCAL_SOURCE = '''../../../lib/util/charset/tests/iconv.c > ../../../lib/util/tests/strv.c > ../../../lib/util/tests/strv_util.c > ../../../lib/util/tests/util.c >+ ../../../lib/util/tests/util_str_escape.c > verif_trailer.c > nss_tests.c > fsrvp_state.c''' > >-TORTURE_LOCAL_DEPS = 'RPC_NDR_ECHO TDR LIBCLI_SMB MESSAGING iconv POPT_CREDENTIALS TORTURE_AUTH TORTURE_UTIL TORTURE_NDR TORTURE_LIBCRYPTO share torture_registry PROVISION ldb samdb replace-test RPC_FSS_STATE' >+TORTURE_LOCAL_DEPS = 'RPC_NDR_ECHO TDR LIBCLI_SMB MESSAGING iconv POPT_CREDENTIALS TORTURE_AUTH TORTURE_UTIL TORTURE_NDR TORTURE_LIBCRYPTO share torture_registry PROVISION ldb samdb replace-test RPC_FSS_STATE util_str_escape' > > bld.SAMBA_MODULE('TORTURE_LOCAL', > source=TORTURE_LOCAL_SOURCE, >-- >2.17.1 > > >From 54fa223b5106f2c84fd8ac74e14d4f9a3882740b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 16:17:29 +0200 >Subject: [PATCH 08/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(backported from commit d3123858fb59046e826cf2c7ec2a3839e6508624) >--- > 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 e866c9de0f1..52750153056 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) > { >@@ -452,6 +453,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; >@@ -464,6 +466,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 475b7d69406..fad60a9c5a7 100755 >--- 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.17.1 > > >From fc1a57e2d019183e736cc4e32ae207164ffc3f1e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 16 Sep 2020 19:20:25 +0200 >Subject: [PATCH 09/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit d8a6e6549c185daa26852d6d85f475cddfb3083a) >--- > 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 e85ffeb8c0b..1fa93dd3ae0 100644 >--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c >+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c >@@ -664,7 +664,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; > >@@ -717,6 +720,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.17.1 > > >From a996f1c177f9feb406a6e9c4cc466a8c77c38a44 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/12] 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> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(backported from commit 82d41977a8bef426396e3e00833d55711a55f372) >needed to add definition of struct _samr_Credentials_t >--- > source3/rpc_server/netlogon/srv_netlog_nt.c | 110 +++++++++++++++++++- > 1 file changed, 107 insertions(+), 3 deletions(-) > >diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c >index c21174a6af8..3d0eb84bf27 100644 >--- a/source3/rpc_server/netlogon/srv_netlog_nt.c >+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c >@@ -1140,6 +1140,17 @@ static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p, > /************************************************************************* > *************************************************************************/ > >+struct _samr_Credentials_t { >+ enum { >+ CRED_TYPE_NT_HASH, >+ CRED_TYPE_PLAIN_TEXT, >+ } cred_type; >+ union { >+ struct samr_Password *nt_hash; >+ const char *password; >+ } creds; >+}; >+ > static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx, > struct auth_session_info *session_info, > struct messaging_context *msg_ctx, >@@ -1324,9 +1335,15 @@ 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_Password nt_hash; >+ struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}}; >+ bool ok; > > become_root(); > status = netr_creds_server_step_check(p, p->mem_ctx, >@@ -1358,13 +1375,100 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, > netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); > } > >- if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &plaintext)) { >+ 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; > } > >- mdfour(nt_hash.hash, plaintext.data, plaintext.length); >+ /* >+ * 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; >+ } >+ >+ mdfour(nt_hash.hash, plaintext.data, plaintext.length); > status = netr_set_machine_account_password(p->mem_ctx, > p->session_info, > p->msg_ctx, >-- >2.17.1 > > >From 063ac1947c9ab39778e78f204bb6a395138c9cf8 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 11/12] 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> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 4b262b03e1e8285c399338895832a115953d3f23) >--- > 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 836d5349d88..221459fa165 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -627,45 +627,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.17.1 > > >From 7c28870320163c255487932cc4fcc70d728fa5ed 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 12/12] 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> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Fri Sep 18 14:13:17 UTC 2020 on sn-devel-184 > >(Backported from commit 9945f3e3548657c33cc2e5ef97eedd1dfe2edf71) >--- > source4/torture/rpc/netlogon.c | 336 +++++++++++++++++++++++++++++++++ > 1 file changed, 336 insertions(+) > >diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c >index 221459fa165..4edae5b7200 100644 >--- a/source4/torture/rpc/netlogon.c >+++ b/source4/torture/rpc/netlogon.c >@@ -388,6 +388,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 > */ >@@ -4165,6 +4484,23 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx) > torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES); > torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation); > >+ 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.17.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:
gary
:
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