1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

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>
This commit is contained in:
Stefan Metzmacher 2020-09-16 19:20:25 +02:00
parent d3123858fb
commit d8a6e6549c

View File

@ -726,7 +726,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;
@ -792,6 +795,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,