Многие могли слышать о таких файлах, как rarjpeg'и. Это особый вид файлов, представляющий собой склеенную вплотную jpeg-картинку и rar-архив. Он является прекрасным контейнером для скрытия факта передачи информации. Создать rarjpeg можно с помощью следующих команд:
UNIX: cat image1.jpg archive.rar > image2.jpg
WINDOWS: copy /b image1.jpg+archive.rar image2.jpg
Или же при наличии hex-редактора.
Разумеется, для скрытия факта передачи информации можно использовать не только формат JPEG, но и многие другие. Каждый формат имеет свои особенности, благодаря которым он может подходить или нет для роли контейнера. Я опишу, как можно найти приклеенные файлы в наиболее популярных форматах или же указать на факт склейки.
Методы детектирования склеенных файлов можно разделить на три группы:
- Метод проверки области после EOF-маркера. Множество популярных форматов файлов имеют так называемый маркер конца файла, который отвечает за отображение нужных данных. Например, программы для просмотра фотографий считывают все байты вплоть до этого маркера, однако, область после него остается игнорируемой. Этот метод идеально подходит для форматов: JPEG, PNG, GIF, ZIP, RAR, PDF.
- Метод проверки размера файла. Структура некоторых форматов (аудио- и видеоконтейнеры) позволяет вычислить реальный размер файла и сравнить его с исходным размером. Форматы: AVI, WAV, MP4, MOV.
- Метод проверки CFB-файлов. CFB или Compound File Binary Format — формат документов, разработанный в Microsoft, представляющий собой контейнер с собственной файловой системой. Этот метод основан на обнаружении аномалий в файле.
Есть ли жизнь после конца файла?
JPEG
Для нахождения ответа на этот вопрос, необходимо углубиться в спецификации формата, который является «родоначальником» склеенных файлов и понять его структуру. Любой JPEG начинается с сигнатуры 0xFF 0xD8.
После этой сигнатуры находится служебная информация, опционально иконка изображения и, наконец, само сжатое изображение. В этом формате конец изображения отмечается двухбайтной сигнатурой 0xFF 0xD9.
PNG
Первые восемь байт PNG-файла занимает следующая сигнатура: 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A. Сигнатура конца, которая заканчивает поток данных: 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82.
RAR
Общая сигнатура для всех rar-архивов: 0x52 0x61 0x72 0x21 (Rar!). После неё идет информация о версии архива и прочие сопутствующие данные. Опытным путем было установлено, что архив заканчивается сигнатурой 0x0A, 0x25, 0x25, 0x45, 0x4F, 0x46.
Таблица форматов и их сигнатур:
Формат | Начальная сигнатура | Конечная сигнатура |
---|---|---|
JPEG | 0xFF 0xD8 | 0xFF 0xD9 |
PNG | 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A | 0x49 0x45 0x4E 0x44 0xAE 0x42 0x60 0x82 |
RAR | 0x52 0x61 0x72 0x21 | 0x0A 0x25 0x25 0x45 0x4F 0x46 |
- Найти начальную сигнатуру;
- Найти конечную сигнатуру;
- Если после конечной сигнатуры нет данных — ваш файл чист и не содержит вложений! В ином случае необходимо искать после конечной сигнатуры другие форматы.
GIF и PDF
Формат | Начальная сигнатура | Конечная сигнатура |
---|---|---|
GIF | 0x47 0x49 0x46 0x38 | 0x00 0x3B |
0x25 0x50 0x44 0x46 | 0x0A 0x25 0x25 0x45 0x4F 0x46 |
- Пункт 1 повторяется из предыдущего алгоритма.
- Пункт 2 повторяется из предыдущего алгоритма.
- При нахождении конечной сигнатуры запомнить её расположение и искать дальше;
- Если таким образом дошли до последнего EOF-маркера — файл чист.
- Если файл не заканчивается конечной сигнатурой — goto место последней найденной конечной сигнатуры.
Большая разница между размером файла и позицией после последней конечной сигнатуры указывает на наличие приклеенного вложения. Разница может составлять больше десяти байт, хотя возможна установка иных значений.
ZIP
Особенность ZIP-архивов заключается в наличие трех различных сигнатур:
Сигнатуры | Описание |
---|---|
0x50 0x4B 0x03 0x04 | Сигнатура обычного архива |
0x50 0x4B 0x05 0x06 | Сигнатура пустого архива |
0x50 0x4B 0x07 0x08 | Сигнатура архива, разделенного на части |
Local File Header 1 |
File Data 1 |
Data Descriptor 1 |
Local File Header 2 |
File Data 2 |
Data Descriptor 2 |
... |
Local File Header n |
File Data n |
Data Descriptor n |
Archive decryption header |
Archive extra data record |
Central directory |
Для проверки ZIP-архива необходимо найти конечную сигнатуру центральной директории, пропустить 18 байт и искать сигнатуры известных форматов в области комментария. Большой размер комментария также свидетельствует о факте склейки.
Размер имеет значение
AVI
Структура AVI-файла следующая: каждый файл начинается с сигнатуры RIFF (0x52 0x49 0x46 0x46). На 8 байте идет уточняющая формат сигнатура AVI (0x41 0x56 0x49 0x20). Блок на смещении 4, состоящий из 4 байт, содержит начальный размер блока данных (порядок байт — little endian). Чтобы узнать номер блока, содержащего следующий размер, необходимо сложить размер заголовка (8 байт) и размер, полученный в блоке 4-8 байт. Таким образом вычисляется полный размер файла. Допускается, что вычисленный размер может быть меньше, чем реальный размер файла. После вычисленного размера файл будет содержать только нулевые байты (необходимо для выравнивания границы в 1 Кб).
Пример вычисления размера:
Смещение | Размер | Следующее смещение |
---|---|---|
4 | 31442 | 8+31442=31450 |
WAV
Как и AVI, WAV-файл начинается с сигнатуры RIFF, однако, у этого файла сигнатура с 8 байта — WAVE (0x57 0x41 0x56 0x45). Размер файла вычисляется таким же образом, как и AVI. Реальный размер должен полностью совпадать с вычисленным.
MP4
MP4 или MPEG-4 – формат медиаконтейнера, используемый для хранения видео- и аудиопотоков, также предусматривает хранение субтитров и изображений.
На смещении 4 байта расположены сигнатуры: тип файла ftyp (66 74 79 70) (QuickTime Container File Type) и подтип файла mmp4 (6D 6D 70 34). Для распознания скрытых файлов, нас интересует возможность вычисления размера файла.
Рассмотрим пример. Размер первого блока находится на нулевом смещении, и он равен 28 (00 00 00 1С, порядок байт Big Endian); он же указывает на смещение, где находится размер второго блока данных. На 28 смещении находим следующий размер блока равный 8 (00 00 00 08). Чтобы найти следующий размер блока, необходимо складывать размеры найденных предыдущих блоков. Таким образом, вычисляется размер файла:
Смещение | Значение | Следующее смещение |
---|---|---|
0 | 28 | 28+0=28 |
28 | 8 | 28+8=36 |
36 | 303739 | 36+303739=303775 |
303775 | 6202 | 303775+6202=309977 |
MOV
Этот широко используемый формат является также контейнером MPEG-4. MOV использует проприетарный алгоритм сжатия данных, имеет похожую на MP4 структуру и используется в тех же целях — для хранения аудио и видеоданных, а также сопутствующих материалов.
Как и MP4, любой mov-файл имеет на 4 смещении 4-х байтную сигнатуру ftyp, однако, следующая сигнатура имеет значение qt__ (71 74 20 20). Правило вычисления размера файла не изменилось: начиная с начала файла вычисляем размер следующего блока и складываем.
Метод проверки этой группы форматов на наличие «приклеенных» файлов заключается в вычислении размера по заданным выше правилам и сравнении его с размером проверяемого файла. Если текущий размер файла много меньше вычисленного, то это указывает на факт склейки. При проверке AVI-файлов допускается, что вычисленный размер может быть меньше размера файла из-за наличия добавленных нулей для выравнивания границы. В таком случае, необходимо проверять нули после вычисленного размера файла.
Проверяем Compound File Binary Format
Этот формат файла, разработанный в Microsoft, также известен под названием OLE (Object Linking and Embedding) или COM (Component Object Model). Файлы DOC, XLS, PPT принадлежат к группе CFB-форматов.
CFB-файл состоит из 512-байтного заголовка и секторов одинаковой длины, хранящих потоки данных или служебную информацию. Каждый сектор имеет свой собственный неотрицательный номер, исключение составляют специальные номера: «-1» — нумерует свободный сектор, «-2» — нумерует сектор, замыкающий цепочку. Все цепочки секторов определены в FAT-таблице.
Предположим, что злоумышленник модифицировал некий doc-файл и вклеил в его конец другой файл. Есть несколько различных способов его обнаружить или указать на аномалию в документе.
Аномальный размер файла
Как было сказано выше, любой CFB-файл состоит из заголовка и секторов равной длины. Чтобы узнать размер сектора, необходимо считать двухбайтное число на 30 смещении от начала файла и возвести 2 в степень этого числа. Данное число должно быть равно или 9 (0x0009), или 12 (0x000C), соответственно, размер сектора файла равен 512 или 4096 байт. После нахождения сектора необходимо проверить следующее равенство:
(FileSize — 512) mod SectorSize = 0
Если это равенство не выполняется, то можно указать на факт склейки файлов. Однако этот метод имеет существенный недостаток. Если злоумышленник знает размер сектора, то ему достаточно приклеить свой файл и ещё n байт, чтобы величина приклеенных данных была кратна размеру сектора.
Неизвестный тип сектора
Если злоумышленник знает о методе обхода предыдущей проверки, то данный метод может детектировать наличие секторов с неопределенными типами.
Определим равенство:
FileSize = 512 + CountReal * SectorSize, где FileSize — размер файла, SectorSize — размер сектора, CountReal — количество секторов.
Определим также следующие переменные:
- CountFat – количество секторов FAT. Находится на 44 смещении от начала файла (4 байта);
- CountMiniFAT – количество секторов MiniFAT. Находится на 64 смещении от начала файла (4 байта);
- CountDIFAT – количество секторов DIFAT. Находится на 72 смещении от начала файла (4 байта);
- CountDE – количество секторов Directory Entry. Для нахождения этой переменной необходимо найти первый сектор DE, который находится на 48 смещении. Затем необходимо получить полное представление DE из FAT и посчитать число DE-секторов;
- CountStreams – количество секторов с датастримами;
- CountFree – количество свободных секторов;
- CountClassified – количество секторов с определенным типом;
CountClassified = CountFAT + CountMiniFAT + CountDIFAT + CountDE + CountStreams + CountFree
Очевидно, что при неравенстве CountClassified и CountReal можно сделать вывод о возможной склейке файлов.
Использованные источники:
Разбор структуры MP4
Разбор структуры AVI
Разбор структуры MOV
Разбор структуры WAV
O-checker: Detection of Malicious Documents through Deviation from File Format Specifications
Спецификации формата GIF
Спецификации формата PDF
Статья про JPEG на Википедии
Разбор структуры ZIP
Комментарии (27)
al_sh
04.09.2017 13:35В jpeg далеко не всегда файл заканчивается 0xFF 0xD9. Можете снести их и файл откроется в большинстве смотрелок. Этим грешат некоторые мобилки.
Tsyganov_M Автор
04.09.2017 14:34Ценное замечание. Однако сделан расчет на то, что злоумышленник не будет каким-либо образом модифицировать файл исходного формата, кроме как приклеивать вложение. Если же конечная сигнатура была удалена, то можно попробовать найти вложение простым сигнатурным поиском по файлу.
qw1
04.09.2017 23:06А не будет ли наоборот, ложных срабатываний, потому что маркер FF D9 просто статистически встретится внутри huffman-потока? Я взял несколько больших jpeg и пару раз нашёл FF D9 в середине файла
Tsyganov_M Автор
05.09.2017 00:59Если FF D9 встречается несколько раз, то можно проверять jpeg по принципу pdf и gif, где их "конечные" сигнатуры могут повторяться. Даже если будет не последний FF D9 будет найден, то после него область файла будет проверяться поиском сигнатур, длина которых от 4 байт и выше. Вероятность ЛПС в таком случае крайне невысокая.
nvv
04.09.2017 16:58Что делать если «злоумышленник» приклеит «нагрузку» к обычному файлу TXT, который по определению не имеет заранее заданного формата?
Просматривать всё содержимое таких файлов, независимо от размера, на предмет поиска известных сигнатур и пытаться выделить файлы по сигнатурам для подтверждения гипотезы?
al_sh
04.09.2017 17:02ну конкретно для тхт ИМХО индикатором может служить символ не входящий в кодировку
lostpassword
05.09.2017 07:48Перегнать предварительно данные в Base64 — и нет проблем.)
Хотя это тоже можно будет детектировать, конечно. Но есть и другие способы кодирования.
nvv
04.09.2017 17:09В кодировку чего?
txt может быть и в UTF и в ANSI и в др.кодировке кодировке.al_sh
04.09.2017 17:21Ок. В случае, если Вы знаете или можете определить в какой кодировке у Вас файл. Более того, в качестве гипотезы, вполне вероятно, что существует сочетания, которых нет ни в одной распространенной кодировке.
qw1
04.09.2017 23:04К текстам надо приклеивать base64-encoded данные.
Или, чтобы не было подозрений на слишком длинные строки, кодировать в UUE
vesper-bot
04.09.2017 18:07Если при парсинге в мультибитовую кодировку в массиве символов оказываются 0х00-0x1F, исключая 0x0D и 0x0A, это скорее всего бинарник. При этом проверять имеет смысл всего три — UTF8LE, UTF8BE, UTF16 (она ЕМНИП только LE).
nvv
04.09.2017 20:28А если это win1251 или koi8-r окажется?
vesper-bot
05.09.2017 09:09А разве в них как в массиве байт в нормальном виде есть 0х00-0x1F, исключая 0x0D и 0x0A? Другое дело, если этот текстовик будет на каком-нибудь 05AB1E, где уже вполне могут попадаться символы из этого диапазона. Однако процент текстовых файлов на всяких экзотических ЯП вроде этого позволяет им пренебречь при анализе потенциально склеенных файлов.
thelongrunsmoke
04.09.2017 21:28+1С точки зрения борьбы с zip-бомбой такие проверки подойдут, но есть более изящные средства. С точки зрения поиска стеганографических весселов, существует много способов сокрытия, и создать графический файл содержащий в себе, скажем, архив и проходящей проверки на структуру вполне возможно.
Однако, для хранения, изображения и видео всё равно надо перекодировать, при определённых настройках, любая сокрытая информация будет потеряна.
qw1
04.09.2017 23:07Предположим, что злоумышленник модифицировал некий doc-файл и вклеил в его конец другой файл
Разумнее класть новый файл сразу в файловую систему Compound. Или даже не в новый файл, а по принципу rarjpeg в один из объектов контейнера.Tsyganov_M Автор
05.09.2017 01:08В данной статье я описал не способы сокрытия файлов, но методы обнаружения вложений, которые приклеены к концу файла, а не внедрены в его структуру в качестве составной части.
impfromliga
05.09.2017 05:16Это интересно, но мой стеганограф написанный еще в лохматом году на бейсике не возьмет.
Не кидайте кирпичи, я не критикую статью, сам такие методы поиска не знал, просто дополняю что есть способы спрятать и по лучше.
На мой взгляд такой вид сокрытия даты слишком наивен.
Я складывал в младшие значащие биты png (визуально незаметно, к тому же если это фото там есть естественный шум матрицы) к слову сказать спрятать дату можно абсолютно в любой медийный формат допускающий субъективно незаметные огрехи.
Для jpeg'а только пришлось бы внедриться в формат кодирования. Найти в нем парные взаимоисключающие условия и на стадии кодирования подменять их в обход правильного кодирования (только в местах мало влияющих на визуальный результат) своим выбором
И в jpeg конечно можно внедрить значительно меньше даты без видимых артефактов
Я видал стеганографф даже для mp3
В простейшем случае для mp3 берется малораспространенный ABR (Avarage Bit Rate) — его суть в том, что он берет для фрейма строго заданный размер. (И чем же это отличается от CBR спросите вы) Дело в том, что он продолжает пытаться сжать сильнее (например тишину), и оставшееся место накапливает, для расширения следующих фреймов. (Само собой это означало бы невозможность реалтаймового кодирования с трансляцией, ведь данные для будущих фреймов должны были бы содержаться в уже переданных) Но еще он ограничивает возможность подключать оставшееся место дальше чем условно на время t. Таким образом он все таки может передаваться почти реалтаймово, с «пингом» воспроизведения в несколько секунд. (Естественно это юзалось в основном при потоковом прослушивании напрмер радиостанций, но не колл-войса)
Так вот, в связи с тем, что периодически этот формат теряет «запасы» слишком далеких полупустых фреймов, туда можно свободно записать что угодно.
Хотя даже этот метод с mp3 ближе к вашему описанию, и послабее защищен чем кодирование «со специальными ошибками» (естественно и для классического cbr/vbr можно реализовать мудреный алг «ошибочного кодирования», но это потребует разбираться в формате досконально)thelongrunsmoke
05.09.2017 07:16Речь идёт не о полноценной стеганографии, а исключительно о составных файлах.
Tsyganov_M Автор
05.09.2017 17:40Благодарю за дополнение, однако, те методы, что вы описали, не совсем подходят под тематику статьи, поскольку в них происходит внедрение в структуру файла, а не склейка, как я уже писал выше. Также, как я понял, это методы скрытия информации, а не обнаружения.
DimonSmart
05.09.2017 07:16Приложу ссылочку на ещё одну интересную методику сокрытия информации:
http://old.computerra.ru/gid/rtfm/office/327832/
Было бы очень интересно услышать комментарии авторов на эту тему.DimonSmart
05.09.2017 07:21+1Склеивание файлов
Возможно ссылка не совсем точная. Но суть в том, что используя особенности контейнера можно сделать файл, котрый будет _одновременно_ и word и excel и при открытии соответствующей программой будет работать и так и так. Но по расширению то это один файл! и сложно догадаться проверить например word на предмет возможности открытия его как excel.
Было бы очень интересно услышать комментарии авторов на эту тему.
Tsyganov_M Автор
05.09.2017 17:46В материале по данной ссылке не описана подробная методика сокрытия doc файла в xls, а скорее гайд, как пользоваться готовой программой, принцип работы которой не раскрывается.
Andrew1411
07.09.2017 11:51Формат CFB позволяет внедрить в его внутреннюю файловую систему «нагрузку». Лет 6 назад проверял, запихифая из плагина для фар в doc файл и .zip и .exe. Word при открытии «нагруженных» документов молчал, никак не замечая нагрузку.
teecat
Эх чуть бы пораньше. Буквально пару дней назад искал такую информацию, чтобы объяснить подобное на пальцах.
Но все равно спасибо!
Tsyganov_M Автор
Надеюсь, материал вам пригодится.