Given is the function compareKey
which is a part of a crackme (a binary file). Which side-channel attack can be used to find the right password (password is made up by ASCII coded big and small letters from a-z, and decimals) and how can you design this function such that there isn't any side-channel?
int compareKey() {
unsigned int leng = strleng(keyInput);
unsigned int correctLeng = strleng(correctKey);
int i, randomTime, falseKey = 0;
unsigned int seed = getpid() + keyInput[0];
srand(seed); // initialize the random seed
if (leng != correctLeng)
return 1;
for (i = correctLeng-1; i >= 0; i--) {
if (keyInput[i] != correctKey[i]) {
usleep(500000); // that delay will stop bruteforce attack
falseKey = 1;
}
}
randomTime = 500000 * (rand() % 3);
usleep(randomTime); // take that
// and this will prevent the attacker to perform a timed attack
return falseKey;
}
So I have already executed the crackme binary and entered some passwords of different length. I realized that if the password has length 7
, it needs waaay more time to print Wrong
(wrong password..). If the password has any other length than 7
, it immediately prints Wrong
. Thus the password is most likely of length 7
(it indeed is!) and we probably have a timing attack here because we see from the above code that the two strings keyInput
and correctKey
) are compared character by character and alert mismatch when they see a difference between the two characters that are currently being compared.
Is this correct obersvation so far?
We can fix this side-channel like this:
def secureCompare(stringA, stringB) :
if (sha256(A) == sha256(B))
return True
else
return False
OR
def secureCompare(stringA, stringB) :
if leng(A) != leng(B):
return False
result = 0
for x, y in zip(A, B) :
result |= x ^ y
return result == 0
Is it alright like that I'm really not sure? : /