DataRecovery Stage ESIEA

From CGSecurity
Jump to navigation Jump to search

Le stage est encadré par Christophe GRENIER et Robert ERRA

Les etudiants

  • BENYEKHLEF Mohamed (convention de stage invalidée)
  • BLANC Gregory
  • BOUFFARD Fabien
  • CHAARAOUI Hicham
  • EL FILALI Karim
  • HASSANI Amine (début de stage: semaine du 3 juillet)
  • VALLEE Igor

Stage

Semaine du 5 juin

Jeudi 8 juin, présentation du projet par Christophe

Semaine du 12 juin

  • Installation et configuration des machines
  • Prise en main de PhotoRec (analyse du code, ...)
  • Premiers tests avec Photorec
  • Recherche de formats à ajouter

Semaine du 19 juin

  • Prise en main de Foremost
  • Comparaison des outils : Photorec et Foremost
  • Recherches sur le format OLE à travers la bibliothèque, la maigre documentation présente sur le web et hexedit
  • Listing des outils concurrents
  • Etude de l'extension .png et des différents chunks

Vendredi 23 juin: Départ de Robert pour le Canada

Semaine du 26 juin

Vendredi 30: RDV de 8h30 à midi avec Christophe
Présents: Gregory, Fabien, Karim, Igor

  • Découverte de nouveaux documents sur le format OLE
  • Division de l'équipe sur deux tâches principales :
    • l'étude du format OLE (étude du header, calcul de la taille, simulation,...)
    • le bruteforce pour retrouver un maximum de fichiers (JPEG pour l'instant)

Christophe est intervenu en fin de semaine pour recadrer les recherches et a développé un début d'application pour le calcul de la taille des fichiers OLE en s'inspirant des méthodes utilisées dans Foremost, méthodes qui restent obscures sur certains points (fib, retrait de 5*512 octets ...).

Semaine du 3 juillet

Bonjour tout le monde! Robert.
Lundi 3: Un nouveau stagiaire a rejoint l'équipe: Amine.
Mardi 4: Envoi par Christophe d'une nouvelle version du programme développé jeudi pour gérer les documents OLE ajoutant la gestion du champ header->num_FAT_blocks.
TODO:

  • affiner la récupération de la taille

Parfois Root Entry et 1Table occupe le même bloc de départ, cela fausse parfois le calcul. => gérer la miniFAT ?

  • gérer header->num_extra_FAT_blocks

Mercredi 5: RDV de 8h30 à midi avec Christophe
Présents: Gregory, Fabien, Karim, Igor

  • traduction en francais de la documentation de TestDisk.
  • gestion plus poussée de la taille des fichiers ole (résultat de 16/18 fichiers doc).
  • optimisation de la méthode de calcul.
  • intégration de la méthode de calcul dans photorec.

=> le fichier f45964.doc est trouvé avec une taille correcte entre 45964-46103.

Semaine du 10 juillet

Jeudi 13: RDV de 8h à 9h20 avec Christophe
Présents: Gregory, Fabien, Karim, Igor

Lundi : La méthode de calcul nous permet d'affiner la recherche des fichiers ole :

Fichier    | Secteurs    | Précédemment | Objectif     | Commentaire 

f2051.doc  | 2051-3741   | 2051-3867    | ??           | taille erronée.

f7964.doc  | 7964-8284   | 7964-8284    | 7964-8284    | gestion d'un fragment supplémentaire, taille erronée
           | 9474-10028  |    ---       | 9474-10031   | à 4 secteurs près, fichier lisible.

f32837.doc | 32837-33396 | 32837-34287  | 32837-33397  | taille erronée à 1 secteur près (erreur de calcul)

f34288.doc |     (*)     | 34288-34306  | 34288-34306  | 
                                        | 34413-36236  |

f36998.doc | 36998-40243 | 36998-40637  | 36998-37649  |
                                        | 37727-39427  | 
                                        | 39477-40380  |

f45964.doc | 45964-46103 | 45964-46909  | 45964-46103  | taille correcte, fichier complet.

f45566.jpg | 45566-45963 | 45566-45963  | 45566-45963  | un des 5 fichiers jpg corrompu est retrouvé 
           | 46104-46826 |              | 46104-46826  | correctement

(*) :  
34288-34306 34432-34432 34440-34440 34484-34484 34488-34491 34493-34493
34495-34498 34500-34500 34502-34504 34506-34506 34510-34511 34513-34515
34518-34520 34523-34526 34528-34532 34534-34537 34539-34539 34541-34549 
34551-34553 34556-34556 34558-34560 34562-34563 34565-34566 34568-34572
34574-34574 34577-34584 34600-34600 34602-34602 34605-34605 34607-34609
34619-34620 34624-34624 34633-34634 34638-34638 34641-34641 34672-34673
34676-36291 36641-36757

Jeudi : Nous avons développé un nouveau calcul de taille de fichier OLE basé sur la documentation d'OpenOffice.

Fichier    | Secteurs    | Précédemment | Objectif     | Commentaire 
                             (Lundi)
f2051.doc  | 2051-3843   | 2051-3741    | ??           | taille erronée.

f7964.doc  | 7964-8284   | 7964-8284    | 7964-8284    | fichier complet OK
           | 9474-10031  | 9474-10028   | 9474-10031   | 

f32837.doc | 32837-33397 | 32837-33396  | 32837-33397  | fichier complet OK

f34288.doc |     (*)     |     (**)     | 34288-34306  | des fichiers .txt sont détectés en premiere pass,
                                        | 34413-36236  | ainsi f34288.doc est la concaténation des secteurs
                                                         libres compris entre les fichiers txt.

f36998.doc | 36998-40326 | 36998-40243  | 36998-37649  | 
                                        | 37727-39427  | 
                                        | 39477-40380  |

f45964.doc | 45964-46103 | 45964-46103  | 45964-46103  | fichier complet OK

f45566.jpg | 45566-45963 | 45566-45963  | 45566-45963  | un des 5 fichiers jpg corrompu est retrouvé 
           | 46104-46826 | 46104-46826  | 46104-46826  | correctement

(*) :  
34288-34306 34432-34432 34440-34440 34484-34484 34488-34491 34493-34493
34495-34498 34500-34500 34502-34504 34506-34506 34510-34511 34513-34515
34518-34520 34523-34526 34528-34532 34534-34537 34539-34539 34541-34549 
34551-34553 34556-34556 34558-34560 34562-34563 34565-34566 34568-34572
34574-34574 34577-34584 34600-34600 34602-34602 34605-34605 34607-34609
34619-34620 34624-34624 34633-34634 34638-34638 34641-34641 34672-34673
34676-36291 36641-36838 différence sur le dernier bloc de secteurs!
(**) :  
34288-34306 34432-34432 34440-34440 34484-34484 34488-34491 34493-34493
34495-34498 34500-34500 34502-34504 34506-34506 34510-34511 34513-34515
34518-34520 34523-34526 34528-34532 34534-34537 34539-34539 34541-34549 
34551-34553 34556-34556 34558-34560 34562-34563 34565-34566 34568-34572
34574-34574 34577-34584 34600-34600 34602-34602 34605-34605 34607-34609
34619-34620 34624-34624 34633-34634 34638-34638 34641-34641 34672-34673
34676-36291 36641-36757

Semaine du 17 juillet

Jeudi 20: RDV de 8h à 9h20 avec Christophe
Présents: Gregory, Fabien, Igor

Suite à la réunion du jeudi, nous avons défini avec Christophe le fonctionnement du bruteforce et les fonctions et structures à implémenter. Par ailleurs, les structures et fonctions vont servir par la suite à modifier radicalement le fonctionnement de PhotoRec. Le bruteforce va se baser sur une liste d'espaces libres (ou plutôt non affectées à la récupération d'un fichier). Cette liste peut être une suite d'espaces mémoire compris entre 2 headers JPEG par exemple. Le but est de parcourir et supprimer les espaces mémoire entraînant une erreur sur le test de la bibliothèque JPEG. Au final, on obtient une suite d'espaces mémoire qui, accolés au premier header JPEG, valide le test JPEG : nous récupérons alors un fichier JPEG. Les espaces mémoire utilisés dans la récupération du fichier JPEG sont ensuite retirés de la liste des espaces dit "libres". La liste est doublement chaînée et comporte les informations suivantes :

  • start: secteur de début du bloc d'espaces mémoire
  • end: secteur de fin
  • ext2: booléen qui indique si le bloc est de type ext2/ext3 (auquel cas il est ignoré dans la

récupération du fichier)

  • file_stat: informations sur la récupération du fichier
