Как восстановить файлы в NTFS с помощью PowerShell

Восстановить файлы NTFS PowerShell

Файловая система NTFS, используемая в операционных системах Windows, сохраняет информацию об удаленных файлах до тех пор, пока блоки диска, на которых они находились, не будут перезаписаны новыми данными. Это позволяет восстанавливать случайно удаленные файлы при помощи различных утилит. В статье рассмотрим способы восстановления удаленных файлов в NTFS при помощи PowerShell.

Еще по теме: Восстановление NTFS используя Scrounge-NTFS Linux

Как восстановить файлы в NTFS с помощью PowerShell

Можно выделить 2 спо­соба уда­ления фай­лов в ОС Windows:

  • уда­ление с помощью сис­темных инструментов del (Shift Del) или erase;
  • уда­ление через кор­зину.

Способы отличаются механиз­мом уда­ления и рядом отличий во время вос­ста­нов­лении удаленных фай­лов.

Ни­ког­да не вос­ста­нав­ливайте уда­лен­ные фай­лы на тот же том, с которо­го они были ранее уда­лены. Для этого лучше исполь­зовать другой носитель.

В начале рассмотрим вос­ста­нов­лени­е нерези­ден­тных фай­лов, а потом поговорим про вос­ста­нов­ление резиден­тных.

Восстановление удаленных файлов с использованием del или erase

Для восстановления удаленных файлов будем использовать модуль PowerShell инструмента PowerForensics. Данный модуль предлагает коман­дле­ты для NTFS и FAT. Умеет работать с сис­темны­ми фай­лами Windows. Может пар­сить атри­буты фай­лов NTFS и кон­верти­ровать мет­ки вре­мени пред­став­ляя их в челове­кочи­таемом виде (что необ­ходимо в компьютерной криминалистике). Под­робную информацию можно узнать из опи­сания.

Начнем с установки модуля (PowerShell необходимо запус­тить от име­ни адми­нис­тра­тора):

Про­верим установку выпол­нив коман­длет:

Ус­танов­ка модуля PowerForensics

Ус­танов­ка модуля PowerShell завер­шена, теперь попробуем найти все уда­лен­ные фай­лы. В глав­ной фай­ловой таб­лице они име­ют флаг уда­ления 00h по сме­щению 16 байт от начала фай­ловой записи.

Для создания тома F запус­каем diskmgmt.msc, а после сжи­маем име­ющий­ся том и выделяем под него нового 5 Гб с раз­мером клас­тера по умолчанию 4096 Кбайт). Положим туда файл, например calc.exe и попробуем уда­лить его через erase (что равносильно удалению через del или Shift-Del).

Те­перь чтобы найти уда­лен­ный фай­ла на томе F выполним коман­дле­т Get-ForensicsFileRecord и отфиль­тру­ем выдачу по фла­гу True для атри­бута Deleted:

По­луче­ние уда­лен­ных фай­лов на томе F

Здесь мы видим основные фай­ловые атри­буты и их зна­чения, одна­ко для вос­ста­нов­ления нам пот­ребу­ется зна­чение фай­ловой записи RecordNumber. Пос­ле того как файл будет най­ден, для даль­нейших дей­ствий луч­ше поль­зовать­ся номером фай­ловой записи, так как имя фай­ла может изме­нять­ся в про­цес­се уда­ления (далее мы раз­берем этот слу­чай).

Имея номер фай­ловой записи, мы смо­жем отыс­кать недос­тающие эле­мен­ты, если файл нерези­ден­тный, и соб­рать его воеди­но по кусоч­кам, пос­ле чего записать содер­жимое в новый файл.

Для это­го запишем в перемен­ную $file_record объ­ект фай­ла со свой­ства­ми (атри­бута­ми фай­ла):

Те­перь можно обра­тить­ся к отдель­ному атри­буту и узнать инте­ресу­ющую нас информа­цию. Для вос­ста­нов­ления нуж­но опре­делить номер началь­ного клас­тера и общее количес­тво занима­емых фай­лом клас­теров. Для это­го в перемен­ную $file_descriptor запишем содер­жимое атри­бута $DATA:

