Zoom Icon

Algoritmo WipeWay

From UIC

Creare un algoritmo Wipe-Way

Contents


Infos
Author: Quequero
Email: Image:Que addr.gif
Website: http://quequero.org
Date: 01/01/2001 (dd/mm/yyyy)
Level: Working brain required
Language: Italian Image:Flag_Italian.gif
Comments: Questo tutorial ha molti anni, tuttavia rappresenta una base ragionevole per implementare un semplice algoritmo di wiping. Per maggiori dettagli leggete i paper di Guttman



Introduzione

Updated: 19/Jan/2007
Lo so che non conoscete gli algoritmi wipe-way ma è ora di presentarli :): servono a cancellare in maniera indelebile un file


Tools

Tasm


Essay

Salve a tutti, quest'oggi impareremo a creare un algoritmo di cifratura wipe-way, in realtà il termine mi è venuto in mente stanotte, ma facciamo un brevissima digressione e vediamo che tipi di algoritmi esistono:

  1. Two-way: prendo un documento A, lo critto ed ottengo B, se poi passo B sotto un filtro riottengo A, e questo mi sembra abbastanza immediato, cifratura-decifratura
  2. One-way: prendo A, lo critto ottenendo B, e poi ci serve dio per riottenere A... In sostanza una volta crittato A non riotterrete mai l'originale, perché l'informazione di partenza è persa per sempre.

