Что такое сигнатура файла. Сигнатурные дела: Анализатор файлов и антивирус — своими руками

Начальство поставило мне довольно интересную задачу. В сжатые сроки написать анализатор исполняемых файлов, который по сигнатурам умел бы находить тела вирусов и определять используемый упаковщик/криптор. Готовый прототип появился уже через пару часов.

Слово автора

Сигнатурный анализ

Поиск вредоносного объекта по сигнатурам - это то, что умеет любой антивирус. В общем случае сигнатура - это формализованное описание некоторых признаков, по которым можно определить, что сканируемый файл - это вирус и вирус вполне определенный.

Тут есть различные методики. Как вариант - использовать сигнатуру, составленную из N байт вредоносного объекта. При этом можно сделать не тупое сравнение, а сравнение по некоторой маске (типа искать байты EB ?? ?? CD 13). Или задавать дополнительные условия вроде «такие-то байты должны находиться у точки входа в программу» и так далее. Сигнатура именно малвари - это частность.

Точно так же описываются некоторые признаки, по которым можно определить, что исполняемый файл упакован тем или иным криптором или упаковщиком (например, банальным ASPack). Если ты внимательно читаешь наш журнал, то точно слышал о такой тулзе как PEiD, способной определять наиболее часто используемые упаковщики, крипторы и компиляторы (в базе есть большое количество сигнатур) для переданного ей PE-файла. Увы, новые версии программы давно не выходят, а недавно на официальном сайте и вовсе появилось сообщение, что дальнейшего развития у проекта не будет. Жаль, потому что возможности PEiD (особенно учитывая систему плагинов) вполне могли оказаться мне полезными. После недолгого анализа все-таки стало ясно, что это не вариант. Но покопавшись в англоязычных блогах, я быстро нашел то, что мне подошло. Проект YARA (code.google.com/p/yara-project).

Что такое YARA?

Я был с самого начала убежден, что где-то в Сети уже есть открытые разработки, которая бы взяли на себя задачу определения соответствия между некоторой сигнатурой и исследуемым файлом. Если бы я смог найти такой проект, то его легко можно было бы поставить на рельсы веб-приложения, добавить туда разных сигнатур и получить то, что от меня требовалось. План стал казаться еще более реальным, когда я прочитал описание проекта YARA.

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

Если для исследуемого файла выполняются условия одного из правил, он определяется соответствующим образом (к примеру, червь такой-то). Простой пример правила, чтобы понимать, о чем идет речь:

rule silent_banker: banker
{
meta:
description = "This is just an example"
thread_level = 3
in_the_wild = true
strings:
$a = {6A 40 68 00 30 00 00 6A 14 8D 91}
$b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
$c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
condition:
$a or $b or $c
}

В этом правиле мы говорим YARA, что любой файл, который содержит хотя бы одну из строк-семплов, описанных в переменных $a, $b, $c, должен классифицироваться как троян silent_banker. И это очень простое правило. На деле рулесы могут быть гораздо сложнее (мы об этом поговорим ниже).
Об авторитете проекта YARA говорит уже даже список проектов, которые его используют, а это:

  • VirusTotal Malware Intelligence Services (vt-mis.com);
  • jsunpack-n (jsunpack.jeek.org);
  • We Watch Your Website (wewatchyourwebsite.com).

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

Немного покопавшись, я довольно быстро разобрался, как писать для YARA правила, а также как прикрутить к нему сигнатуры вирусов от бесплатного авера и упаковщиков от PEiD. Но начнем мы с установки.

Установка

Как я уже сказал, проект написан на Python’е, поэтому легко может быть установлен и на Linux, и на Windows, и на Mac. На первых порах можно просто взять бинарник. Если вызвать приложение в консоли, то получим правила для запуска.

$ yara
usage: yara ... ... FILE | PID

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

Свой антивирус

Самый главный вопрос: где взять базу сигнатур известных вирусов? Антивирусные компании активно делятся такими базами между собой (кто-то более щедро, кто-то - менее). Если честно, я поначалу даже сомневался, что где-то в Сети кто-то открыто выкладывает подобные вещи. Но, как оказалось, есть добрые люди. Подходящая база из популярного антивируса ClamAV доступна всем желающим (clamav.net/lang/en). В разделе «Latest Stable Release» можно найти ссылку на последнюю версию антивирусного продукта, а также ссылки для скачивания вирусных баз ClamAV. Нас прежде всего будут интересовать файлы main.cvd (db.local.clamav.net/main.cvd) и daily.cvd (db.local.clamav.net/daily.cvd).

Первый содержит основную базу сигнатур, второй - самую полную на данный момент базу с различными дополнениями. Для поставленной цели вполне хватит daily.cvd, в котором собрано более 100 000 слепков малвари. Однако база ClamAV - это не база YARA, так что нам необходимо преобразовать ее в нужный формат. Но как? Ведь мы пока ничего не знаем ни о формате ClamAV, ни о формате Yara. Об этой проблеме уже позаботились до нас, подготовив небольшой скриптик, конвертирующий базу вирусных сигнатур ClamAV в набор правил YARA. Сценарий называется clamav_to_ yara.py и написан Мэтью Ричардом (bit.ly/ij5HVs). Скачиваем скрипт и конвертируем базы:

$ python clamav_to_yara.py -f daily.cvd -o clamav.yara

В результате в файле clamav.yara мы получим сигнатурную базу, которая сразу будет готова к использованию. Попробуем теперь комбинацию YARA и базы от ClamAV в действии. Сканирование папки с использованием сигнатуры выполняется одной единственной командой:

$ yara -r clamav.yara /pentest/msf3/data

Опция -r указывает, что сканирование необходимо проводить рекурсивно по всем подпапкам текущей папки. Если в папке /pentest/msf3/data были какие-то тела вирусов (по крайней мере тех, что есть в базе ClamAV), то YARA немедленно об этом сообщит. В принципе, это уже готовый сигнатурный сканер. Для большего удобства я написал простой скрипт, который проверял обновления базы у ClamAV, закачивал новые сигнатуры и преобразовывал их в формат YARA. Но это уже детали. Одна часть задачи выполнена, теперь можно приступать к составлению правил для определения упаковщиков/крипторов. Но для этого пришлось немного с ними разобраться.

Игра по правилам

Итак, правило - это основной механизм программы, позволяющий отнести заданный файл к какой-либо категории. Правила описываются в отдельном файле (или файлах) и по своему виду очень напоминают конструкцию struct{} из языка С/С++.

rule BadBoy
{
strings:
$a = "win.exe"
$b = "http://foo.com/badfi le1.exe"
$c = "http://bar.com/badfi le2.exe"
condition:
$a and ($b or $c)
}

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

1. Каждое правило начинается с ключевого слова rule, после которого идет идентификатор правила. Идентификаторы могут иметь такие же имена, как и переменные в C/С++, то есть состоять из букв и цифр, причем первый символ не может быть цифрой. Максимальная длина имени идентификатора - 128 символов.

2. Обычно правила состоят из двух секций: секция определений (strings) и секция условия (condition). В секции strings задаются данные, на основе которых в секции condition будет приниматься решение, удовлетворяет ли заданный файл определенным условиям.

3. Каждая строка в разделе strings имеет свой идентификатор, который начинается со знака $ - в общем, как объявление переменной в php. YARA поддерживает обычные строки, заключенные в двойные кавычки (« ») и шестнадцатеричные строки, заключенные в фигурные скобки ({}), а также регулярные выражения:

$my_text_string = "text here"
$my_hex_string = { E2 34 A1 C8 23 FB }

4. В секции condition содержится вся логика правила. Эта секция должна содержать логическое выражение, определяющее, в каком случае файл или процесс удовлетворяет правилу. Обычно в этой секции идет обращение к ранее объявленным строкам. А идентификатор строки рассматривается в качестве логической переменной, которая возвращает true, если строка была найдена в файле или памяти процесса, и false в противном случае. Вышеуказанное правило определяет, что файлы и процессы, содержащие строку win.exe и один из двух URL, должны быть отнесены к категории BadBoy (по имени правила).

5. Шестнадцатеричные строки позволяют использовать три конструкции, которые делают их более гибкими: подстановки (wildcards), диапазоны (jumps) и альтернативный выбор (alternatives). Подстановки - это места в строке, которые неизвестны, и на их месте может быть любое значение. Обозначаются они символом «?»:

$hex_string = { E2 34 ?? C8 A? FB }

Такой подход очень удобен при задании строк, длина которых известна, а содержимое может меняться. Если же часть строки может быть разной длины, удобно использовать диапазоны:

$hex_string = { F4 23 62 B4 }

Данная запись означает, что в средине строки может быть от 4 до 6 различных байт. Можно реализовать также и альтернативный выбор:

$hex_string = { F4 23 (62 B4 | 56) 45 }

Это означает, что на месте третьего байта может быть 62 В4 или 56, такой записи соответствуют строки F42362B445 или F4235645.

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

$a at 100 and $b at 200

Если строка может находиться внутри определенного диапазона адресов, используется оператор in:

$a in (0..100) and $b in (100..fi lesize)

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

rule OfExample1
{
strings:
$foo1 = "dummy1"
$foo2 = "dummy2"
$foo3 = "dummy3"
condition:
2 of ($foo1,$foo2,$foo3)
}

Приведенное правило требует, чтобы файл содержал любые две строки из множества ($foo1,$foo2,$foo3). Вместо указания конкретного числа строк в файле можно использовать переменные any (хотя бы одна строка из заданного множества) и all (все строки из заданного множества).

7. Ну и последняя интересная возможность, которую надо рассмотреть - применение одного условия ко многим строкам. Эта возможность очень похожа на оператор of, только более мощная - это оператор for..of:

for expression of string_set: (boolean_expression)