Пос­ле чего можно получить зна­чения началь­ного клас­тера и количес­тва клас­теров, которые занима­ет наш файл. В перемен­ную $start_cluster сох­раним эти дан­ные:

На рисун­ке спра­ва видим содер­жимое этой перемен­ной в кон­соли PowerShell, а сле­ва — атри­бут $Data с его полями для нашего уда­лен­ного фай­ла.

На­чаль­ный клас­тер и количес­тво исполь­зуемых клас­теров

Те­перь дело за малым: нуж­но записать содер­жимое по «адре­су» выше (номер началь­ного клас­тера и количес­тво клас­теров) в вос­ста­нов­ленный файл на томе.

Бу­дем записы­вать на том С:, что­бы не затереть уда­лен­ные дан­ные на томе F:. Мож­но выпол­нить запись при помощи коман­дле­та Invoke-ForensicDD из модуля PowerForensics или исполь­зовать WriteAllBytes из биб­лиоте­ки System.IO.File:

Здесь мы ука­зыва­ем в парамет­ре InFile том и рас­положе­ние фай­ла, который будет ско­пиро­ван (в нашем слу­чае это том F и рас­положе­ние уда­лен­ного фай­ла).

В качес­тве сме­щения на дис­ке ука­зыва­ем адрес началь­ного клас­тера, умно­жен­ный на 4096, и количес­тво клас­теров, так­же умно­жен­ных на 4096, ведь раз­мер клас­тера на нашем томе равен 4096 Кбайт.

Пос­ле чего ука­зыва­ем количес­тво фай­лов на дис­ке и путь с име­нем фай­ла, куда будет вос­ста­нов­лен наш файл.

В резуль­тате мы получа­ем наш рабочий каль­кулятор в кор­не тома C:\calc.exe.

Вос­ста­нов­ление каль­кулято­ра

Вот толь­ко есть одно но: нес­мотря на то что каль­кулятор запус­кает­ся и работа­ет без нарека­ний, хеш‑сум­мы ори­гиналь­ного фай­ла (до уда­ления) и фай­ла пос­ле вос­ста­нов­ления не бьют­ся…

Восстановить файлы NTFS PowerShell

При­чина тому — раз­ница в раз­мере фай­ла пос­ле вос­ста­нов­ления. Раз­мер фай­ла до уда­ления равен 27 648 байт, а пос­ле вос­ста­нов­ления — 28 672 (что при делении на 4096 дает нам 7 — те самые семь клас­теров в сум­ме). То есть при вос­ста­нов­лении мы забот­ливо дозапи­сали нулями 1024 байт, это нуж­но и важ­но учи­тывать при получе­нии ори­гиналь­ного фай­ла.

Зна­чения реаль­ного раз­мера фай­ла (RealSize=27 648) и выделен­ного под хра­нение фай­ла прос­транс­тва (AllocationSize=28 672) хра­нят­ся в атри­буте $DATA. Вся информа­ция у нас на руках, давайте наведем кра­соту. Для это­го, преж­де чем сох­ранить содер­жимое клас­теров в файл, запишем мас­сив бай­тов в перемен­ную $bytearray:

Пос­ле чего, исполь­зуя фун­кцию WriteAllBytes сис­темной биб­лиоте­ки System.IO.File, запишем содер­жимое в файл, ука­зав вер­хнюю гра­ницу мас­сива для записи [0..($bytearray.Length - (1024 + 1))]:

Те­перь пос­чита­ем хеш‑сум­мы и срав­ним получен­ные зна­чения.

За­пись в файл

Как и ожи­далось, хеш‑сум­мы бьют­ся, зна­чит, пос­ле вос­ста­нов­ления содер­жимое фай­ла изме­нено не было. Если с вос­ста­нов­лени­ем уда­лен­ных с исполь­зовани­ем del (Shift-Del) или erase фай­лов все понят­но, то что про­исхо­дит в сис­теме, ког­да вы переме­щаете файл в кор­зину?

Восстановление удаленных файлов через корзину

Сра­зу сле­дует отме­тить, что переме­щение фай­ла в кор­зину не рав­но уда­лению: файл уда­ляет­ся пос­ле очис­тки кор­зины (хоть это и оче­вид­но, тем не менее упо­мянуть об этом сто­ит).

