Продолжаем заметать следы или Инструменты безвозвратного удаления

16 0

Напомню, что ранее Алексей Тутаев рассказывал нам про алгоритмы удаления данных с носителей. Вот ссылка на его статью, если потеряли: Заметаем следы. Или как безвозвратно удалить файл на жестком диске. Мы пошли дальше и посмотрели, какие существуют инструменты уничтожения данных.

Задачу мы себе сформулировали так: нам нужен инструмент уничтожения данных, которым мы сможем управлять прямо из прикладного кода, который был бы бесплатным, работал бы не слишком медленно и позволял выполнить уничтожение данных в соответствии с требованиями ГОСТ Р 50739-95 (а в идеале поддерживал бы разные алгоритмы удаления). Отбор прошли несколько участников:

  • библиотека Directum.FileShredder.Shredder — та самая, из материала Алексея;
  • утилита SDelete из набора Sysinternals;
  • Eraser — еще одна утилита с интересным подходом к уничтожению;
  • ну и на реализацию инструмента прямо на ISBL мы тоже возложили надежду.

Как мы тестировали

Для тестирования мы подготовили на жестком диске небольшой раздел — всего около тридцати мегабайт, чтобы было проще окинуть взглядом наш театр военных действий. На этом диске мы создавали файлы, уничтожали их разными способами и затем смотрели, что от них осталось. Уничтожение считается успешным, если не удается найти ни одного фрагмента исходного файла. А чтобы сравнение инструментов было честным, для уничтожения файлов во всех инструментах был применен алгоритм, поддерживаемый ими всеми — DOD 5220.22-M, формально удовлетворяющий и требованиям ГОСТ.

Для контроля результатов уничтожения мы использовали следующие инструменты:

  • WinHex — условно-бесплатная утилита, получающая доступ к содержимому носителя на низком уровне, позволяющая искать данные по фрагменту содержимого и восстанавливать их;
  • DiskView — еще одна утилита от Sysnternals. Она использовалась скорее в процессе, чем для контроля результатов — с ее помощью мы наблюдали "географию" расположения фрагментов файлов в кластерах на диске.

Пишем инструмент на ISBL

Суть алгоритма DOD 5220.22-M достаточно простая, и мы реализовали его на ISBL. На вход алгоритм получает имя файла и запрашивает у файловой системы его размер в байтах. Затем три раза генерируется буфер вычисленного размера, который записывается в указанный файл.

FSO = CreateObject("Scripting.FileSystemObject")
SourceFile = FSO.GetFile(FileName)
SizeInBytes = SourceFile.Size

// DOD 5220.22-M

// Первый проход: шаблон 0x00
Buffer = DupeString(Char(0); SizeInBytes)
WriteFile(Filename; "Overwrite"; Buffer)

// Второй проход: шаблон 0xFF
Buffer = DupeString(Char(255); SizeInBytes)
WriteFile(Filename; "Overwrite"; Buffer)

// Третий проход: случайные данные
/* Быстрый способ получить рандомный буфер нужной длины
для третьего прохода: генерим guid, из него конкатенацией
складываем строку длиной не менее SizeInBytes,после чего
шифруем ее. Пароль - сам guid.
Из полученного шифротекста берем первые SizeInBytes байтов
и получаем бессмысленный набор данных, никак не связанный
с исходным содержимым файла и поэтому бесполезный для криптоанализа.
Почему так: генерация случайных чисел с помощью функции rаnd()
и ей подобных на ISBL и VBS занимает много времени (десятки секунд
для одного мегабайта), а плюсов с точки зрения безопасности не видно. */
Crypto: ICrypto = CreateObject("SBRte.SBCrypto")
Encrypter = Crypto.Encrypter
ID = NewID()
Buffer = DupeString(ID; 1 + SizeInBytes / Length(ID))
Encrypter.Content = Buffer
Encrypter.Password = ID
Encrypter.Encrypt()
Buffer = Copy(Encrypter.CryptContent; 0; SizeInBytes)
WriteFile(Filename; "Overwrite"; Buffer)

// Переименовать файл
NewFileName = ExtractFilePath(Filename) & NewID()
RenameFile(Filename; NewFileName)

// Удалить файл
DeleteFile(NewFileName)

