Привет, Хабр.


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


Я сделал проект по скрытому хранению информации в файловой системе (далее ФС).
Это можно применить для кражи конфиденциальной информации в образовательных целях.


Image


В виде опытного образца была выбрана весьма старенькая линуксовая ФС ext2.



Реализация


Соображения о реализации


Если хорошо "раздраконить" стандарт ext2, то можно заменить, что в ФС существует так называемый Superblocks, в котором дана основная информация о системе. После мной были найдены Block Bitmap и Inode Table. Почти сразу родилась идея записи информации в пустые на данный момент блоки ФС. Теперь стоило продумать защиту от программиста, вооруженного hex-редактором.


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


Для отделения нужных блоков от всех остальных при чтении в каждый блок было решено добавить по специальному маркеру в начало блока. Этот маркер шифровался в зависимости от номера блока в исходном файле. Такая уловка сразу позволила не только находить нужные блоки, но и узнавать их правильный порядок.


Общий принцип работы системы.


image


Алгоритм записи


По пунктам:


  • Сначала записать в исходную файловую систему какую-либо информацию;
  • Удалить эту информацию (не обязательно всю);
  • Файл для сокрытия разбить на блоки одинаковой длины, добавив маркер;
  • Зашифровать эти блоки;
  • Поместить зашифрованные блоки в пустые блоки ФС.

Для любителей блок-схем

Ниже представлена блок-схема алгоритма записи. На вход алгоритм получает четыре файла:
-Образ изменяемой файловой системы;
-Файл, подлежащий стеганографии;
-Файл с ключом шифрования для AES;
-Файл с маркером.
image


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


Но достаточно очевидно как это можно исправить: необходимо перезаписать алгоритм записи блоков в ФС. Это понятная, но невероятно трудоёмкая задача.
Для Proof Of Consept я это не реализовывал.


В результате получатся следующие изменения в ФС, так выглядит ФС до стеганографии (предварительно был записан аудиофайл).
image
А так выглядит ФС с уже застеганографированной информацией.
image


Алгоритм чтения


По пунктам:


  • Со знанием ключа и способа построения маркеров составить первые N маркеров, с гарантией что N, умноженное на длину блока файловой системы больше длины застеганографированного файла;
  • Произвести поиск блоков в ФС, начинающихся с маркеров;
  • Расшифровать полученные блоки и отделить маркеры;
  • Собрать полученные блоки в правильном порядке и получить исходный файл.

Для любителей блок-схем

Ниже представлена блок-схема алгоритма записи. На вход алгоритм получает три файла:
-Образ файловой системы;
-Файл с ключом шифрования для AES;
-Файл с маркером.
image


После работы программы появляется файл Read, который и будет извлеченным из стеганографированной ФС файлом, если ключ или маркер были указаны неверно, то файл Read будет пуст.
(для любителей красивостей можно вкраплять не только файл, но "шапку", содержащую метаинформацию: имя файла, права, время последнего изменения и т.д.)


Автоматизация запуска


Для удобства были написаны bash скрипты, автоматизирующие запуск на Linux (тестировалось на Ubuntu 16.04.3 LTS).
Разберем запуск по шагам.
Запись:


  1. sudo Copy_Flash.sh “DEVICE” — получаем образ ФС из DEVICE(флэш);
  2. ./Write.sh “FILE” “KEY” “MARKER” – создаем виртуальное окружение, скачиваем необходимые библиотеки и запускаем скипт на запись;
  3. sudo ./Write_Flash.sh “DEVICE” – записываем измененную ФС снова на DEVICE.

Чтение:


  1. sudo Copy_Flash.sh “DEVICE” — получаем образ ФС из DEVICE(флэш);
  2. ./Read.sh “KEY” ‘MARKER” — создаем виртуальное окружение, скачиваем необходимые библиотеки и запускаем скипт на чтение;
  3. В текущем каталоге открываем файл Read – это и есть застеганографированная информация.

Заключение


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


Весь код реализован на языке Python версии 3.5.2. Пример работы представлен на моем youtube канале. Полный код проекта выложен на github.
(Да-да, я знаю, что для production версии нужно писать на чём-нибудь "быстром", например на Си ;) )
В данной реализации размер входного файла для стеганографии не должен превышать 1000 кБ.


