Se da la función compareKey
, que forma parte de un crackme (un archivo binario). ¿Qué ataque de canal lateral se puede usar para encontrar la contraseña correcta (la contraseña está formada por letras grandes y pequeñas codificadas en ASCII de az, y decimales) y cómo se puede diseñar esta función para que no haya ningún canal lateral? / p>
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;
}
Así que ya ejecuté el binario crackme e ingresé algunas contraseñas de diferente longitud. Me di cuenta de que si la contraseña tiene una longitud 7
, se necesita más tiempo para imprimir Wrong
(contraseña incorrecta ..). Si la contraseña tiene una longitud diferente a 7
, se imprime inmediatamente Wrong
. Por lo tanto, es más probable que la contraseña tenga una longitud 7
(¡de hecho lo es!) Y probablemente tengamos un ataque de tiempo aquí porque vemos en el código anterior que las dos cadenas keyInput
y correctKey
) se comparan carácter por carácter y discrepancia de alerta cuando ven una diferencia entre los dos caracteres que se están comparando actualmente.
¿Esta es la respuesta correcta hasta ahora?
Podemos arreglar este canal lateral de esta manera:
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
¿Está bien así que realmente no estoy seguro? : /