typedef struct struct_alloc_list t_alloc_list;

struct struct_alloc_list
{
  short int ext2;
  uint64_t start;
  uint64_t end;
  t_alloc_data *prev;
  t_alloc_data *next;
  t_file_stat *file_stat;
}

Cette liste est inclus dans l'objet file_recovery (qui récupére justement les blocs d'un fichier):

struct file_recovery_struct
{
  t_file_stat *file_stat;
  FILE *handle;
  char filename[2048];
  uint64_t header_distance;
  uint64_t file_size;
  uint64_t file_size_on_disk;
  uint64_t start;
  t_alloc_list sector_list;
};

Pour ajouter des blocs dans cette liste, Gregory a développé une fonction : add_block_list(t_alloc_list* list_block,uint64_t block,int ext2). La fonction prend en paramètre la liste, le numéro du bloc à ajouter et un booléen qui indique s'il est de type ext2/ext3 ou non. Auquel cas, lors de l'ajout, le bloc ext2 sera isolé des autres blocs. Par exemple, la liste peut ressembler à ce qui suit:

0             11|12       12|13            20
[blocs non ext2]|[bloc ext2]|[blocs non ext2]

Pour modifier la liste de l'espace libre une fois que l'on a identifié un fichier , Igor a redéveloppé la fonction : update_free_space(t_alloc_list *list_free_space, t_alloc_list *list_file_rec). La fonction prend en paramètre la liste de secteur libre et la liste des secteurs occupés par le fichier retrouvé. Exemple de fonctionnement :

                               AVANT
