Хакер - Воскрешению подлежит! Восстанавливаем файлы в NTFS с использованием PowerShell

Хакер - Воскрешению подлежит! Восстанавливаем файлы в NTFS с использованием PowerShell

hacker_frei

https://t.me/hacker_frei

Антон Кузнецов

Содержание статьи

  • Теория
  • Резидентные и нерезидентные файлы атрибуты
  • Время и атрибуты $STANDARD_INFO и $FILE_NAME
  • Восстановление файлов, удаленных с использованием del или erase
  • Восстановление файлов, удаленных через корзину
  • Выводы

Су­щес­тву­ет мно­жес­тво спо­собов вер­нуть утра­чен­ные или уда­лен­ные с накопи­телей фай­лы. В статье мы с тобой осве­жим в памяти теоре­тичес­кие осно­вы вос­ста­нов­ления уда­лен­ной информа­ции в фай­ловой сис­теме NTFS v3.1 и под­робно рас­смот­рим прак­тичес­кий спо­соб руч­ного вос­ста­нов­ления фай­лов с исполь­зовани­ем PowerShell.

INFO

Хо­чу отдать дол­жное Кри­су Кас­пер­ски за его тру­ды на эту тему и под­робное опи­сание теории и прак­тики в кни­ге «Вос­ста­нов­ление дан­ных. Прак­тичес­кое руководс­тво», а заод­но поб­лагода­рить Ва­лен­тина Хол­могоро­ва и Ксе­нию Кирило­ву за обновле­ние и пере­изда­ние кни­ги в 2021 году.

Се­год­ня соз­дано пре­дос­таточ­но прог­рам­мных решений для вос­ста­нов­ления уда­лен­ных фай­лов с раз­личных фай­ловых сис­тем. Одна­ко, если переф­разиро­вать извес­тное изре­чение, прак­тика без теории мер­тва: что­бы мак­сималь­но эффектив­но исполь­зовать инс­тру­мен­ты, нуж­но понимать, как они работа­ют. Если перед спе­циалис­том сто­ит задача не прос­то вер­нуть утра­чен­ные фай­лы, а разоб­рать­ся в при­чинах инци­ден­та, зна­ния об устрой­стве фай­ловых сис­тем прос­то необ­ходимы.

ТЕОРИЯ

Под­робно рас­смат­ривать струк­туру NTFS я не вижу смыс­ла, опи­сание мож­но най­ти в кни­ге Кри­са «Вос­ста­нов­ление дан­ных. Прак­тичес­кое руководс­тво» и статье «Фай­ловая сис­тема NTFS извне и изнутри» (в двух час­тях). Одна­ко, что­бы наши дей­ствия при вос­ста­нов­лении фай­лов были осмыслен­ными, нам все же при­дет­ся осве­жить в памяти некото­рые клю­чевые осо­бен­ности фай­ловой сис­темы NTFS 3.1, а заод­но вспом­нить, как хра­нят­ся и уда­ляют­ся фай­лы.

WARNING

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

В фай­ловой сис­теме NTFS работа­ет прин­цип «все есть файл». Файл же име­ет опре­делен­ный набор атри­бутов. Мы не будем раз­бирать все атри­буты фай­лов, зат­ронем толь­ко самые важ­ные: $STANDARD_INFO$FILE_NAME$DATA.

В атри­бутах $STANDARD_INFO и $FILE_NAME записа­ны мет­ки вре­мени, под­робнее о них мы погово­рим поз­же, а в атри­буте $DATA хра­нит­ся содер­жимое резиден­тно­го фай­ла. В слу­чае с нерези­ден­тны­ми фай­лами там рас­полага­ются «ссыл­ки» на раз­бро­сан­ное по сек­торам содер­жимое фай­ла, называ­емое data runs или отрезка­ми. Отрезки пред­став­ляют собой пос­ледова­тель­ность клас­теров, которые хра­нят содер­жимое нерези­ден­тно­го фай­ла, а в качес­тве упо­мяну­тых «ссы­лок» в атри­буте $DATA исполь­зует­ся номер началь­ного клас­тера и количес­тво иду­щих сле­дом клас­теров. Как видишь, матема­тика прос­тая: если файл нерези­ден­тный (боль­ше 720 байт), нам нуж­но най­ти клас­тер, с которо­го он начина­ется, и соб­рать все клас­теры воеди­но в вер­ном поряд­ке, а пос­ле записать содер­жимое клас­теров в новый файл.

Все фай­ловые атри­буты хра­нят­ся в фай­ловой записи (File Record) таб­лицы Master File Table ($mft). Это наиваж­ней­ший слу­жеб­ный файл (отто­го он име­ет резер­вную копию $mftmirr), так как содер­жит в себе информа­цию обо всех фай­лах и дирек­тори­ях на томе. Имея на руках толь­ко файл $mft, мож­но выс­тро­ить хро­ноло­гию свя­зан­ных с фай­лами событий, а в некото­рых слу­чаях — вос­ста­новить фай­лы.