Данную запись надо читать так: из строк, заданных в string_ set, по крайней мере expression штук должно удовлетворять условию boolean_expression. Или, другими словами: выражение boolean_expression вычисляется для каждой строки из string_set, и expression из них должны возвратить значение True. Далее мы рассмотрим эту конструкцию на конкретном примере.

Делаем PEiD

Итак, когда с правилами все стало более менее ясно, можно приступать к реализации в нашем проекте детектора упаковщиков и крипторов. В качестве исходного материала на первых порах я позаимствовал сигнатуры известных упаковщиков у все того же PEiD. В папке plugins находится файл userdb.txt, который и содержит то, что нам нужно. В моей базе оказалось 1850 сигнатур.

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


signature = 50 E8 ?? ?? ?? ?? 58 25 ?? F0 FF FF 8B C8 83 C1 60 51 83 C0 40 83 EA 06 52 FF 20 9D C3
ep_only = true

Первая строка задает имя упаковщика, которое будет отображаться в PEiD, для нас же это будет идентификатор правила. Вторая - непосредственно сама сигнатура. Третья - флаг ep_only, указывающий, искать ли данную строку только по адресу точки входа, или же по всему файлу.

Ну что, попробуем создать правило, скажем, для ASPack? Как оказалось, в этом нет ничего сложного. Сначала создадим файл для хранения правил и назовем его, например, packers.yara. Затем ищем в базе PEiD все сигнатуры, в названии которых фигурирует ASPack, и переносим их в правило:

rule ASPack
{
strings:
$ = { 60 E8 ?? ?? ?? ?? 5D 81 ED ?? ?? (43 | 44) ?? B8 ?? ?? (43 | 44) ?? 03 C5 }
$ = { 60 EB ?? 5D EB ?? FF ?? ?? ?? ?? ?? E9 }
[.. вырезано..]
$ = { 60 E8 03 00 00 00 E9 EB 04 5D 45 55 C3 E8 01 }
condition:
for any of them: ($ at entrypoint)
}

У всех найденных записей флаг ep_only установлен в true, то есть эти строки должны располагаться по адресу точки входа. Поэтому мы пишем следующее условие: «for any of them: ($ at entrypoint)».

Таким образом, наличие хоть одной из заданных строк по адресу точки входа будет означать, что файл упакован ASPack’ом. Обрати также внимание, что в данном правиле все строки заданы просто с помощью знака $, без идентификатора. Это возможно, так как в condition-секции мы не обращаемся к каким-то конкретным из них, а используем весь набор.

Чтобы проверить работоспособность полученной системы, достаточно выполнить в консоли команду:

$ yara -r packers.yara somefi le.exe

Скормив туда пару приложений, упакованных ASPack’ом, я убедился, что все работает!

Готовый прототип

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

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

Обычно для определения месторасположения файлов используется таблица разделов диска. Если сравнить диск с книгой, то таблица разделов будет аналогична ее оглавлению. При сканировании R-Studio ищет файлы известных типов в таблице разделов диска по определенным заданным сигнатурам. Это становится возможным благодаря тому, что практически каждый тип файла имеет уникальную сигнатуру или шаблон данных. Файловые сигнатуры находятся в определенном месте в начале файла и во многих случаях также и в конце файла. При сканировании R-Studio сопоставляет найденные данные с сигнатурами файлов известных типов, что позволяет их идентифицировать и восстановить их данные .

При помощи технологии сканирования файлов известных типов R-Studio позволяет восстановить данные с дисков, которые были переформатированы, а также таблицы разделов которых были перезаписаны. Более того, если раздел диска перезаписан, поврежден или удален, то сканирование файлов известных типов является единственно возможным .

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

В состав R-Studio уже включены сигнатуры наиболее распростаненных типов файлов (просмотреть полный список файлов известных типов можно в разделе R-Studio Online Справки.)

В случае необходимости пользователь может добавить новые типы файлов в состав R-Studio. Например, если необходимо найти файлы какого-либо уникального типа, или же разработанного после даты последнего выпуска R-Studio, то можно добавить в состав файлов известных типов собственные сигнатуры. Далее будет рассмотрен данный процесс.

Пользовательские Файлы Известных Типов
Пользовательские сигнатуры файлов известных типов хранятся в XML файле, заданном в диалоговом окне Настройки. Добавление сигнатуры состоит из двух частей:

  1. Определение файловой сигнатуры находящейся в начале файла и при наличии в конце файла.
  2. Создание XML файла, содержащего файловую сигнатуру и другую информацию о типе файлов.

Все это можно выполнить при помощи R-Studio. При этом вам не нужно быть специалистом в области составления (редактирования) XML документов или в области шестнадцатиричного редактирования - в данном руководстве (статье), ориентированном на пользователя самого начального уровня, будут подробно рассмотрены все этапы этого процесса.

Пример: Добавление сигнатуры для файла формата MP4 (XDCam-EX Codec)
Рассмотрим добавление файловой сигнатуры на примере файла.MP4, созданного с использованием Sony XDCAM-EX. Ею можно воспользоваться, например, в случае повреждения SD карты для , которые вы еще не успели сохранить на жестком диске компьютера.

