Jobs
From UIC
Contents |
Lavora con la UIC
-
Unpacker per Aspack 2.12assegnato.
Get a job with us
-
Unpacker for Aspack 2.12assigned.
Selezioni Febbraio 2007
Valutazione dei concorrenti per il coding di un unpacker per Aspack 2.12.
Task: sono stati dati due compiti:
- Un eseguibile volutamente compromesso, il compito era di astrarre dall'asm al C due delle routine utilizzate.
- Una struttura che rappresentava un header, il compito era quello di scrivere un programma per leggere le informazioni da un file che utilizzava questo header.
Il primo task è servito a valutare le capacità di astrazione del canditato, il secondo task è servito a valutare le qualità di problem-solving e la conoscenza di un linguaggio di programmazione.
All'ora stabilita come termine finale, sono giunte soltanto due soluzioni, i candidati sono stati:
- Pnluck
- ev0
Regole di valutazione
Reversing
6 punti ad ogni routine ben reversata, cosi' ripartiti:
- Codice correttamente convertito: 3 punti max
- Livello di astrazione: 3 punti max
Coding
9 punti cosi' ripartiti:
- Parsing corretto di un file standard: 3 punti max
- Parsing corretto di un file forgiato fuori dallo standard: 4 punti max
- Qualita' del codice e del coding-style: 2 punti max
- Crash del programma: -3 punti
Esame delle Soluzioni
L'eseguibile compilato fa uso di un semplice RC4, l'unica differenza dall'implementazione originale e' stata l'aggiunta di un IVInitialization Vector casuale accodato alla password. La password e' gia' presente nel file .exe, xorata con un valore di 0x12.
- Pass xorata: fwafpwv
- Pass decifrata: testbed
Tale password viene utilizzata per il l'inizializzazione della S-Box e per la cifratura di una stringa posta in chiaro all'interno del file: Welcome to UIC Testbed application. Il main() dell'applicazione e' il seguente:
char pass_xored[] = "fwafpwv";
for(i = 0; i < (int)strlen(pass_xored); i++)
pass_xored[i] ^= 0x12;
Init(pass_xored, strlen(pass_xored));
Crypt(welcome, out, 34);
La parte aggiunta all'RC4 e' la seguente:
....
key[len + 1] = (k & 0xFF000000) >> 24;
key[len + 2] = (k & 0x00FF0000) >> 16;
key[len + 3] = (k & 0x0000FF00) >> 8;
key[len + 4] = (k & 0x000000FF);
La parte di coding prevedeva invece la scrittura di un'applicazione che interpretasse il seguente header:
int size_of_header; // Size of header
int size_of_image; // Sizeof image, including this header
char number_of_sections; // Number of sections
unsigned short *sections_size; // Size in bytes of each section
int *sections_offset; // Start offset of each section
}
Pnluck
Reversing:
Nella routine Init() il codice e' stato convertito in maniera complessivamente corretta: 3 punti.
L'astrazione non e' invece delle migliori: 2 punti.
Nella routine Crypt() il codice e' corretto: 3 punti.
L'astrazione lascia un po' a desiderare, alcuni costrutti sono riportati nel loro equivalente assembly. Faccio notare che:
- shr eax, 10 --> variabile >>= 10
- and eax, 10 --> variabile &= 10
Il resto del codice e' un po' una cannibalizzazione del disassemblato piu' che una vera astrazione: 1 punto.
Coding:
Il codice dell'applicazione e' scritto bene e con eleganza:
- Un file corretto viene parsato bene
- Un file in cui una sezione sovrascrive l'header viene parsato bene
- Un file in cui due sezioni overlappato viene parsato bene
- Un file forgiato per generare un crash viene gestito bene
Il programma fa uso delle eccezioni del C++, ma era stato richiesto espressamente che venisse scritto in ANSI C. Vengono quindi assegnati: 8 punti
ev0
Reversing:
La routine di Init() e' stata convertita in maniera corretta, tuttavia c'e' un piccolo errore nell'implementazione di un loop: 2.5 punti
L'astrazione anche in questo caso non e' delle migliori, ma il codice e' un po' piu' chiaro di quello di Pnluck: 2.5 punti
La routine Crypt() e' stata implementata in maniera corretta, o meglio: il codice che esegue la cifratura e' corretto, ma c'e' un errore decisamente grave nella dichiarazione della chiamata che porta ad avere un bello stack overflow: 2 punti
L'astrazione anche qui non e' delle migliori, ma il codice e' meno cannibalizzato del precedente: 2 punti
Coding:
Il codice dell'applicazione e' un po' caotico, le variabili sono dichiarate un po' ovunque (e questo non e' consentito in ansi C):
- Un file corretto non viene parsato bene (c'e' un errore nel calcolo della correct_size)
- A prescindere dal precedente error, se una sezione va a trovarsi nell'header, il programma non se ne accorge
- Il programma non si accorge che una sezione overlappa su un'altra
- Correggendo il primo errore, il programma ha una buona resistenza ai file forgiati per farlo crashare.
Vengono assegnati: 2 punti per la tolleranza ai crash ed 1 punto al coding style perche' anche questo codice non e' ANSI C. A causa dell'errore nel calcolo della correct_size non vengono assegnati ulteriori punti :(
Risultati
Faccio i miei complimenti ad entrambi!!!