Еще один важ­ный слу­жеб­ный файл — кар­та сво­бод­ного прос­транс­тва $BitMap. С ее помощью отсле­жива­ются все исполь­зуемые и неис­поль­зуемые клас­теры, что, конеч­но же, нап­рямую свя­зано с соз­дани­ем и уда­лени­ем фай­лов или дирек­торий. Клас­тер же в NTFS — минималь­ная еди­ница дис­кового прос­транс­тва, дос­тупно­го для раз­мещения фай­лов и дирек­торий в фай­ловой сис­теме NTFS. По умол­чанию раз­мер клас­тера равен 4096 Kбайт, но при соз­дании тома мож­но задать иной раз­мер.

Про­цесс уда­ления фай­ла под­робно опи­сан в кни­ге Кри­са, так­же информа­цию мож­но най­ти в статье «Раз­гре­баем руины. Как вос­ста­новить уда­лен­ные фай­лы на раз­делах NTFS». 

РЕЗИДЕНТНЫЕ И НЕРЕЗИДЕНТНЫЕ ФАЙЛЫ АТРИБУТЫ

Не­кото­рые матери­алы, пос­вящен­ные фай­ловой сис­теме NTFS v3.1, упо­мина­ют о резиден­тных и нерези­ден­тных фай­лах. Резиден­тны­ми фай­лами счи­тают­ся те, раз­мер которых мень­ше или равен 720 байт (это количес­тво бай­тов было получе­но исклю­читель­но опыт­ным путем в NTFS v3.1 в Windows 10, хотя в дру­гих источни­ках читатель может най­ти иную информа­цию о мак­сималь­ном раз­мере резиден­тно­го фай­ла: он варь­иру­ется от 700 байт до 1 Кбайт). Такие фай­лы хра­нят все содер­жимое в $mft (Master File Table), и в этом слу­чае флаг нерези­ден­тнос­ти (Non-resident flag) у них равен 00h. Для нерези­ден­тных фай­лов (стро­го боль­ше 720 байт) флаг Non-resident flag равен 01h.

На самом деле флаг резиден­тнос­ти при­сущ каж­дому атри­буту фай­ла в отдель­нос­ти (в том чис­ле $FN$SI и дру­гим атри­бутам), а не самому фай­лу как таково­му. Нес­мотря на наличие такого фла­га у каж­дого атри­бута, сущес­тву­ют исклю­читель­но резиден­тные атри­буты, которые хра­нят свои дан­ные толь­ко в фай­ле $mft (нап­ример, $FILE_NAME$STANDARD_INFO$VOLUME_NAME). Есть атри­буты, которые могут быть как резиден­тны­ми, так и нерези­ден­тны­ми (это спра­вед­ливо по отно­шению к атри­бутам $DATA$EA и дру­гим). Наконец, сущес­тву­ют фай­ловые атри­буты, которые хра­нят свои дан­ные исклю­читель­но за пре­дела­ми $mft, то есть явля­ются стро­го нерези­ден­тны­ми ($BITMAP$REPARSE_POINT$SECURITY_DESCRIPTOR и про­чие).

Время и атрибуты $STANDARD_INFO и $FILE_NAME

При соз­дании фай­ла на томе, переме­щении меж­ду томами и прак­тичес­ки любых манипу­ляци­ях с фай­лами (пере­име­нова­ние, локаль­ное переме­щение, дос­туп внут­ри одно­го тома, изме­нение) у фай­ла изме­няют­ся атри­буты $STANDARD_INFO (далее — $SI) и $FILE_NAME (далее — $FN). В них ука­зано вре­мя, ког­да про­изош­ло дей­ствие с фай­лом.

В сле­дующих таб­лицах показа­но, какие атри­буты фай­лов $SI и $FN меня­ются и при каких дей­стви­ях с фай­лом.

Из­менение атри­бута $FILE_NAME
Из­менение атри­бута $STANDARD_INFO

Здесь:

  • Modification (изме­нение атри­бутов $Data и $INDEX);
  • Accessed (обра­щение к содер­жимому фай­ла);
  • Change MFT (запись в таб­лицу MFT — не отоб­ража­ется в Windows);
  • BornTime (или birthday of file — соз­дание фай­ла).

Важ­но, что при уда­лении через del или erase атри­буты $FILE_NAME и $STANDARD_INFO не изме­няют­ся.

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

ВОССТАНОВЛЕНИЕ ФАЙЛОВ, УДАЛЕННЫХ С ИСПОЛЬЗОВАНИЕМ DEL ИЛИ ERASE

Нас­тало вре­мя прис­тупить к прак­тичес­кой час­ти, что­бы зак­репить теорию и поуп­ражнять­ся в вос­ста­нов­лении уда­лен­ных фай­лов. Но для начала сле­дует выделить два спо­соба уда­ления фай­лов в Windows:

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

Та­кое раз­деление свя­зано с раз­ницей в механиз­ме уда­ления и некото­ром отли­чии при вос­ста­нов­лении фай­лов.

WARNING

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