Первый Этап: Определение Файловой Сигнатуры
Для определения файловой сигнатуры рассмотрим примеры файлов такого же формата.

Пусть это четыре видео файла с Sony XDCAM-EX:
ZRV-3364_01.MP4
ZRV-3365_01.MP4
ZRV-3366_01.MP4
ZRV-3367_01.MP4

Для удобства рассмотрения пусть это будут файлы небольшого размера. Файлы большего размера сложнее просматривать в шестнадцатиричной форме.

1. Откроем файлы в R-Studio. Для этого щелкнем по каждому файлу правой кнопкой мыши и выберем пункт Просмотр/Правка (View/Edit) контекстного меню.

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

3. Определим файловую сигнатуру в начале файла. В нашем примере она находится в самом начале файла. Обратите внимание, что так происходит не всегда - часто файловая сигнатура находится в начале файла, но не в первой строке (смещении).

Из нижеприведенных изображений следует, что содержимое всех четырех файлов различно, но все они начинаются с одной и той же файловой сигнатуры.


Кликните по изображению для его увеличения


Кликните по изображению для его увеличения


Кликните по изображению для его увеличения


Кликните по изображению для его увеличения

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

InВ текстовом виде файловая сигнатура имеет следующий вид:
....ftypmp42....mp42........free

Точками (“.”) обозначены символы, которые не могут быть представлены в текстовом виде. Поэтому необходимо также привести и шестнадцатиричный вид файловой сигнатуры:
00 00 00 18 66 74 79 6D 70 34 32 00 00 00 00 6D 70 34 32 00 00 00 00 00 00 00 08 66 72 65 65

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

На нижеприведенных изображениях выделена файловая сигнатура в конце файла:


Кликните по изображению для его увеличения


Кликните по изображению для его увеличения


Кликните по изображению для его увеличения


Кликните по изображению для его увеличения

Обратите внимание, что данные перед выделенной областью (файловая сигнатура), во всех четырех файлах одни и те же. Это техническая информация, которая не является файловой сигнатурой, но говорит о том, что все четыре снимка (файла) были сделаны при помощи одной камеры с одинаковыми параметрами. Обычно удается отличить совпадающие шаблоны с технической информацией от файловой сигнатуры. В нашем примере в последней строке до начала файловой сигнатуры мы видим текст ‘RecordingMode type=”normal”’, который явно говорит о том, что это какой-то параметр файла, а не сигнатура. Всегда обращайте особое внимание на эту строку, чтобы ошибочно не включить техническую информацию в состав файловой сигнатуры.

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

В шестнадцатиричном виде файловая сигнатура имеет следующий вид:
3N 2F 4E 6F 6E 52 65 61 6N 54 69 6A 65 4A 65 74 61 3E 0D 0A 00
Обратите внимание: в конце файла сигнатура будет не всегда.

Второй Этап: Создание XML файла, описывающего Известный Тип Файлов
Теперь, определив файловую сигнатуру, можно создать XML файл и включить соответствующий тип файлов в состав R-Studio. Это можно сделать двумя способами:

2.1 Используя встроенный графический редактор файловых сигнатур:
Выберите пункт Настройки (Settings) меню Инструменты (Tools), в открывшемся диалоговом окне Настройки (Settings) щелкните по вкладке Известные типы файлов (Known Files Types) и далее нажмите кнопку Редактировать... (Edit User’s File Types).

Кликните по изображению для его увеличения