Пос­ле переме­щения фай­ла в кор­зину в дирек­тории C:\$Recycle.Bin\<Users SID>\ соз­дает­ся два фай­ла c име­нами, которые начина­ются с $I и $R и закан­чива­ются ори­гиналь­ным рас­ширени­ем переме­щен­ного в кор­зину фай­ла. Даже с отоб­ражени­ем скры­тых фай­лов в дирек­тории нам не удас­тся пос­мотреть на соз­данные пос­ле переме­щения в кор­зину фай­лы.

Что­бы до них доб­рать­ся, содер­жимое дирек­тории C:\$Recycle.Bin\<Users SID>\ нуж­но перемес­тить в спе­циаль­но соз­данную для иссле­дова­ния дирек­торию (мож­но вос­поль­зовать­ся PowerShell-коман­дле­том Copy-Item). Пос­ле переме­щения нам ста­нут дос­тупны сле­дующие фай­лы:

(далее — $I) — файл с метадан­ными, соз­дает­ся, как толь­ко файл переме­щает­ся в кор­зину. Он исполь­зует­ся для вос­ста­нов­ления фай­ла из кор­зины средс­тва­ми Microsoft, под­робнее раз­бор фай­ла будет при­веден ниже.

(далее — $R) — файл, который соз­дает­ся пос­ле переме­щения в кор­зину. Это копия переме­щен­ного в кор­зину фай­ла, о чем говорят оди­нако­вое содер­жимое и хеш‑сум­мы (если срав­нить ори­гинал до уда­ления и переме­щен­ный файл). Изме­няет­ся толь­ко имя фай­ла.

Пос­ле переме­щения фай­ла в кор­зину

Раз­бор содер­жимого популяр­ных фай­лов и фай­ловых записей, а так­же струк­тур таб­лиц MFT, MBR, GPT и фай­ловых атри­бутов встре­чает­ся в пуб­ликаци­ях на GitHub. Одна­ко мне не уда­лось най­ти опи­сание фай­ла $I с метадан­ными, поэто­му давайте вмес­те раз­берем­ся, что полез­ного мож­но обна­ружить в таком фай­ле.

В роли подопыт­ного будет по‑преж­нему выс­тупать файл calc.exe. Перемес­тим его копию в кор­зину, пос­ле чего ско­пиру­ем все содер­жимое из дирек­тории C:\$Recycle.Bin\<Users SID>\* в пап­ку для иссле­дова­ния.

Ни­же пред­став­лен раз­бор всех полей фай­ла $IOWX1VN.exe (был соз­дан при переме­щении каль­кулято­ра в кор­зину).

Восстановить NTFS PowerShell

Здесь:

  • жел­тый цвет — File Header, заголо­вок фай­ла $I;
  • си­ний цвет — File Size (Bytes) — раз­мер фай­ла;
  • крас­ный цвет — атри­бут $SI ChangedTime — вре­мя уда­ления, точ­нее, переме­щения фай­ла в кор­зину в фор­мате UTC;
  • би­рюзо­вый цвет — FileName Length — раз­мер име­ни фай­ла в бай­тах;
  • пур­пурный цвет — File Path — пол­ный путь до фай­ла, который был уда­лен (переме­щен в кор­зину).

У каж­дого поль­зовате­ля своя $Recycle.Bin (кор­зина). Более того, на каж­дом томе такая кор­зина соз­дает­ся по умол­чанию. Гру­бо говоря, кор­зина из тома С проб­расыва­ется в том F и дру­гие соз­данные тома.

Поэто­му перед име­нем уда­лен­ного фай­ла мы видим SID поль­зовате­ля — зачас­тую это полез­ная информа­ция о том, какой поль­зователь в сис­теме перемес­тил файл в кор­зину и выпол­нил уда­ление. Нап­ример, для фай­ла calc.exe пол­ное имя фай­ла будет выг­лядеть так:

или

Кро­ме информа­ции о том, кто уда­лил файл, мы получа­ем информа­цию о мет­ках вре­мени и о момен­те, ког­да файл был переме­щен в кор­зину. Так­же нам ста­новит­ся известен путь, по которо­му хра­нил­ся файл до переме­щения.

