[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#9141) Side channel vulnerability at password check
- To: openldap-its@OpenLDAP.org
- Subject: (ITS#9141) Side channel vulnerability at password check
- From: scf@ieee.org
- Date: Thu, 12 Dec 2019 13:21:05 +0000
- Auto-submitted: auto-generated (OpenLDAP-ITS)
Full_Name: Shou C
Version: 2.4.48
OS:
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (98.185.228.137)
Here is the implementation of lutil_memcmp at /libraries/liblutil/memcmp.c
int
(lutil_memcmp)(const void *v1, const void *v2, size_t n)
{
if (n != 0) {
const unsigned char *s1=v1, *s2=v2;
do {
if (*s1++ != *s2++) return *--s1 - *--s2; // immediate return after
difference
} while (--n != 0);
}
return 0;
}
Later, it is redefined as memcpy.
Then this function is used in the password checking function to compare user
password and inputed password. This would lead to a timing attack / side channel
attack.
Here are all usages related to comparison of plaintext password
/libraries/liblutil/passwd.c: 341
if( is_allowed_scheme("{CLEARTEXT}", schemes ) ) {
return ( passwd->bv_len == cred->bv_len ) ?
memcmp( passwd->bv_val, cred->bv_val, passwd->bv_len )
: 1;
}
Here are all usages related to comparison of hashed password (although this is
less exploitable, by bruteforcing based on hash value, with enough time,
attacker could still recover the password):
/contrib/slapd-modules/passwd/sha2/slapd-sha2.c:262
rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
/contrib/slapd-modules/passwd/sha2/slapd-sha2.c:303
rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
/contrib/slapd-modules/passwd/sha2/slapd-sha2.c:350
rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
/contrib/slapd-modules/passwd/sha2/slapd-sha2.c:391
rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
/contrib/slapd-modules/passwd/sha2/slapd-sha2.c:438
rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
/contrib/slapd-modules/passwd/sha2/slapd-sha2.c:479
rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
/libraries/liblutil/passwd.c: 526
rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
/libraries/liblutil/passwd.c: 567
rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
/libraries/liblutil/passwd.c: 613
rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
/libraries/liblutil/passwd.c: 654
rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
/libraries/liblutil/passwd.c: 894
return memcmp( PasswordHash, storedPasswordHash, 32) ? LUTIL_PASSWD_ERR :
LUTIL_PASSWD_OK;
etc..
A safer implementation is:
int
(lutil_safe_memcmp)(const void *v1, const void *v2, size_t n)
{
int c=0;
if (n != 0) {
const unsigned char *s1=v1, *s2=v2;
do {
if (*s1++ != *s2++ && c == 0) c += *--s1 - *--s2;
} while (--n != 0);
}
return c;
}