Нажмите кнопку Создать тип файла (Create File Type) в диалоговом окне Редактирование пользовательских типов (Edit User"s File Types).
Задайте следующие параметры:

  • Id - уникальный цифровой идентификатор. Данное число будет выбрано произвольно; единственное, оно не должно совпадать с цифровым идентификатором какого-либо другого типа файлов.
  • Group Description - группа, в которой будут находится найденные файлы в R-Studio. Можно задать либо новую группу, либо выбрать одну из тех которые уже есть. У нас это будет группа “Multimedia Video (Мультимедиа: Видео)”.
  • Description - краткое описание типа файлов. В нашем примере можно использовать, например, "Sony cam video, XDCam-EX".
  • Extension - расширение файлов данного типа. В нашем случае - mp4.

Параметр Свойства (Features) необязательный, в нашем случае нам не нужно его использовать.

Кликните по изображению для его увеличения

Далее необходимо ввести начальную и конечную файловую сигнатуру. Для этого выберите Начало (Begin) и далее в контекстном меню команду Добавить сигнатуру (Add Signature).

Кликните по изображению для его увеличения

Затем дважды щелкните по полю <пустая сигнатура> () и введите соответствующий текст.

Кликните по изображению для его увеличения

Затем создайте конечную файловую сигнатуру. Не забудьте ввести 21 в поле столбца От (From).

Кликните по изображению для его увеличения

Вы успешно создали собственную сигнатуру файлов известного типа.

Теперь необходимо ее сохранить. Есть два способа: вы можете либо сохранить ее в файл по умолчанию заданный на вкладке Главная (Main) диалогового окна Настройки (Settings) нажав на кнопку Сохранить (Save). Либо нажать на кнопку Сохранить как... (Save As...) и сохранить сигнатуру в какой-либо другой файл.

2.2 Создание XML файла, описывающего Известный Тип Файлов, вручную:
Для создания данного файла воспользуемся XML версией 1.0 и кодировкой UTF-8. Не отчаивайтесь, если вы не знаете, что это такое, - просто откройте любой текстовый редактор (например, Notepad.exe) и в первой строке ввести следующий текст:

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

Вставим его сразу после

Далее определим файловую сигнатуру (тег ). Начальная сигнатура (в начале файла), будет находиться внутри тега без каких-либо атрибутов. Используем текстовый вид сигнатуры, но при этом заменив шестнадцатиричными символы, которые не могут быть представлены в текстовом виде. Перед каждым шестнадцатиричным символом вставим "\x" Таким образом тег с файловой сигнатурой будет выглядеть следующим образом:

В случае наличия необходимо также определить конечную сигнатуру (в конце файла). Для этого используется тот же тег, но с элементом "from" и атрибутом "end". Это будет выглядеть следующим образом:

Вспомните, что в конечной файловой сигнатуре не было нетекстовых символов, однако был слеши и треугольные скобки. Чтобы избежать путаницы и ошибок в синтаксисе XML мы заменим в сигнатуре символы "/", "<" и ">" их шестнадцатиричными значениями.

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

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


\x00\x00\x00\x18ftypmp42\x00\x00\x00\x00mp42\x00\x00\x00\x00\x00\x00\x00\x08free
\x3C\x2FNonRealTimeMeta\x3E\x0D\x0A\x00

Помните: синтаксис XML чувствителен к регистру, следовательно, правильным будет являться тег , а не .

Сохраним файл в текстовом формате с расширением.xml. Например: SonyCam.xml.

Мы успешно создали собственную сигнатуру файлов известного типа. Данный пример вполне достаточен для понимания основных принципов создания пользовательского типа файлов. Более опытные пользователи могут использовать XML версии 2.0. Подробнее об этом можно прочесть в разделе R-Studio online Справки.

Этап 3: Проверка и Добавление Файла, описывающего Известный Тип Файлов
На следующем этапе необходимо добавить (загрузить) ваш XML файл в R-Studio. При этом он будет автоматически проверен.

Загрузим в R-Studio созданный на предыдущем этапе XML файл. Для этого выберем пункт Настройки (Settings) меню Инструменты (Tools). В области Пользовательские типы файлов (User’s file types) вкладки Главная (Main) диалогового окна Настройки (Settings) добавим созданный нами XML файл (SonyCam.xml). Нажмем кнопку Применить (Apply).

Кликните по изображению для его увеличения

2. Ответим Да (Yes) на запрос о загрузке нового типа файлов.

Кликните по изображению для его увеличения

3. Для проверки того, что тип файлов был успешно загружен, щелкнем на вкладку Известные Типы Файлов (Known File Types) диалогового окна Настройки (Settings). Вспомните, что мы добавляли тип файлов в группу Multimedia Video (Мультимедиа: Видео). Раскрыв данную группу (папку), мы должны увидеть элемент с описанием, заданным нами при создании XML файла: Sony cam video, XDCam-EX (.mp4).

Кликните по изображению для его увеличения


Кликните по изображению для его увеличения

Если в синтаксисе файла имеются какие-либо ошибки, то вы увидите соответствующее сообщение:

Кликните по изображению для его увеличения

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

Этап 4: Тестирование файла, описывающего Известный Тип Файлов
ля проверки корректности созданного нами пользовательского типа файлов попробуем найти наши.mp4 файлы на съемном USB флеш-диске.

1. Под ОС Windows Vista или Windows 7 выполним полное (не быстрое) форматирование диска или воспользуемся утилитой очистки дискового пространства (например, R-Wipe & Clean) для полного удаления всех имеющихся на диске данных. Пусть USB диск отформитрован в FAT32 (размер искомых файлов не превышает 2 Гб).

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

3. В ОС диск будет определен как, например, логический диск F:\.

4. Запустим R-Studio. Выберем наш диск (F:\) и нажмем кнопку Сканировать (Scan)

Кликните по изображению для его увеличения

5. В диалоговом окне Сканировать (Scan) в области (File System) щелкнем на кнопку Изменить... (Change...) и снимем все флажки. Таким образом мы отключим поиск файловых систем и файлов, используя таблицу разделов.
Кликните по изображению для его увеличения

6. Установим флажок Дополнительно Искать Известные Типы Файлов (Extra Search for Known File Types). Это позволит R-Studio искать при сканировании файлы известных типов.

7. Чтобы начать сканирование нажмем кнопку Сканировать (Scan).

8. Подождем, пока R-Studio отсканирует диск. На вкладке Информация о Сканировании (Scan Information) будет отображаться ход сканирования (прогресс).


Кликните по изображению для его увеличения

9. После окончания сканирования выберем элемент Дополнительно Найденные Файлы (Extra Found Files) и дважды щелкнем по нему мышью.


Кликните по изображению для его увеличения

10. Наши тестовые файлы будут находиться в папке Sony cam video, XDCam-EX folder (или в папке под другим названием, соответствующим описанию типа файлов, заданному на Втором Этапе).


Кликните по изображению для его увеличения

Вы видите, что имена файлов, даты и месторасположение (папки) не были восстановлены, так как данная информация хранится в файловой системе. Поэтому в R-Studio автоматически каждый файл будет отображен с новым именем.

Однако видно, что содержимое файлов не повреждено. Чтобы в этом убедиться, откроем их в соответствующей программе, например VLC media player.


Кликните по изображению для его увеличения

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

Многие могли слышать о таких файлах, как rarjpeg"и. Это особый вид файлов, представляющий собой склеенную вплотную jpeg-картинку и rar-архив. Он является прекрасным контейнером для скрытия факта передачи информации. Создать rarjpeg можно с помощью следующих команд:

UNIX: cat image1.jpg archive.rar > image2.jpg
WINDOWS: copy /b image1.jpg+archive.rar image2.jpg

Или же при наличии hex-редактора.

Разумеется, для скрытия факта передачи информации можно использовать не только формат JPEG, но и многие другие. Каждый формат имеет свои особенности, благодаря которым он может подходить или нет для роли контейнера. Я опишу, как можно найти приклеенные файлы в наиболее популярных форматах или же указать на факт склейки.

Методы детектирования склеенных файлов можно разделить на три группы:

  1. Метод проверки области после EOF-маркера. Множество популярных форматов файлов имеют так называемый маркер конца файла, который отвечает за отображение нужных данных. Например, программы для просмотра фотографий считывают все байты вплоть до этого маркера, однако, область после него остается игнорируемой. Этот метод идеально подходит для форматов: JPEG, PNG, GIF, ZIP, RAR, PDF.
  2. Метод проверки размера файла. Структура некоторых форматов (аудио- и видеоконтейнеры) позволяет вычислить реальный размер файла и сравнить его с исходным размером. Форматы: AVI, WAV, MP4, MOV.
  3. Метод проверки 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.

Таблица форматов и их сигнатур:
Алгоритм проверки на склейку в данных форматах предельно прост:

  1. Найти начальную сигнатуру;
  2. Найти конечную сигнатуру;
  3. Если после конечной сигнатуры нет данных - ваш файл чист и не содержит вложений! В ином случае необходимо искать после конечной сигнатуры другие форматы.

GIF и PDF

PDF документ может иметь более одного EOF-маркера, например, из-за неправильной генерации документа. Количество конечных сигнатур в GIF-файле равно количеству кадров в нем. Исходя из особенностей этих форматов, можно улучшить алгоритм проверки наличия приклеенных файлов.
  1. Пункт 1 повторяется из предыдущего алгоритма.
  2. Пункт 2 повторяется из предыдущего алгоритма.
  3. При нахождении конечной сигнатуры запомнить её расположение и искать дальше;
  4. Если таким образом дошли до последнего EOF-маркера - файл чист.
  5. Если файл не заканчивается конечной сигнатурой - goto место последней найденной конечной сигнатуры.
Большая разница между размером файла и позицией после последней конечной сигнатуры указывает на наличие приклеенного вложения. Разница может составлять больше десяти байт, хотя возможна установка иных значений.

ZIP

Особенность ZIP-архивов заключается в наличие трех различных сигнатур:Структура архива такова:
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
Больше всего интересна центральная директория, которая содержит метаданные о файлах в архиве. Центральная директория всегда начинается с сигнатуры 0x50 0x4b 0x01 0x02 и заканчивается сигнатурой 0x50 0x4b 0x05 0x06, после которых следует 18 байт метаданных. Что интересно, пустые архивы состоят только из конечной сигнатуры и 18 нулевых байт. После 18 байт следует область комментария к архиву, которая является идеальным контейнером для скрытия файла.

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

Размер имеет значение

AVI

Структура AVI-файла следующая: каждый файл начинается с сигнатуры RIFF (0x52 0x49 0x46 0x46). На 8 байте идет уточняющая формат сигнатура AVI (0x41 0x56 0x49 0x20). Блок на смещении 4, состоящий из 4 байт, содержит начальный размер блока данных (порядок байт - little endian). Чтобы узнать номер блока, содержащего следующий размер, необходимо сложить размер заголовка (8 байт) и размер, полученный в блоке 4-8 байт. Таким образом вычисляется полный размер файла. Допускается, что вычисленный размер может быть меньше, чем реальный размер файла. После вычисленного размера файл будет содержать только нулевые байты (необходимо для выравнивания границы в 1 Кб).

Пример вычисления размера:


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). Чтобы найти следующий размер блока, необходимо складывать размеры найденных предыдущих блоков. Таким образом, вычисляется размер файла:

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 - количество секторов.