L'utilizzo del primo è piuttosto evidente, il secondo potrebbe non esserlo altrettanto. A cosa ci serve un algoritmo che, a partire da una serie di dati, ci torna una serie quasi-random di numeri? Beh se l'algoritmo è progettato bene, e la serie quasi-random di numeri è univoca per un grande numero di possibili combinazioni in ingresso, allora si che diventa utile! Pensate alle password, inserirle in un database in chiaro non è un'operazione intelligente, perché se il database viene rubato, le pass vengono immediatamente esposte. Se invece le diamo in pasto ad un algoritmo di hashing, possiamo ottenere un'impronta univoca della password che però non ci rivela la password stessa. A quel punto in fase di autenticazione l'utente inserisce la pass, il sistema la cifra con il suo algoritmo di hash e controlla i due hash, quello nel db e quello generato dall'input dell'utente, il risultato? Se i due hash sono uguali allora anche le pass (quasi)sicuramente saranno uguali. In questo modo possiamo effettuare un confronto diretto per verificare l'uguaglianza di due sistemi di dati, senza dover aver i dati in chiaro. Furba come idea vero? È ovvio che l'algoritmo deve presentare il minor numero di collisioniCioe' a due input differenti deve rispondere con due output differenti possibili, ma non dobbiamo aspettarci miracoli. Un algoritmo che in output genera un hash di 128 bit (l'MD5 ad esempio), può rappresentare 2^128 stati differenti, per cui una stringa di 200 bit (che può assumere 2^200 stati differenti) potrebbe in taluni casi generare una collisione. Ed infatti recentemente sono stati sviluppati degli attacchi molto efficaci contro MD4 e MD5. Noi sfrutteremo in parte gli algoritmi di hashing in modo da utilizzarli per cifrare un file prima di cancellarlo, in modo da effettuare un wiping, ovvero una rimozione completa del dato dal disco. Tutto ciò che cercheremo di fare sarà semplicemente di generare una stringa abbastanza casuale ed utilizzarla per cifrare i dati, ripetendo l'operazione più volte, con stringhe diverse, riusciremo ad eliminare il dato dal disco con ragionevole sicurezza.
Qui sotto vi presento l'algoritmo e non tutto un intero programma, il resto lo potete adattare secondo le vostre esigenze, la mia unica supposizione è che nel buffer: "buffer", siano contenuti i byte di una eventuale password o di un eventuale file, vi spiegherò approfonditamente il funzionamento dell'algoritmo alla fine:

Random1 dd 5809172h ; DOVETE settarli al valore che volete!!!
Random2 dd 0005371h ; DOVETE settarli al valore che volete!!!

.code
<b>START:</b>
xor ecx, ecx

<b>algo:</b>
mov eax, <em>Random1</em>
mul <em>Random2</em>
inc eax
mov ebx, dword ptr[buffer+ecx]
ror ebx, 4
shl ebx, 2
xor ebx, eax
ror ebx, 4
shr ebx, 8
xor ebx, eax
call GetTickCount
xor ebx, eax
mov eax, ebx
mul <em>Random1</em>
xor ebx, eax
call GetTickCount
xor ebx, eax
mul <em>Random2</em>
xor ebx, eax
call GetTickCount
ror eax, 3
shr eax, 4
mov edx, eax
push edx
call GetTickCount
pop edx
add eax, edx
xor eax, edx
xor ebx, eax
mov dword ptr[buffer+ecx], ebx
add ecx, 4
 ; Qua ci dovete aggiungere un check per vedere se la pass o i byte nel
 ; buffer sono finiti

jmp <b>algo</b>

Eccomi, non vi preoccupate, vi commento tutto adesso: all'inizio del codice ECX viene azzerato perché usato come contatore, poi ci sono queste istruzioni:

mov eax, Random1
mul Random2
inc eax

che servono a piazzare un numero casuale in EAX, si tratta di un semplice algoritmo per la generazione di un numero pseudo-casuale, poi:

mov ebx, dword ptr[buffer+ecx]
ror ebx, 4
shl ebx, 2
xor ebx, eax
ror ebx, 4
shr ebx, 8
xor ebx, eax

vengono mossi in ebx i primi 4 byte della password, o del file, vengono rotati a destra di 4, shiftati a sinistra di 2 e poi vengono xorati con il valore casuale che si trovava in EAX. Il risultato viene di nuovo rotato a destra di 4 shiftato a sinistra di 8 e poi di nuovo xorato con EAX:

call GetTickCount
xor ebx, eax
mov eax, ebx
mul Random1
xor ebx, eax
call GetTickCount
xor ebx, eax
mul Random2
xor ebx, eax
call GetTickCount
ror eax, 3
shr eax, 4
mov edx, eax
push edx

ed adesso viene chiamata l'API GetTickCount che riporta in EAX i millisecondi da quando Windows è stato avviato (questa chiamata viene utilizzata per riempire un entropy-pool, la sua funzione è quella di acquisire dati _random_ da parte del sistema), i byte vengono quindi xorati con questo valore, EAX viene poi ancora randomizzata con il primo algoritmo, ed i byte vengono ancora xorati con questo valore random, viene chiamata di nuovo GetTickCount e quindi i byte vengono ancora xorati con EAX che viene di nuovo randomizzata, e usata per xorare ancora i byte. Poi GetTickCount viene ancora chiamato, ma il risultato stavolta viene randomizzato tramite dei ror e degli shift, quello che ne esce fuori viene messo in EDX che viene poi salvato:

call GetTickCount
pop edx
add eax, edx
xor eax, edx
xor ebx, eax
mov dword ptr[buffer+ecx], ebx
add ecx, 4
;Qui va il test
jmp algo

viene chiamata per l'ultima volta GetTickCount, viene ripreso il valore che stava in EDX e viene sommato a quello riportato da GetTickCount, la somma di questi valori viene quindi xorata con EDX ed il risultato xora poi i nostri cari byte che vengono rimessi a posto, il contatore viene incrementato di una DWORD e si ricomincia il loop finché il file non è finito. Dunque come facciamo a sapere se questo algoritmo è sicuro? Se ogni dword viene cifrata almeno 10/15 volte, l'algoritmo nella sua semplicità è comunque abbastanza sicuro. L'unico problema è la casualita', su un computer ottenere un dato random è davvero difficile, GetTickCount ci da una mano. Per star tranquilli diciamo che l'attaccante dovrebbe sapere con esattezza il valore ritornato da GetTickCount, tuttavia se in casa non siamo spiati, o se il nostro computer non è compromesso, allora di certo non basterà l'undelete per recuperare i dati :).

Ciauz e buona crittazione da Quequero

Mi raccomando non vi crittate l'hard disk :)


Disclaimer

Quequero vi invita a non cifrare il disco con questo algoritmo :), se lo fate ve ne assumete la responsabilità :).