Хабрахабр

[recovery mode] Стеганография мимо файлов: прячем данные прямо в секторах

Небольшое предисловие

Стеганография, если кто не помнит, — это сокрытие информации в каких-либо контейнерах. Например, в картинках (обсуждалось тут и тут). Можно также скрыть данные в служебных таблицах файловой системы (об этом писалось тут), и даже в служебных пакетах протокола TCP. К сожалению, у всех этих методов есть один недостаток: чтобы незаметно «вкрапить» информацию в контейнер, нужны хитрые алгоритмы, учитывающие особенности внутреннего устройства контейнера. Да и с устойчивостью контейнера к манипуляциям возникают проблемы: например, если чуточку подредактировать картинку, скрытая информация теряется.

Забегая вперед скажу — да, можно! Можно ли как-то обойтись без хитрых алгоритмов и тонких манипуляций с данными, и при этом все-таки обеспечить работоспособность контейнера и приемлемый уровень сохранности скрытых данных? И даже утилитку предложу.

Кровавые подробности метода

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

Достоинство такого метода очевидно: мы не зависим ни от формата файлов, ни даже от типа используемой файловой системы.

Недостатки тоже, думаю, очевидны:

  • Секретные данные можно будет изменить только полной перезаписью всего диска, с последующим воссозданием видимого пользователю содержимого. При этом нельзя пользоваться софтом, воссоздающим диск из образа: он воссоздаст и предыдущие секретные данные.
  • Чем больше объем секретных данных, тем больше вероятность потери части информации.
  • Извлечение данных с диска может занять много времени. От нескольких минут до нескольких дней (современные диски больши-ие).

Теперь перейдем к частностям.

Если вооружить взгляд, скажем, редактором диска, то данные предстанут во всей красе. Понятно, что если просто размазать секретные данные по всему диску, то скрыты они будут только от невооруженного взгляда. Шифровать будем простенько, но со вкусом: по алгоритму aes256-cbc. Поэтому данные неплохо бы зашифровать, чтобы не отсвечивали. Ключ шифрования спросим у пользователя, пусть хороший пароль придумывает.

Тут нам поможет контрольная сумма, да не простая, а SHA1. Следующий вопрос — в том, как нам отличить «правильные» данные от испорченных. Для git'а она достаточно хороша, значит, и нам подойдет. А что? Решено: снабжаем каждый сохраненный фрагмент информации контрольной суммой, и если после расшифровки она совпала — значит, расшифровка удалась.

Номер фрагмента — чтобы отслеживать, какие кусочки мы уже расшифровали, а какие остались. Еще обязательно понадобится номер фрагмента и общая длина секретных данных. Ну и раз уж у нас все равно наклевывается заголовок, то добавим туда имя секретного файла. Общая длина нам пригодится при обработке последнего фрагмента, чтобы не писать лишние данные (сиречь паддинг). Оно пригодится уже после расшифровки, чтобы не гадать, чем его открывать.

Проверяем метод на практике

Для проверки возьмем самый распространенный носитель — флэшку. У меня нашлась старенькая на 1 Гб, что вполне подойдет для экспериментов. Если вам, как и мне, пришла в голову мысль не париться с физическими носителями, а потестировать на файлике — образе диска, то сразу скажу: не выйдет. При форматировании такого «диска» линукс создает файл заново, и все неиспользуемые сектора будут заполнены нулями.

Памяти там негусто, поэтому большие файлы прятать не будем. В качестве машины с линуксом, к сожалению, пришлось воспользоваться валяющейся на балконе метеостанцией на Raspberry Pi 3. Слишком маленькие файлы тоже прятать смысла нет: утилитка пишет данные на диск кластерами по 4 Кб. Ограничимся максимальным размером в 10 мегабайт. Поэтому снизу ограничимся файлом в 3 кб — он влезает в один такой кластер.

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

  1. Быстрое форматирование в формате FAT16 с размером кластера 16 кб. Это то, что предлагает сделать Windows 7 с флэшкой, на которой отсутствует файловая система.
  2. Заполнение флэшки всяким мусором на 50%.
  3. Заполнение флэшки всяким мусором на 100%.
  4. «Долгое» форматирование в формате FAT16 (с перезаписью всего).

Первые два испытания вполне ожидаемо закончились полной победой: утилита смогла успешно извлечь 10 мегабайт секретных данных с флэшки. А вот после того, как флэшку забили файлами под завязку, произошел сбой:

Total clusters read: 250752, decrypted: 158
ERROR: cannot write incomplete secretFile

Понятно, что 10 мегабайт тут никак не наберется, а ведь среди этих кластеров явно есть дубликаты. Как видим, удалось успешно расшифровать только 158 кластеров (632 килобайта сырых данных, что дает 636424 байта полезной нагрузки). Но зато можно гарантировать, что 3 килобайта секретных данных мы восстановим с флэшки даже после того, как ее отформатируют и запишут под завязку. Даже 1 мегабайт таким образом уже не восстановишь. Впрочем, опыты показывают, что с такой флэшки вполне возможно извлечь файл длиной 120 килобайт.

Последнее испытание, к сожалению, показало, что флэшка перезаписалась вся:

$ sudo ./steganodisk -p password /dev/sda
Device size: 250752 clusters
250700 99%
Total clusters read: 250752, decrypted: 0
ERROR: cannot write incomplete secretFile

Попробуем перед форматированием создать на флэшке раздел, а уже в нем — файловую систему. Ни одного кластера не сохранилось… Печально, но не трагично! Кстати, с завода она пришла именно с таким форматированием, так что ничего подозрительного мы не делаем.
Вполне ожидаемо, что доступное пространство на флэшке немного уменьшилось.

Но зато теперь количество успешно расшифрованных кластеров увеличилось более чем в два раза! Также вполне ожидаемо, что 10 мегабайт все-таки не удалось спрятать на полностью забитый диск.

Total clusters read: 250752, decrypted: 405

Мегабайт, к сожалению, собрать из кусочков не получится, а вот килобайт двести — запросто.

120 килобайт секретных данных прекрасно влезло в неиспользуемое пространство. Ну и весть о последней, 4-й проверке, на этот раз радостная: полное форматирование такой флэшки не привело к уничтожению всей информации!

Сводная таблица по тестированию:

Немного теоретизирования: о свободном месте и неиспользуемых секторах

Если вы когда-то разбивали жесткий диск на разделы, то могли обратить внимание, что далеко не всегда получается отвести все свободное пространство на диске. Первый раздел всегда начинается с некоторым отступом (обычно это 1 мегабайт, или 2048 секторов). За последним разделом тоже, бывает, остается небольшой «хвост» из неиспользуемых секторов. Да и между разделами иногда остаются промежутки, хотя и редко.

А значит, и прочитать тоже. Другими словами, на диске есть сектора, к которым нет доступа при обычной работе с диском, но данные-то в эти сектора записать можно! С поправкой на то, что есть еще таблица разделов и код загрузчика, которые как раз и расположены в пустой области в начале диска.

Вот есть у нас на диске пустой раздел. Отвлечемся на время от разделов и посмотрим на диск с высоты, так сказать, птичьего полета. Можно ли сказать, что какие-то сектора на диске остались незатертыми? Создадим в нем файловую систему.

Ответ практически всегда будет — да! И-и-и — барабанная дробь! Ведь в большинстве случаев создание файловой системы сводится к тому, что на диск записывается только несколько блоков служебной информации, а в остальном содержимое раздела не меняется.

Например, файловая система FAT16 с размером кластера в 64 килобайта очевидно, не сможет полностью занять раздел с размером, не кратным 64 килобайтам. А еще — чисто эмпирически — можно предположить, что файловая система не всегда может занять все отведенное ей пространство до последнего сектора. Впрочем, экспериментально это предположение подтвердить не удалось. В конце такого раздела должен будет остаться «хвост» в несколько секторов, недоступный для хранения пользовательских данных.

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

Утилита для экспериментов

Исходники утилиты можно пощупать здесь

0 и выше и OpenSSL. Для сборки потребуется Qt версии 5. Если что-то не собирается — возможно, придется подправить файл steganodisk.pro.

При этом вырастут расходы на служебную информацию: заголовок и контрольная сумма занимают фиксированные 68 байт. Можно поменять размер кластера с 4 Кб на, скажем, 512 байт (в secretfile.h).

Никаких вопросов перед перезаписью указанного файла или устройства не будет! Запускать утилиту нужно, естественно, с правами пользователя root, причем с осторожностью.

Наслаждайтесь.

Показать больше

Похожие публикации

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»