Определим также следующие переменные:

  1. CountFat – количество секторов FAT. Находится на 44 смещении от начала файла (4 байта);
  2. CountMiniFAT – количество секторов MiniFAT. Находится на 64 смещении от начала файла (4 байта);
  3. CountDIFAT – количество секторов DIFAT. Находится на 72 смещении от начала файла (4 байта);
  4. CountDE – количество секторов Directory Entry. Для нахождения этой переменной необходимо найти первый сектор DE, который находится на 48 смещении. Затем необходимо получить полное представление DE из FAT и посчитать число DE-секторов;
  5. CountStreams – количество секторов с датастримами;
  6. CountFree – количество свободных секторов;
  7. CountClassified – количество секторов с определенным типом;
CountClassified = CountFAT + CountMiniFAT + CountDIFAT + CountDE + CountStreams + CountFree

Очевидно, что при неравенстве CountClassified и CountReal можно сделать вывод о возможной склейке файлов.

Понятие «Магическое число » в программировании имеет три значения:

  • Сигнатура данных
  • Выделенные уникальные значения, которые не должны совпадать с другими значениями (например, UUID)
  • Плохая практика программирования.

Сигнатура данных

Магическое число , или сигнатура , - целочисленная или текстовая константа , используемая для однозначной идентификации ресурса или данных . Такое число само по себе не несёт никакого смысла и может вызвать недоумение, встретившись в коде программы без соответствующего контекста или комментария , при этом попытка изменить его на другое, даже близкое по значению, может привести к абсолютно непредсказуемым последствиям. По этой причине подобные числа были иронично названы магическими . В настоящее время это название прочно закрепилось как термин . Например, любой откомпилированный класс языка Java начинается с шестнадцатеричного «магического числа» 0xCAFEBABE . Второй широко известный пример - любой исполняемый файл ОС Microsoft Windows с расширением.exe начинается с последовательности байт 0x4D5A (что соответствует ASCII -символам MZ - инициалы Марка Збиковски , одного из создателей MS-DOS). Менее известным примером является неинициализированный указатель в Microsoft Visual С++ (начиная с 2005 версии Microsoft Visual Studio), который в режиме отладки имеет адрес 0xDEADBEEF .