Хочу выразить благодарность пользователю PavelMSTU за ценные советы при планировании исследования и рекомендации по оформлению статьи.

Комментарии (24)


  1. arandomic
    26.01.2018 13:10

    Я правильно понимаю, что никто не гарантирует сохранность спрятанных данных во время обычной работы с FS?
    Т.е. свободные блоки всегда могут быть перетерты, если на флешку закинут новый файл?


    1. Kazmal Автор
      26.01.2018 17:15

      Да, они всегда могут быть затерты, но можно попробовать в таблице Inode ставить у занятых застеганографированным файлом блоков 1, тогда перезаписываться не будет, но тут тоже есть проблема, тогда объём занятой памяти не будет равняться суммарному объёму записанных данных.


      1. shs
        26.01.2018 17:40

        Речь идет о битмапе блоков, по-видимому. Такой способ плох тем, что придется «исправлять» слишком много метаданных, иначе можно спалиться на первом же fsck, после которого «программист уже будет знать, что где следует искать».

        Другое дело — занятые кластера приписать к badblock inode, но тут опять же придется обновлять все его метаданные и вносить изменения в битмап блоков, суперблок и таблицы дескрипторов.


        1. Kazmal Автор
          26.01.2018 17:48

          Да, о Bitmap, опечатался


      1. worldmind
        26.01.2018 20:21

        Как вариант записывать с дублированием.


  1. tBlackCat
    26.01.2018 13:16
    +1

    > Если хорошо «раздраконить» стандарт ext2, то можно заменить, что в ФС существует…
    Опечатка — заметить таки. :)
    Криптография весьма сложна и требуются солидные исследования метода, но задумка в принципе неплохая.
    Напомнило мне давнюю историю, времён беспредельного владычества дискет.
    Файловых систем было немного, дискеты перезаписывались многократно, форматировались в разных ОС. И как-то раз пробило меня посмотреть битую дискету на низком уровне, чтобы вытащить информацию.
    Вытащил, но попутно вытащил и махровой давности информацию, которая была записана в иной файловой системе, причём она оказалась не битой. И это после неоднократного переформатирования (знаю, что физически информация не уничтожается при форматировании), перезаписи…
    Нечто подобное было и с первыми винчестерами.
    К рассматриваемому вопросу.
    Любая файловая система имеет вполне определённую структуру и любое отклонение от её структуры выдаёт с головой и хвостом наличие чего-то нештатного. Т.е. даёт повод более пристально покопаться при серьёзном обследовании носителя информации, тем более и программ достаточно, и аппаратные комплексы есть. А расшифровка, тут вопрос уже вторичный, более из правового поля — что там говорится про несертифицицированные средствы шифрования?
    На бытовом уровне пока не привлекут к ответственности (не всегда), но всё меняется, когда доходит до мира бизнеса.
    И, самое главное, все эти ухищрения не спасают от зловредов, портящих именно ФС, скорее можно стать самому себе злобным буратиной.
    Идея, заложенная в пресловутом Truecrypt, с двумя ключами — истинным и ложным, выгляжит предпочтительнее. По крайней мере смонтированный контейнер (диск целиком предпочтительнее) с правами «только чтение» менее подвержен атакам, позволяющим всё испортить.
    Остаётся только реализовать теневое уничтожение неучтёнки при введении ложного ключа, если сильнО желание шифроваться.
    Как бы там не было, но для себя предпочитаю винчестеры на полочке в антистатической упаковке. Безопаснее для архивного хранения.
    Оперативная же информация, для её хранения достаточно существующих способов, например, маленький сервер «в удалении» с распределённым каналом доступа. Даже при серьёзном подкопе никто не поедет, напрмер, в иную страну. Да что там говорить, даже в соседний город далеко не всегда потянутся.
    Старые проверенные методы до сих пор актуальны, как во Властелине колец — воедино собрать и единою черною волей сковать. Главное не переборщить.
    Наиболее интересна стеганография в варианте маскировки в однотипном контейнере, где уши не так сильно будут торчать. Музыка в музыке, картинка в картинке…


    1. PavelMSTU
      26.01.2018 13:26

      Идея, заложенная в пресловутом Truecrypt, с двумя ключами — истинным и ложным

      Можно поподробнее? Можно просто ссылку на инфу по поводу двух ключей?


      1. tBlackCat
        26.01.2018 13:35

        Посмотрите документацию на Truecrypt, она при установке программы лежит в каталоге. Ссылку не могу дать, при моей карме ссылки не проходят, но поисковики по названию программы щедро поделятся (последней рабочей версией считается 7.1a, далее пошли непонятки).
        Суть же двух ключей заключена в ппостом: для монтирования контейнера выдаётся запрос на ввод пароля. Так в этой программе был реализован второй ключ при вводе которого вместо правильного контейнер открывался, но открывался в области, выделенной для ложного срабатывания. В конце контейнера можно было накидать кучу мусора, который и выдавался на всеобщее обозрение. Основная же информация оставалась нелоступной.
        Понятно, что в итоге выявить подмену можно простой записью контейнера «под завязку» (там была защита, чтобы ложные данные не потёрли основные), но против терморектального анализа помогало.


  1. iig
    26.01.2018 14:01

    Древние вирусы под DOS умели прятать свой код в свободных блоках ФС. Но они их помечали как испорченные.


  1. shs
    26.01.2018 14:09

    В суперблоке нет битиков с битмапами и таблицей айнодов. Указатели на битмапы (блоков и айнодов) хранятся в таблице дескрипторов каждой группы.


    1. Kazmal Автор
      26.01.2018 17:38

      Спасибо, исправил неточность


  1. tBlackCat
    26.01.2018 16:23

    Ещё раз спасибо за расширение моих возможностей. Переношу ссылки сюда по рекомендации PavelMSTU:

    www.truecryptrussia.ru Краткое описание, в котором, в частности, упоминается интересующая возможность (названа двойным паролем).

    www.truecryptrussia.ru инструкция на русском.

    bloginfo.biz/truecrypt-part-two-advanced-level.html вторая часть инструкции. Здесь фича даже на картинке показана.
    Попробуйте программу, если не пользовались. Единственное, что не пробовал — загнать всю операционку на шифрованный диск. Предупреждаю сразу, для этого программу нельзя использовать в portable-варианте, требуется установка в систему.


    1. mibori
      29.01.2018 18:43

      обратите внимание на veracrypt в качестве более поддерживаемой альтернативы. Также, сейчас небезопасно запускать truecrypt самим не собранного из исходников. Была информация о подделках. truecryptrussia.ru выглядит сомнительно в том плане, что не предлагает этого сделать.


      1. tBlackCat
        29.01.2018 19:14

        Спасибо, про Veracrypt в курсе. Truecrypt считается последней версией 7.1a, лежащей в своём загашнике с махровой давности времён. Мне не важна возможность чтения криптованного контейнера большим братом, больше беспокоит зараза, которая может порезвиться на дисках.
        В сравнении с Truecrypt Veracrypt ещё молодая программа, хочется побольше статистики по ней получить, а это — время.

        > truecryptrussia.ru выглядит сомнительно в том плане, что не предлагает этого сделать.
        Возможно у них нет исходников, вызывающих полное доверие. Мутная история с Truecrypt как-то резко возникла.


  1. berez
    26.01.2018 16:38

    Данный метод стеганографии, вероятно, нуждается в доработке, дополнительном тестировании и расширении на более популярные файловые системы, такие как Fat32, NTFS и ext4.

    Дарю простой и универсальный метод стеганографии, не зависящий от файловой системы:
    — весь раздел заранее заполняем шифрованными блоками. Например, используем тот же AES, каждый 512-байтный сектор шифруется по паролю (плюс можно задействовать номер сектора, чтобы содержимое не совпадало). Для проверки правильности расшифровки сектор помещаем хэш-сумму его содержимого (сойдет и MD5) — например, в заголовок.
    — скрываемую информацию записываем многократно. Каждый сектор с информацией помечаем коротеньким заголовочком (порядковый номер фрагмента зашифрованного файла, например). Так, если у нас в заголовке только номер фрагмента (4 байта) и хэш-сумма содержимого (16 байт), то полезная нагрузка одного сектора будет 512-20 = 492 байта.
    Вот и все.
    Теперь создаем в этом разделе файловую систему (любую) и даже пишем на нее всякую лабуду. Главное — создавать ФС без проверки секторов на предмет битости, т.к. в этом случае все секторы раздела будут перезаписаны.

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

    И не надо никакие битмапы искать и анализировать, не надо разбираться в особенностях конкретных файловых систем.


    1. Kazmal Автор
      26.01.2018 17:46
      +1

      Спасибо, мысль интересная. Но мы можем быть совсем невезучими, и какой-то блок все же будет перезаписан. Да и в случае, если образ такой ФС попадёт кому-то на анализ, полное отсутствие пустых блоков сразу вызовет подозрение, особенно если ФС была создана недавно.


      1. Deosis
        29.01.2018 09:27

        ФС вообще не знает про данные. Поэтому такой метод не повлияет на список пустых блоков.


        ПС. Так как размеры файлов не всегда совпадают с размером блоков, то информацию можно скрывать в таких "хвостах".


    1. mibori
      29.01.2018 18:47

      Дарю простой и универсальный метод стеганографии, не зависящий от файловой системы

      1. вы уверены, что будет работать на HFS+Filevault2 и APFS?
      2. есть имплементации?


      1. berez
        29.01.2018 22:23

        вы уверены, что будет работать на HFS+Filevault2 и APFS?

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

        есть имплементации?

        Не знаю. Возможно, кто-то уже делал что-то подобное. Я лично предпочитаю не прятать шифрованные файлы — пусть себе выглядят как испорченные, мало ли что с флэшкой стряслось. :)
        Накидать прототипчик на основе кода, имеющегося в статье, нетрудно при желании.


  1. berez
    26.01.2018 18:50

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

    Должен быть перезаписан не просто один блок, а все блоки с одним и тем же фрагментом зашифрованного файла. Это весьма маловероятно, особенно если копий разбросано несколько десятков по всему разделу — файловой системе придется «прицельно» размазывать файлы по всему пространству раздела. Большинство файловых систем располагают файлы достаточно компактно.

    Да и в случае, если образ такой ФС попадёт кому-то на анализ, полное отсутствие пустых блоков сразу вызовет подозрение, особенно если ФС была создана недавно.

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

    Да и — скажем честно — если флэшку кто-то изучает настолько пристально, что вручную разбирается с пустым пространством — для нашего Штирлица это уже провал. Поздно утюги на подоконнике рядами выставлять. :)


    1. Kazmal Автор
      26.01.2018 20:27

      По поводу блоков — я имел ввиду, что мы будем совсем невезучими, но это, конечно, маловероятно.

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

      Но ещё раз повторюсь, мысль интересная.


      1. berez
        29.01.2018 18:16

        А насчёт пристального изучения, просто по образу ФС отсутствие пустых блоков будет более подозрительно.

        Пристальное изучение раздела на уровне секторов и пустых мест — это уже провал резидента. :)
        Но вообще можно возразить. После создания ФС пустое место вовсе не обязательно должно содержать нули или один и тот же байт. Раздел ведь мог раньше содержать, скажем, рипы с блюрея — а это много-много практически рандомных байт.
        Так что отмазка в стиле «а, так я на этой флэшке раньше киношки держал» — вполне себе правдоподобная. Правда, не получится старое содержимое восстановить программами-восстанавливалками, но это оч-чень косвенная улика.

        (тем более, что там будет много повторяющихся блоков)

        Не будет, если при шифровании подмешивать порядковый номер сектора, как я упоминал. Скажем, перед шифрованием содержимое сектора XOR'им с порядковым номером сектора на диске, потом шифруем. В результате содержимое секторов с одинаковыми данными будет различным — номера-то различаются.


  1. pansa
    26.01.2018 23:55

    Занятно, но вот зашифрованные AES участи будут в свою очередь выделяться высокой энтропией, что будет бросаться в глаза не меньше, особенно, если кто специально ищет. imho.


    1. berez
      29.01.2018 18:09

      Энтропия видеофайлов тоже вполне себе на уровне. Достаточно записать на ФС несколько видеороликов. :)