liste de secteur libre           | liste des secteurs occupés
[0 - 100] [150 - 200]            | [50 - 100] [150 - 170]

                               APRES
liste de secteur libre           | liste des secteurs occupés
[0 -  49] [171 - 200]            | [50 - 100] [150 - 170] 


Et enfin, parmis les différentes fonctions à implémenter, Fabien a développé la fonction truncate_fs() qui permet de retirer les secteurs non utilisés de la liste, ainsi qu'une fonction qui calcule la taille réelle occupée par le fichier.

Pour cela, truncate_fs() prend en paramètre la liste correspondant au fichier et la taille du fichier, il suffit donc de parcourir la liste et de libérer les éléments n'appartenant pas au fichier. La fonction get_file_size (les noms seraient peut être à revoir) exclut les secteurs correspondant à ext2.


Exemple de fonctionnement :

[0-10] [11-11] [12-41]
data    ext2    data

la taille sera donc de la forme : 
taille=((10-0+1)+(41-12+1))x Blocksize

Si nous avons alloué une liste allant de 0 à 150 et que la taille du fichier n'est que de 140,
 truncate_fs( t_alloc_list * list-file,uint64_t taille) retirera la partie en trop.

Semaine du 24 juillet

Mardi 25 juillet: Retour de Robert du Canada

Questions

  • concernant le test de validite des headers, photorec parcourt-il le bloc jusqu'a trouver des caracteres permettant d'identifier une extension ou compare-t-il directement le debut du bloc avec les nombreux headers repertories dans l'application ?
    Uniquement le début du bloc car un fichier commence au début d'un secteur.
  • concernant l'identification des extensions, foremost s'appuie a la fois sur un header et un footer. Serait-il interessant d'ajouter les footers de foremost a la recherche ?
    Les footers peuvent être recherchés par la fonction data_check ou file_check. C'est le cas pour les fichiers zip et jpeg par exemple.

PhotoRec et ses concurents

Foremost

Très rapide mais ne gère pas les fichiers fragmentés Comparaison avec TestDisk: https://www.cgsecurity.org/Articles/2006_06_SSTIC_photorec.pdf

Formats de fichier

Formats de fichiers qu'il faudrait récupérer

Format OLE

Ce format de fichier est utilisé pour les documents Office.

Format PNG

en etudiant plus profondement les .png, nous avons decouvert plusieurs chunks dont un chunk permettant de designer la fin de l'image "IEND". Certains chunks sont plutot interessant comme le pHYS qui doit etre, nous supposons, suivi de la taille de l'image, en tout cas, c'est ce qu'il designe. Nous pourrions ainsi connaitre la taille du fichier. Par ailleurs, dans la fragmentation, il serait interessant de rechercher des fichiers comportant le chunk IEND, nous permettant ainsi d'identifier un fragment final.

Gestion de la fragmentation

Toujours concernant la fragmentation, les blocs non reconnus etant de moins en moins nombreux au fur et à mesure des passes, serait-il interessant d'implementer un traitement plus lourd qui permettent de combiner des fichiers corrompus dont le header est reconnu avec des fichiers comportant des footers valides dans un premier temps, puis des blocs de type inconnu dans un deuxieme temps ? L'utilisateur pourra activer cette fonctionnalite a sa guise.
Très bonne idée que l'on pourrait appliquer aux jpeg.
Considérons que le bon fichier est J1 J2 J3 J4 J5 et que PhotoRec teste le fichier J1 J2 J3 B1 B2 B3 J4 J5. Si par exemple le test de la lib jpeg échoue en B2, on sait que le bloc B2 ne fait pas partie de l'image ou bien qu'il y a une erreur dans les blocs précédents.
Hypothèse: le fichier est en 2 fragments.
Le processus de récupération peut tester
J1 J2 J3 B1 B3 J4 J5
J1 J2 J3 B1 J4 J5
J1 J2 J3 B1 J5
J1 J2 J3 B2 B3 J4 J5
J1 J2 J3 B3 J4 J5
J1 J2 J3 J4 J5 <= Bingo