В UNIX-подобных операционных системах тип файла обычно определяется по сигнатуре файла, вне зависимости от расширения его названия. Для интерпретации сигнатуры файла в них предусматривается стандартная утилита file .

Плохая практика программирования

Также «магическими числами» называют плохую практику программирования, когда в исходном тексте встречается числовое значение и неочевидно, что оно означает. Например, такой фрагмент, написанный на Java, будет плохим:

drawSprite (53 , 320 , 240 );

final int SCREEN_WIDTH = 640 ; final int SCREEN_HEIGHT = 480 ; final int SCREEN_X_CENTER = SCREEN_WIDTH / 2 ; final int SCREEN_Y_CENTER = SCREEN_HEIGHT / 2 ; final int SPRITE_CROSSHAIR = 53 ; ... drawSprite (SPRITE_CROSSHAIR , SCREEN_X_CENTER , SCREEN_Y_CENTER );

Теперь понятно: данная строка выводит в центр экрана спрайт - перекрестие прицела. В большинстве языков программирования все значения, используемые для таких констант, будут вычислены ещё на этапе компиляции и подставлены в места использования значений. Поэтому такое изменение исходного текста не ухудшает быстродействие программы.

Кроме того, магические числа - потенциальный источник ошибок в программе:

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

Магические числа и кроссплатформенность

Иногда магические числа вредят кроссплатформенности кода . Дело в том, что в Си в 32- и 64-битных ОС гарантируется размер типов char , short и long long , в то время как размер int , long , size_t и ptrdiff_t может меняться (у первых двух - в зависимости от предпочтений разработчиков компилятора, у последних двух - в зависимости от разрядности целевой системы). В старом или неквалифицированно написанном коде могут встречаться «магические числа», означающие размер какого-либо типа - при переходе на машины с другой разрядностью они могут привести к трудноуловимым ошибкам.

Например:

const size_t NUMBER_OF_ELEMENTS = 10 ; long a [ NUMBER_OF_ELEMENTS ]; memset (a , 0 , 10 * 4 ); // неправильно - подразумевается, что long равен 4 байтам, используется магическое число элементов memset (a , 0 , NUMBER_OF_ELEMENTS * 4 ); // неправильно - подразумевается, что long равен 4 байтам memset (a , 0 , NUMBER_OF_ELEMENTS * sizeof (long )); // не совсем правильно - дублирование имени типа (если изменится тип, то придется менять и здесь) memset (a , 0 , NUMBER_OF_ELEMENTS * sizeof (a [ 0 ])); // правильно, оптимально для динамических массивов ненулевого размера memset (a , 0 , sizeof (a )); // правильно, оптимально для статических массивов