Красота подхода в том, что алгоритм уничтожения может быть реализован совершенно любой, с любым количеством проходов и самыми немыслимыми шаблонами. Кроме того, поскольку инструмент выполнен на ISBL, со встраиванием его в прикладную разработку системы Directum не возникает совершенно никаких сложностей. И работает-то он быстро. Вот только не уничтожает данные! WinHex обнаружил на диске не просто фрагменты исходного файла, а весь файл целиком и успешно его восстановил. Выяснилось, что в момент записи первого же буфера на диск местоположение файла на диске меняется: исходный файл располагался в начале раздела, а оказался посередине или в конце. Это мы выяснили с помощью DiskView. Исходные же кластеры хоть и помечены свободными, но все еще содержат в себе данные. Это, разумеется, никуда не годится. Способы записи в файл использовали разные: и функция WriteFile, и объект FileSystemObject, и ADO Stream. Результат везде одинаковый, данные можно найти и восстановить. Получается, мы можем генерировать буфер для перезаписи, но не можем правильно записать его на диск. И поскольку рабочих схем найти не удалось, инструмент выбыл из гонки.

SDelete

https://docs.microsoft.com/en-us/sysinternals/downloads/sdelete

В утилите SDelete от Sysinternals реализован всего один алгоритм удаления (DOD 5220.22-M), но можно указать количество проходов перезаписи, уничтожить дерево каталогов со всем содержимым и даже выполнить "зачистку" незанятого места на диске. SDelete является утилитой командной строки и имеет всего несколько ключей, так что вызвать ее из прикладных вычислений несложно:

SDelete = "D:\APPS\SDelete\sdelete.exe"
Command = Format('"%s" -p 1 "%s"'; ArrayOf(SDelete; Filename))
ExecuteProcess(Command; smNormal; wmYes)

В результате применения утилиты файлы исчезли с диска практически бесследно: с помощью WinHex удалось обнаружить только следы перезаписи имени файла, но содержимое найти и восстановить не удалось. При этом работала утилита довольно быстро (удаление файла размером 1 мегабайт = 0,2 секунды) и заслуженно вырвалась в лидеры.

Directum.FileShredder.Shredder

Shredder представляет собой библиотеку (DLL), в которой реализован com-объект, доступный в прикладных вычислениях после регистрации библиотеки. На борту есть поддержка целой обоймы алгоритмов уничтожения включая нужный нам DOD 5220.22-M:

ShredderAlgo = "dod" // gost, hmg1, hmg3, vsitr, dod, rcmp, schneier, gutmann,
Shredder = CreateObject("Directum.FileShredder.Shredder")
ShredderResult = Shredder.ShredFile(FileName; ShredderAlgo)
if ShredderResult <<>> ''
  Error = Format('При уничтожении файла (%s) возникла ошибка: %s'; ArrayOf(FileName; ShredderResult))
  Raise(CreateException(''; Error; ecWarning))  
endif   
Shredder = nil

Shredder тоже прекрасно справился с уничтожением файла, найти на диске фрагменты после удаления файла не удалось. Однако не порадовало быстродействие: на удаление файла размером 1 мегабайт Shredder тратил в среднем около 4 секунд. Похоже, его можно использовать там, где требуется выбор алгоритма, а объем удаляемых данных невелик. Но на больших объемах Shredder очевидно уступает SDelete.

Eraser

https://eraser.heidi.ie

Бесплатная утилита с графическим интерфейсом. Что отличает Eraser от остальных, так это работа с очередью заданий на уничтожение. Если вы захотите удалить файл, то вы должны создать соответствующую задачу и добавить ее в очередь. Каждая задача в очереди Eraser — это совокупность информации:

  • об объекте уничтожения — это может быть конкретный файл или каталог, содержимое "Корзины" пользователя, незанятое место на диске. Это также может быть безопасное перемещения файлов или папок или полная очистка раздела на жестком диске;
  • об алгоритме уничтожения — как и Shredder, Eraser знает несколько готовых алгоритмов перезаписи, а также предлагает возможность создать свои собственные, настроив необходимое количество проходов и указав для каждого из них свой шаблон данных для перезаписи;
  • о времени старта — задача может быть выполнена непосредственно после помещения в очередь, по расписанию, при загрузке операционной системы или вручную.

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

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

Eraser = "C:\Program Files\Eraser\Eraser.exe"
Command = Format('"%s" erase /method="ecbf4998-0b4f-445c-9a06-23627659e419" /quiet file="%s"';
                 ArrayOf(Eraser; Filename))
ExecuteProcess(Command; smNormal; wmYes)

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

Финиш

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

Обсудить итоги можно здесь или на habr.

Пока комментариев нет.

Авторизуйтесь, чтобы написать комментарий