Wright dans l'ombre

Il s'agit d'une histoire sur l'une des tùches que nous avons préparées pour la phase de qualification CTFZone , qui s'est tenue fin novembre. Vous pouvez en savoir plus sur le processus de préparation à la qualification ici .

Vous commencez avec deux fichiers: decrypt_flag.py et ntfs_volume.raw. Jetons un coup d'Ɠil au script. Il ouvre un fichier nommĂ© key.bin, puis, Ă  l'aide d'une boucle, il essaie de prendre une chaĂźne binaire de 34 octets Ă  partir de chaque dĂ©calage Ă  l'intĂ©rieur du fichier, qui est ensuite utilisĂ©e comme entrĂ©e pour la fonction PBKDF2. Chaque clĂ© retournĂ©e est utilisĂ©e comme clĂ© XOR pour dĂ©chiffrer la chaĂźne chiffrĂ©e cousue dans le code. Si son hachage MD5 dĂ©chiffrĂ© correspond Ă  la valeur prĂ©dĂ©terminĂ©e sous une forme dĂ©chiffrĂ©e, le script utilise les donnĂ©es reçues pour gĂ©nĂ©rer et imprimer le drapeau.

Vous devez donc trouver le fichier key.bin. Il est impossible de trier simplement tous les décalages à l'intérieur du fichier image (ntfs_volume.raw), car le processus de recherche de la clé sera trop lent. Ce n'est pas interdit par les rÚgles, mais vous n'aurez certainement pas le temps avant la fin du CTF.

Le fichier image contient une table de partition MBR à partition unique. Son décalage est de 2048 secteurs de 512 octets, et il contient le systÚme de fichiers NTFS, mais le fichier key.bin n'est pas là:

$ fls -o 2048 -r -p ntfs_volume.raw | grep -F key.bin | wc –l
0

NTFS stocke les noms de fichiers codés UTF-16LE. Essayons de chercher dedans!


RĂ©sultats de la recherche pour les enregistrements de fichiers

AprÚs avoir étudié les résultats de la recherche, nous nous concentrons sur les enregistrements de fichiers qui commencent par la signature FILE [1]. Voici la seule entrée de ce type:


Record trouvé