Те­перь давайте погово­рим о вос­ста­нов­лении фай­ла, который был уда­лен через кор­зину. По алго­рит­му оно похоже на вос­ста­нов­ление фай­лов, уда­лен­ных с помощью del или erase, пос­коль­ку для фай­ловой сис­темы нет раз­ницы меж­ду фай­лами, уда­лен­ными из кор­зины или какой‑либо дру­гой дирек­тории. По сути, сис­тема уда­ляет фай­лы так же, как при при­мене­нии ути­лит del или erase, толь­ко пред­варитель­но пере­име­новав фай­лы в

Ве­роят­но, у вас воз­ник впол­не логич­ный воп­рос: какой из двух фай­лов вос­ста­нав­ливать — $I или $R? Ведь при очис­тке кор­зины уда­лят­ся оба эти фай­ла и их записи какое‑то вре­мя будут хра­нить­ся в $mft (до переза­писи дру­гими дан­ными).

Для вос­ста­нов­ления уда­лен­ного фай­ла нам нуж­ны оба: и $R, и $I. Файл $R тре­бует­ся для вос­ста­нов­ления содер­жимого, а файл $I — для получе­ния ори­гиналь­ного име­ни фай­ла.

Единс­твен­ный недос­тающий эле­мент при вос­ста­нов­лении — ори­гиналь­ное имя, которое мож­но отыс­кать толь­ко в фай­ле $I. Но файл $I резиден­тный, а это зна­чит, что приш­ло вре­мя разоб­рать­ся, как вос­ста­нав­ливать резиден­тные фай­лы.

Для начала мы так­же най­дем ID фай­ловой записи для фай­ла $I:

Пос­ле чего обра­тим­ся к атри­буту $DATA по ука­зан­ному ID и запишем содер­жимое атри­бута в мас­сив бай­тов:

В $Byte_Array хра­нит­ся содер­жимое резиден­тно­го фай­ла.

Струк­туру фай­ла $I мы уже разоб­рали и пом­ним, что бай­ты с 0 до 26 отво­дят­ся на фай­ловый заголо­вок, раз­мер фай­ла в бай­тах, атри­бут $SI Changed Time и раз­мер фай­лового име­ни. А начиная с индекса 27 до кон­ца фай­ла хра­нит­ся пол­ное имя фай­ла (путь + имя). Зная эту информа­цию, мы можем получить недос­тающий эле­мент для вос­ста­нов­ления нашего каль­кулято­ра.

Для это­го мы декоди­руем зна­чения мас­сива с индекса 27 до кон­ца мас­сива в UTF8 и вос­поль­зуем­ся коман­дле­том Split-Path, что­бы получить толь­ко имя фай­ла:

NTFS PowerShell

Все дан­ные для вос­ста­нов­ления нерези­ден­тно­го фай­ла $ROWX1VN.exe у нас есть, и спо­соб мы уже изу­чили, поэто­му дело за малым. Готовый сце­нарий для вос­ста­нов­ления уда­лен­ных через кор­зину фай­лов мож­но най­ти на GitHub.

Заключение

Вос­ста­нов­ление уда­лен­ных фай­лов — задача доволь­но кро­пот­ливая и инте­рес­ная. Хотя авто­мати­зиро­ван­ных средств для это­го пре­дос­таточ­но, луч­ше не доводить дело до потери дан­ных. Что­бы обе­зопа­сить себя от утра­ты цен­ной информа­ции, не забывайте соз­давать бэкапы и хра­нить их по прин­ципу 3-2-1.

Ду­маю, что с получен­ными зна­ниями читате­лю не сос­тавит тру­да раз­работать собс­твен­ную прог­рамму для авто­мати­зации про­цес­са вос­ста­нов­ления.

ПОЛЕЗНЫЕ ССЫЛКИ:

Дима (Kozhuh)

Эксперт в кибербезопасности. Работал в ведущих компаниях занимающихся аналитикой компьютерных угроз. Анонсы новых статей в Телеграме.

Добавить комментарий