Given è la funzione compareKey
che è una parte di un crackme (un file binario). Quale attacco di canale laterale può essere utilizzato per trovare la password corretta (la password è composta da lettere grandi e piccole codificate ASCII da az e decimali) e come è possibile progettare questa funzione in modo tale che non ci siano canali laterali?
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;
}
Quindi ho già eseguito il crackme binario e inserito alcune password di diversa lunghezza. Mi sono reso conto che se la password ha lunghezza 7
, ha bisogno di più tempo per stampare Wrong
(password errata ..). Se la password ha una lunghezza diversa da 7
, stampa immediatamente Wrong
. Quindi la password è molto probabilmente di lunghezza 7
(lo è davvero!) E probabilmente abbiamo un attacco temporale qui perché vediamo dal codice precedente che le due stringhe keyInput
e correctKey
) vengono confrontati carattere per carattere e disallineamento di allerta quando vedono una differenza tra i due caratteri attualmente confrontati.
Questa è una corretta obiezione?
Possiamo correggere questo canale laterale in questo modo:
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
Va bene così non sono sicuro? : /