The branch, v4-13-stable has been updated via 09ef8ab5099 VERSION: Disable GIT_SNAPSHOT for the 4.13.0rc6 release. via de91bb3d467 WHATSNEW: Add release notes for Samba 4.13.0rc6. via 049388aeb94 WHATSNEW: document the planed removal of "server schannel" via ba279325b7a WHATSNEW: document the 'smb2 disable oplock break retry' option via e4dc8227ae1 CVE-2020-1472(ZeroLogon): s4 torture rpc: repeated bytes in client challenge via 7c88d85ca8c CVE-2020-1472(ZeroLogon): s4 torture rpc: Test empty machine acct pwd via e5c7800b096 CVE-2020-1472(ZeroLogon): docs-xml: document 'server require schannel:COMPUTERACCOUNT' via 6192153da9a CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: log warnings about unsecure configurations via b93e1dcd154 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: support "server require schannel:WORKSTATION$ = no" via 7ab19ec5a10 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: refactor dcesrv_netr_creds_server_step_check() via 32dd379f30a CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: log warnings about unsecure configurations via b6f91e77ef4 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: support "server require schannel:WORKSTATION$ = no" via befc2aca239 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: refactor dcesrv_netr_creds_server_step_check() via 6e8f1830382 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: protect netr_ServerPasswordSet2 against unencrypted passwords via 4ad58d61ba1 CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: Fix mem leak onto p->mem_ctx in error path of _netr_ServerPasswordSet2(). via ed94cb18f01 CVE-2020-1472(ZeroLogon): s4:rpc_server/netlogon: protect netr_ServerPasswordSet2 against unencrypted passwords via ba9110a17d7 CVE-2020-1472(ZeroLogon): libcli/auth: reject weak client challenges in netlogon_creds_server_init() via fdac15704f9 CVE-2020-1472(ZeroLogon): libcli/auth: add netlogon_creds_is_random_challenge() to avoid weak values via afa0ec41cbb CVE-2020-1472(ZeroLogon): s4:rpc_server:netlogon: make use of netlogon_creds_random_challenge() via 5f28e4f7473 CVE-2020-1472(ZeroLogon): s3:rpc_server:netlogon: make use of netlogon_creds_random_challenge() via acf80197316 CVE-2020-1472(ZeroLogon): libcli/auth: make use of netlogon_creds_random_challenge() in netlogon_creds_cli.c via 9d90cd2b509 CVE-2020-1472(ZeroLogon): s4:torture/rpc: make use of netlogon_creds_random_challenge() via b57b6004db8 CVE-2020-1472(ZeroLogon): libcli/auth: add netlogon_creds_random_challenge() via 45d4e546067 VERSION: Bump version up to 4.13.0rc5... from f5fd34cced9 VERSION: Disable GIT_SNAPSHOT for the 4.13.0rc5 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-13-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 103 +++++- docs-xml/smbdotconf/security/serverschannel.xml | 69 +++- libcli/auth/credentials.c | 44 ++- libcli/auth/netlogon_creds_cli.c | 3 +- libcli/auth/proto.h | 3 + libcli/auth/wscript_build | 2 +- source3/rpc_server/netlogon/srv_netlog_nt.c | 212 +++++++++++- source4/rpc_server/netlogon/dcerpc_netlogon.c | 175 +++++++++- source4/torture/rpc/lsa.c | 2 +- source4/torture/rpc/netlogon.c | 433 ++++++++++++++++++++---- 11 files changed, 928 insertions(+), 120 deletions(-) Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index 7f954aee9e0..88a9887726f 100644 --- a/VERSION +++ b/VERSION @@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=5 +SAMBA_VERSION_RC_RELEASE=6 ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 467d4c0dfc5..b103703144f 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,13 +1,66 @@ Release Announcements ===================== -This is the fifth release condidate of Samba 4.13. This is *not* +This is the sixth release condidate of Samba 4.13. This is *not* intended for production environments and is designed for testing purposes only. Please report any defects via the Samba bug reporting system at https://bugzilla.samba.org/. Samba 4.13 will be the next version of the Samba suite. +SECURITY +======== + +o CVE-2020-1472: Unauthenticated domain takeover via netlogon ("ZeroLogon"). + +The following applies to Samba used as domain controller only (most +seriously the Active Directory DC, but also the classic/NT4-style DC). + +Installations running Samba as a file server only are not directly +affected by this flaw, though they may need configuration changes to +continue to talk to domain controllers (see "file servers and domain +members" below). + +The netlogon protocol contains a flaw that allows an authentication +bypass. This was reported and patched by Microsoft as CVE-2020-1472. +Since the bug is a protocol level flaw, and Samba implements the +protocol, Samba is also vulnerable. + +However, since version 4.8 (released in March 2018), the default +behaviour of Samba has been to insist on a secure netlogon channel, +which is a sufficient fix against the known exploits. This default is +equivalent to having 'server schannel = yes' in the smb.conf. + +Therefore versions 4.8 and above are not vulnerable unless they have +the smb.conf lines 'server schannel = no' or 'server schannel = auto'. + +Samba versions 4.7 and below are vulnerable unless they have 'server +schannel = yes' in the smb.conf. + +Note each domain controller needs the correct settings in its smb.conf. + +Vendors supporting Samba 4.7 and below are advised to patch their +installations and packages to add this line to the [global] section if +their smb.conf file. + +The 'server schannel = yes' smb.conf line is equivalent to Microsoft's +'FullSecureChannelProtection=1' registry key, the introduction of +which we understand forms the core of Microsoft's fix. + +Some domains employ third-party software that will not work with a +'server schannel = yes'. For these cases patches are available that +allow specific machines to use insecure netlogon. For example, the +following smb.conf: + + server schannel = yes + server require schannel:triceratops$ = no + server require schannel:greywacke$ = no + +will allow only "triceratops$" and "greywacke$" to avoid schannel. + +More details can be found here: +https://www.samba.org/samba/security/CVE-2020-1472.html + UPGRADING ========= @@ -78,19 +131,47 @@ REMOVED FEATURES The deprecated "ldap ssl ads" smb.conf option has been removed. +The deprecated "server schannel" smb.conf option will very likely +removed in the final 4.13.0 release. + + smb.conf changes ================ - Parameter Name Description Default - -------------- ----------- ------- - ldap ssl ads removed - smb2 disable lock sequence checking No - domain logons Deprecated no - raw NTLMv2 auth Deprecated no - client plaintext auth Deprecated no - client NTLMv2 auth Deprecated yes - client lanman auth Deprecated no - client use spnego Deprecated yes + Parameter Name Description Default + -------------- ----------- ------- + ldap ssl ads Removed + smb2 disable lock sequence checking Added No + smb2 disable oplock break retry Added No + domain logons Deprecated no + raw NTLMv2 auth Deprecated no + client plaintext auth Deprecated no + client NTLMv2 auth Deprecated yes + client lanman auth Deprecated no + client use spnego Deprecated yes + server schannel To be removed in 4.13.0 + server require schannel:COMPUTER Added + + +CHANGES SINCE 4.13.0rc5 +======================= + +o Jeremy Allison <j...@samba.org> + * BUG 14497: CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: Protect + netr_ServerPasswordSet2 against unencrypted passwords. + +o Günther Deschner <g...@samba.org> + * BUG 14497: CVE-2020-1472(ZeroLogon): s3:rpc_server/netlogon: Support + "server require schannel:WORKSTATION$ = no" about unsecure configurations. + +o Gary Lockyer <g...@catalyst.net.nz> + * BUG 14497: CVE-2020-1472(ZeroLogon): s4 torture rpc: repeated bytes in + client challenge. + +o Stefan Metzmacher <me...@samba.org> + * BUG 14497: CVE-2020-1472(ZeroLogon): libcli/auth: Reject weak client + challenges in netlogon_creds_server_init() + "server require schannel:WORKSTATION$ = no". CHANGES SINCE 4.13.0rc4 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> diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c index c541eeff470..23339d98bfa 100644 --- a/libcli/auth/credentials.c +++ b/libcli/auth/credentials.c @@ -24,6 +24,7 @@ #include "system/time.h" #include "libcli/auth/libcli_auth.h" #include "../libcli/security/dom_sid.h" +#include "lib/util/util_str_escape.h" #ifndef HAVE_GNUTLS_AES_CFB8 #include "lib/crypto/aes.h" @@ -33,6 +34,33 @@ #include <gnutls/gnutls.h> #include <gnutls/crypto.h> +bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge) +{ + /* + * If none of the first 5 bytes of the client challenge is unique, the + * server MUST fail session-key negotiation without further processing + * of the following steps. + */ + + if (challenge->data[1] == challenge->data[0] && + challenge->data[2] == challenge->data[0] && + challenge->data[3] == challenge->data[0] && + challenge->data[4] == challenge->data[0]) + { + return false; + } + + return true; +} + +void netlogon_creds_random_challenge(struct netr_Credential *challenge) +{ + ZERO_STRUCTP(challenge); + while (!netlogon_creds_is_random_challenge(challenge)) { + generate_random_buffer(challenge->data, sizeof(challenge->data)); + } +} + static NTSTATUS netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, const struct netr_Credential *in, struct netr_Credential *out) @@ -677,7 +705,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); NTSTATUS status; - + bool ok; if (!creds) { return NULL; @@ -690,6 +718,20 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); + ok = netlogon_creds_is_random_challenge(client_challenge); + if (!ok) { + DBG_WARNING("CVE-2020-1472(ZeroLogon): " + "non-random client challenge rejected for " + "client_account[%s] client_computer_name[%s]\n", + log_escape(mem_ctx, client_account), + log_escape(mem_ctx, client_computer_name)); + dump_data(DBGLVL_WARNING, + client_challenge->data, + sizeof(client_challenge->data)); + talloc_free(creds); + return NULL; + } + creds->computer_name = talloc_strdup(creds, client_computer_name); if (!creds->computer_name) { talloc_free(creds); diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c index 407cb471cbc..12cb3149ff6 100644 --- a/libcli/auth/netlogon_creds_cli.c +++ b/libcli/auth/netlogon_creds_cli.c @@ -1177,8 +1177,7 @@ static void netlogon_creds_cli_auth_challenge_start(struct tevent_req *req) TALLOC_FREE(state->creds); - generate_random_buffer(state->client_challenge.data, - sizeof(state->client_challenge.data)); + netlogon_creds_random_challenge(&state->client_challenge); subreq = dcerpc_netr_ServerReqChallenge_send(state, state->ev, state->binding_handle, diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index 88f4a7c6c50..a62668f088f 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -13,6 +13,9 @@ /* The following definitions come from /home/jeremy/src/samba/git/master/source3/../source4/../libcli/auth/credentials.c */ +bool netlogon_creds_is_random_challenge(const struct netr_Credential *challenge); +void netlogon_creds_random_challenge(struct netr_Credential *challenge); + NTSTATUS netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); NTSTATUS netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, diff --git a/libcli/auth/wscript_build b/libcli/auth/wscript_build index 41937623630..2a6a7468e45 100644 --- a/libcli/auth/wscript_build +++ b/libcli/auth/wscript_build @@ -18,7 +18,7 @@ bld.SAMBA_SUBSYSTEM('NTLM_CHECK', bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH', source='credentials.c session.c smbencrypt.c smbdes.c', - public_deps='MSRPC_PARSE gnutls GNUTLS_HELPERS', + public_deps='MSRPC_PARSE gnutls GNUTLS_HELPERS util_str_escape', public_headers='credentials.h:domain_credentials.h' ) diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index 2a2e2d0ac6e..c217fee9c43 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; @@ -841,8 +842,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; @@ -1074,20 +1074,25 @@ 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; } - 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")); @@ -1096,9 +1101,97 @@ 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; + } + + /* + * 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; + 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)); + 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; } @@ -1345,9 +1438,14 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, -- Samba Shared Repository