В пер­вую оче­редь раз­берем­ся с вос­ста­нов­лени­ем нерези­ден­тных фай­лов, а даль­ше пос­мотрим, как вос­ста­нав­ливать резиден­тные. Итак, прак­тиковать­ся мы будем с исполь­зовани­ем PowerShell-модуля PowerForensics авторс­тва Джа­реда Эткинсо­на. Этот модуль прост в уста­нов­ке и содер­жит полез­ные коман­дле­ты для работы с фай­ловыми сис­темами NTFS и FAT. Он поз­воля­ет работать с сис­темны­ми фай­лами Windows и пар­сить атри­буты фай­лов NTFS, кон­верти­ровать мет­ки вре­мени из бай­тового пред­став­ления в челове­ко‑чита­емое (что необ­ходимо в форен­зике). Под­робнее узнать о воз­можнос­тях модуля мож­но из его опи­сания.

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

Import-Module PowerForensics

Про­верим, что все прош­ло успешно, для это­го выпол­ним коман­длет

Get-Command - Module PowerForensics

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

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

Как уже было ска­зано в теоре­тичес­кой час­ти, в Windows пос­тоян­но про­исхо­дят изме­нения, какие‑то фай­лы уда­ляют­ся, а какие‑то, наобо­рот, соз­дают­ся (нап­ример, начиная с Windows 8 количес­тво фай­лов Prefetch огра­ниче­но 1024, поэто­му ста­рые уда­ляют­ся сис­темой, а новые соз­дают­ся при запус­ке исполня­емых фай­лов).

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

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

Get-ForensicFileRecord -VolumeName F: | Where-Object {$_.Deleted}

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

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

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

$file_record = Get-ForensicFileRecord -VolumeName F: -Index 43

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

$file_descriptor=$file_record.Attribute | Where-Object {$_.name -eq 'DATA'}`

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

$start_cluster = $file_descriptor.DataRun | select *

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

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

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

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

Invoke-ForensicDD -InFile \\.\F: -Offset ($st_cl.StartCluster*4096) -BlockSize ($st_cl.ClusterLength*4096) -Count 1 -OutFile C:\calc.exe

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

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

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

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

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

$bytearray = Invoke-ForensicDD -InFile \\.\F: -Offset ($st_cl.StartCluster*4096) -BlockSize ($st_cl.ClusterLength*4096) -Count 1

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

[System.IO.File]::WriteAllBytes("C:\calc.exe",$bytearray[0..($bytearray.Length - (1024 + 1))])

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

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

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

ВОССТАНОВЛЕНИЕ ФАЙЛОВ, УДАЛЕННЫХ ЧЕРЕЗ КОРЗИНУ

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

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

  1. $I<random>.original_extension (далее — $I) — файл с метадан­ными, соз­дает­ся, как толь­ко файл переме­щает­ся в кор­зину. Он исполь­зует­ся для вос­ста­нов­ления фай­ла из кор­зины средс­тва­ми Microsoft, под­робнее раз­бор фай­ла будет при­веден ниже.
  2. $R<random>.original_extension (далее — $R) — файл, который соз­дает­ся пос­ле переме­щения в кор­зину. Это копия переме­щен­ного в кор­зину фай­ла, о чем говорят оди­нако­вое содер­жимое и хеш‑сум­мы (если срав­нить ори­гинал до уда­ления и переме­щен­ный файл). Изме­няет­ся толь­ко имя фай­ла.
Пос­ле переме­щения фай­ла в кор­зину

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

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

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

Здесь:

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

У каж­дого поль­зовате­ля своя $Recycle.Bin (кор­зина). Более того, на каж­дом томе такая кор­зина соз­дает­ся по умол­чанию. Гру­бо говоря, кор­зина из тома С проб­расыва­ется в том F и дру­гие соз­данные тома. Поэто­му перед име­нем уда­лен­ного фай­ла мы видим SID поль­зовате­ля — зачас­тую это полез­ная информа­ция о том, какой поль­зователь в сис­теме перемес­тил файл в кор­зину и выпол­нил уда­ление. Нап­ример, для фай­ла calc.exe пол­ное имя фай­ла будет выг­лядеть так:

F:\$RECYCLE.BIN\S-1-5-21-3457051395-4168275294-665325124-1000\$ROWX1VN.exe

ли­бо

F:\$RECYCLE.BIN\S-1-5-21-3457051395-4168275294-665325124-1000\$IOWX1VN.exe

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

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

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

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

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

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

Get-ForensicFileRecord -VolumeName F:| where {$_.Deleted}

$file_record = Get-ForensicFileRecord -VolumeName F: -Index 44

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

$file_descriptor=$file_record.Attribute | Where-Object {$_.name -eq 'DATA'}

$Byte_Array = $file_descriptor.RawData

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

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

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

$filename = Split-Path -Path ([System.Text.Encoding]::UTF8.GetString($Byte_Array[27..$Byte_Array.Length])) -Leaf

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

ВЫВОДЫ

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

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

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei



Report Page