Числа, которые не являются магическими

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

The function code (FC) in the telegram header identifies the telegram type, such as Request telegram (Request or Send/Request) and Acknowledgement or Response telegram (Acknowledgement frame, Response frame). In addition the function code contains the actual transmission function and control information that prevent loss and duplication of messages, or the station type with FDL status .

7 6 5 4 3 2 1 0 FC: Function Code Request
1 Request Telegramm
X FCV = Alternating bit switched on
X href=»http://profibus.felser.ch/en/funktionscode.htm#aufruffolgebit»>FCB = Alternating bit (from frame count)
1 0 (0x0) CV = Clock Value ()
1 other Reserved
0 0 (0x0) TE = Time Event (Clock synchronization)
0 3 (0x3) SDA_LOW = Send Data Acknowledged — low priority
0 4 (0x4) SDN_LOW = Send Data Not acknowledged — low priority
0 5 (0x5) SDA_HIGH = Send Data Acknowledged — high priority
0 6 (0x6) SDN_HIGH = Send Data Not acknowledged
0 7 (0x7) MSRD = Send Request Data with Multicast Reply
0 9 (0x9) Request FDL Status
0 12(0xC) SRD low = Send and Request Data
0 13(0xD) SRD high = Send and Request Data
0 14(0xE) Request Ident with reply
0 15 (0xF) Request LSAP Status with reply 1)
0 other Reserved

1) this value is in the last version of the standard not defined anymore but only reserved

7 6 5 4 3 2 1 0 FC: Function Code Response
0 Response telegram
0 Reserved
0 0 Slave
0 1 Master not ready
1 0 Master ready, without token
1 1 Master ready, in token ring
0 (0x0) OK
1 (0x1) UE = User Error
2 (0x2) RR = No resources
3 (0x3) RS = SAP not enabled
8 (0x8) DL = Data Low (normal case with DP)
9 (0x9) NR = No response data ready
10(0xA) DH = Data High (DP diagnosis pending)
12(0xC) RDL = Data not received and Data Low
13(0xD) RDH = Data not received and Data High
other Reserved

Frame Count Bit The frame count bit FCB (b5) prevents message duplication by the acknowledging or responding station(responder) and any loss by the calling station (initiator). Excluded from this are requests without acknowledgement (SDN) and FDL Status, Ident and LSAP Status requests.

For the security sequence, the initiator must carry an FCB for each responder. When a Request telegram (Request or Send/Request) is sent to a responder for the first time, or if it is re-sent to a responder currently marked as non-operational, the FCB must be set as defined in the responder. The initiator achieves this in a Request telegram with FCV=0 and FCB=1. The responder must assess a telegram of this kind as the first message cycle and store the FCB=1 together with the initiator’s address (SA) (see following table). This message cycle will not be repeated by the initiator. In subsequent Request telegrams to the same responder, the initiator must set FCV=1 and change the FCB with each new Request telegram. Any responder that receives a Request telegram addressed to it with FCV=1 must evaluate the FCB. If the FCB has changed when compared with the last Request telegram from the same initiator (same SA), this is valid confirmation that the preceding message cycle was concluded properly. If the Request telegram originates from a different initiator (different SA), evaluation of the FCB is no longer necessary. In both cases, the responder must save the FCB with the source SA until receipt of a new telegram addressed to it. In the case of a lost or impaired acknowledgement or response telegram, the FCB must not be changed by the initiator in the request retry: this will indicate that the previous message cycle was faulty. If the responder receives a Request telegram with FCV=1 and the same FCB as the last Request telegram from the same initiator (same SA), this will indicate a request retry. The responder must in turn retransmit the acknowledgement or response telegram held in readiness. Until the above-mentioned confirmation or receipt of a telegram with a different address (SA or DA) that is not acknowledged (Send Data with No Acknowledge, SDN) the responder must hold the last acknowledgement or response telegram in readiness for any possible request retry. In the case of Request telegrams that are not acknowledged and with Request FDL Status, Ident, and LSAP Status, FCV=0 and FCB=0; evaluation by the responder is no longer necessary.

b5 b4 Bit position
FCB FCV Condition Meaning Action
0 0 DA = TS/127 Request without acknowledgement
Request FDL Status/ Ident/ LSAP Status
Delete last acknowledgement
0/1 0/1 DA # TS Request to another responder
1 0 DA = TS First request FCBM:= 1
SAM:= SA
Delete last acknowledgement / response
0/1 1 DA = TS
SA = SAM
FCB # FCBM
New Request Delete last acknowledgement / response
FCBM:= FCB
Hold acknowledgement / response in readiness for retry
0/1 1 DA = TS
SA = SAM
FCB = FCBM
Retry Request FCBM:= FCB
Repeat acknowledgement / response and continue to hold in readiness
0/1 1 DA = TS
SA # SAM
New initiator FCBM:= FCB
SAM:= SA Hold acknowledgement / response in readiness for retry

FCBM stored FCB in memory SAM stored SA in memory