L'objectif est dĂ©jĂ  proche! Nous avons un dossier, mais nous avons besoin de donnĂ©es. Dans NTFS, ils sont stockĂ©s dans l'attribut $ DATA, qui peut ĂȘtre rĂ©sident ou non-rĂ©sident [2]. Pour l'enregistrement que nous avons trouvĂ©, cet attribut commence Ă  l'offset 0 × 3AADD00 et indique des donnĂ©es non rĂ©sidentes (cela signifie que les informations sont stockĂ©es en dehors de l'enregistrement de fichier).

Alors, oĂč sont exactement les donnĂ©es du fichier souhaitĂ©? Pour rĂ©pondre Ă  cette question, il est nĂ©cessaire de dĂ©coder les soi-disant paires de mappage, ou sĂ©ries de donnĂ©es (paires «longueur de bloc - dĂ©calage de bloc») [3]. Les exĂ©cutions de donnĂ©es du fichier souhaitĂ© sont les suivantes (notez le dĂ©calage 0 × 3AADD40): 22 53 01 A0 4E 21 05 31 C1 11 38 30 00. Ou, si nous les rĂ©organisons:

1.	22 53 01 A0 4E
2.	21 05 31 C1
3.	11 38 30 00

Le fichier se compose de trois fragments, la taille du premier est de 339 clusters, et il commence par le cluster # 20128. Pour notre code utilisant PBKDF2, cet extrait est volumineux. Comme indiquĂ© dans l'en-tĂȘte du systĂšme de fichiers, la taille d'un cluster est de 4096 octets:

$ fsstat -o 2048 ntfs_volume.raw | grep 'Cluster Size'
Cluster Size: 4096

Jetons un coup d'Ɠil aux donnĂ©es pour ce dĂ©calage (en octets):
2048 * 512 + 20128 * 4096 = 83492864. Nous allons extraire toute quantité importante d'informations (par exemple, 128 octets) d'ici, l'insérer dans un nouveau fichier, que nous appellerons key.bin, exécuter le script ... Rien n'a réussi.

Peut-ĂȘtre que le fichier n'Ă©tait pas stockĂ© dans la version actuelle, mais dans la version prĂ©cĂ©dente du systĂšme de fichiers (formatage prĂ©cĂ©dent) - n'oubliez pas que nous n'avons pas vu l'enregistrement du fichier supprimĂ© du mĂȘme nom. Quelle Ă©tait la taille du cluster auparavant? Cherchons l'en-tĂȘte du systĂšme de fichiers avec la signature NTFS [4]. Peut-ĂȘtre que nous avons de la chance et que nous trouvons vraiment l'en-tĂȘte du formatage prĂ©cĂ©dent.


RĂ©sultats de la recherche pour l'en-tĂȘte du systĂšme de fichiers

Les premiĂšre et derniĂšre positions dans les rĂ©sultats de la recherche se rĂ©fĂšrent au systĂšme de fichiers actuel, mais les en-tĂȘtes du systĂšme de fichiers situĂ©s entre eux semblent appartenir Ă  la mise en forme prĂ©cĂ©dente. Et ils ont une taille de cluster diffĂ©rente!


En-tĂȘte du systĂšme de fichiers de la version prĂ©cĂ©dente.

Une telle taille de secteur est Ă©crite avec un dĂ©calage de 0 × 4554800B: 00 02 ou 512. Mais une telle taille de cluster est enregistrĂ©e avec un dĂ©calage de 0 × 0x4554800D: F7 ou 247.

Donc, nous avons la taille du cluster (en octets) 512 * 247 = 126464. Une sorte de non-sens! Si vous croyez l'analyseur NTFS [5], une telle valeur doit avoir un signe et ĂȘtre traitĂ©e d'une maniĂšre spĂ©ciale, donc la taille rĂ©elle du cluster (en secteurs) est 1 << - (- 9) = 512. Ou, si en octets, 512 * 512 = 262144 Semble maintenant plus crĂ©dible.

Les données commencent ici à ce décalage (en octets):
2048 * 512 + 20128 * 262144 = 5277483008. Essayons Ă  nouveau de faire la mĂȘme astuce avec les informations qui y sont stockĂ©es ... Encore une fois, un Ă©chec! Qu'est-ce qui ne va pas? Nous avons le FCT ici, cela signifie «pas si» que tout peut ĂȘtre.

La tùche sur laquelle nous nous battons s'appelle In the Shadows. Il est possible que cela ait quelque chose à voir avec les clichés instantanés du volume. Nous avons donc un fichier du systÚme de fichiers qui existait auparavant dans ce volume. Malheureusement, nous ne pouvons tout simplement pas prendre et monter son cliché instantané, mais nous connaissons le décalage exact auquel les données commencent! Il s'agit de 5277483008 ou, à l'intérieur de la section, 5277483008 - 2048 * 512 = 5276434432.

Selon les spécifications du format VSS [6], les blocs de données redirigés sont décrits dans la structure du descripteur de bloc contenant un champ 64 bits dans lequel le décalage d'origine (à l'intérieur du volume) est stocké, et également un champ de 64 bits décrivant le décalage du bloc cible (à l'intérieur du volume). Cherchons 5276434432 comme un petit nombre endian 64 bits.

Il n'y a que deux résultats dans les résultats, et un seul d'entre eux est situé à un décalage pair.


Descripteur de bloc trouvé

DĂ©calage du bloc cible: 00 00 9B 03 00 00 00 00, ou simplement 60489728. DĂ©calage final: 60489728 + 2048 * 512 = 61538304. À partir d'ici, exportez une certaine quantitĂ© de donnĂ©es vers un nouveau fichier nommĂ© key.bin, et ...

$ ./decrypt_flag.py
ctfzone{my_c0ngr4t5_t0_u,w311_d0n3_31337}

Terminé!

Références


  1. https://flatcap.org/linux-ntfs/ntfs/concepts/file_record.html
  2. https://flatcap.org/linux-ntfs/ntfs/attributes/data.html
  3. https://flatcap.org/linux-ntfs/ntfs/concepts/data_runs.html
  4. https://flatcap.org/linux-ntfs/ntfs/files/boot.html
  5. https://github.com/msuhanov/dfir_ntfs/blob/94bb46d6600153071b0c3c507ef37c42ad62110d/dfir_ntfs/BootSector.py#L58
  6. https://github.com/libyal/libvshadow/blob/master/documentation/Volume%20Shadow%20Snapshot%20(VSS)%20format.asciidoc#431-block-descriptor

Source: https://habr.com/ru/post/undefined/


All Articles