Вредоносное ПО и форензика
Зачем использовать NotHoly для анализа malware
Статический triage в sandbox, который никогда не запускает образец, и модель, что объясняет и ложит на ATT&CK без отказа. Детонация в вашей лаборатории.
Напишите первое правило YARA, добейтесь совпадения с одним безобидным тестовым файлом и отсутствия совпадения с другим и узнайте, зачем каждому правилу нужны позитивные и негативные тесты.
YARA — инструмент поиска по шаблонам. Вы пишете правило, которое описывает, как выглядит файл, а YARA выводит файлы, подходящие под описание. Чаще всего ею пользуются аналитики вредоносного ПО. Они пишут правила для строк, структуры файлов и последовательностей байтов, а затем сканируют папки, образы дисков и дампы памяти. Тот же механизм работает на любых ваших файлах, например на шаблоне, в котором не должно быть внутренней метки, или конфиге, в котором не должно быть токена.
YARA понятия не имеет, что опасно. Она находит то, что написано в правиле. Правило — это утверждение о байтах, и качество правила определяется этим утверждением.
Проект размещён на GitHub в организации VirusTotal. Официальное руководство по написанию правил на Read the Docs служит справочником по синтаксису. VirusTotal также поддерживает YARA-X, переписанную на Rust версию, которая сохраняет большую часть языка правил. Эти два инструмента пересекаются, но не идентичны, так что прочитайте заметки о совместимости, прежде чем переносить правило с одного на другой.
Хеш файла отвечает на один узкий вопрос: известен ли уже именно этот файл? Измените один байт, и хеш изменится. Подробнее об этом в статье о хешах файлов. Правило YARA задаёт вопрос шире: есть ли в файле ожидаемые фрагменты? Одно правило может совпасть со многими файлами, у которых есть общая строка, структура или шаблон байтов, даже если ни у одной пары нет общего хеша.
С этого более широкого вопроса начинаются и проблемы. Хеш почти никогда не совпадает с файлом, с которым не должен. Небрежное правило может совпасть с половиной файлового сервера. Поэтому учиться надо прежде всего писать правило, которое совпадает с нужным и больше ни с чем, и доказывать это на файлах, которые вы контролируете. Синтаксис здесь вторичен.
У каждого правила есть имя, а за ним в фигурных скобках до трёх секций:
rule Example_Rule {
meta:
description = "What this rule is for"
strings:
$text = "some text"
condition:
$text
}Имена правил состоят из букв, цифр и подчёркиваний и не могут начинаться с цифры. Имя попадает в каждый отчёт о совпадении, поэтому выбирайте такое, по которому читателю понятно, о чём правило.
В meta лежат пары ключ-значение для людей: описание, автор, дата, ссылка на исследование, на котором основано правило. YARA никогда не использует meta для решения о совпадении. Всё равно держите эти данные точными, потому что следующий человек, открывший файл, им поверит.
Каждая строка получает идентификатор, начинающийся с $. Условие ссылается на строки по этому идентификатору. Строки бывают трёх видов.
Текстовые строки пишутся в двойных кавычках:
$marker = "LAB-TRAINING-MARKER"Модификаторы меняют способ сопоставления текста. nocase игнорирует регистр. wide сопоставляет текст UTF-16LE, где после каждого символа ASCII идёт нулевой байт, что обычно для бинарников Windows. fullword требует, чтобы совпадение стояло отдельно, вне более длинного слова.
Шестнадцатеричные строки пишутся в фигурных скобках и сопоставляют сырые байты:
$mz = { 4D 5A }Эти два байта — сигнатура MZ в начале многих исполняемых файлов Windows. ?? совпадает с любым одним байтом, [2-4] допускает разрыв от двух до четырёх неизвестных байтов, а ( 90 | 91 ) совпадает с любым из двух байтов.
Регулярные выражения пишутся между слешами:
$version = /LAB-[A-Z]+ v[0-9]+/Регулярка — самый гибкий вид строк, и её проще всего сделать слишком широкой. Если шаблон можно выразить обычной текстовой или шестнадцатеричной строкой, используйте её.
Условие — булево выражение. Оно объединяет строки и свойства файла в один ответ: совпадение или нет.
$marker истинно, когда строка встречается хотя бы один раз.any of them и all of them охватывают все строки правила. 2 of ($a, $b, $c) требует двух из трёх.$marker at 0 требует, чтобы строка начиналась с первого байта. $marker in (0..512) требует, чтобы она была где-то в первых 512 байтах.#marker > 3 считает вхождения.filesize < 2KB проверяет размер файла.uint16(0) == 0x5A4D читает первые два байта как целое little-endian и проверяет сигнатуру MZ.Условие нужно каждому правилу. Правило со строками и без осмысленного условия либо сломано, либо бесполезно.
-s YARA также печатает каждую совпавшую строку и смещение в байтах, где она найдена.Сначала строки, потом условие. Условие вроде $a and $b строгое, потому что для совпадения правила нужно найти обе строки.
Ожидаемый вывод ниже описан словами, потому что точное форматирование в разных версиях YARA может отличаться. Сравнивайте то, что видите, с этими описаниями.
Работайте в пустой папке. В Windows выполняйте команды в Git Bash. Heredoc на шаге 3 в PowerShell работает иначе.
В Debian и Ubuntu:
sudo apt install yaraВ macOS через Homebrew:
brew install yaraВ Windows скачайте zip релиза с https://github.com/VirusTotal/yara/releases, распакуйте его и поместите исполняемый файл в PATH. Файл может называться yara64.exe. Переименуйте его в yara.exe или скопируйте под этим именем, чтобы команды ниже работали как написано.
Проверьте установку:
yara --versionВы должны увидеть номер версии. Эта статья версию не фиксирует, так что используйте последний релиз, который даёт ваш способ установки.
mkdir yara-lab && cd yara-lab
printf 'LAB-TRAINING-MARKER v1\n' > match.txt
printf 'ordinary text file\n' > nomatch.txtОба файла — простой текст, написанный вами. Первый должен совпасть с правилом, второй не должен.
Кавычки вокруг EOF важны. Без них shell заменит $m пустой переменной до того, как YARA увидит файл, и правило перестанет компилироваться.
cat > lab.yar <<'EOF'
rule Lab_Training_Marker {
meta: description = "Matches the lab training marker"
strings: $m = "LAB-TRAINING-MARKER"
condition: $m
}
EOFВ правиле три части. Meta говорит, для чего правило. Строка говорит, что в файле должен быть текст метки. Условие говорит, что файл совпадает, когда эта строка найдена хотя бы один раз.
yara -s lab.yar match.txtYARA должна напечатать имя правила и путь к файлу. Из-за -s она также выводит совпавшую строку со смещением в байтах и найденным текстом. Метка начинается с первого байта match.txt, поэтому смещение должно быть 0x0.
yara lab.yar nomatch.txtОжидаемый вывод: ничего. YARA печатает только совпадения, поэтому тишина значит, что файл не совпал.
Тишина что-то значит, только если сработал позитивный тест. Сначала выполните шаг 4. Если шаг 4 ничего не напечатал, дело в правиле или установке, и тишина на шаге 5 ни о чём не говорит.
Почти совпадающий файл — самый полезный негативный, потому что он не проходит по одной узкой причине.
printf 'LAB-TRAINING\n' > near.txt
yara lab.yar near.txtОжидаемый вывод: ничего. В файле есть начало метки, но нет полной строки, поэтому строка не найдена и условие ложно.
yara -r lab.yar .Флаг -r сканирует папку рекурсивно. Ожидайте в выводе match.txt. Вероятно, вы увидите и lab.yar, сам файл правила. В файле правила есть текст метки, так что правило совпадает со своим исходником. Это частая ошибка, о ней расскажет следующий раздел. Держите правила в другой папке, отдельно от сканируемых данных.
Для учебной метки лабораторное правило подходит. Реальным правилам обычно нужно ограничение, которого одна строка не даёт. Допустим, вам нужны только небольшие файлы с меткой:
rule Lab_Training_Marker_Small {
strings: $m = "LAB-TRAINING-MARKER"
condition: $m and filesize < 1KB
}Проверьте так же. match.txt должен совпасть. nomatch.txt и near.txt не должны. С точки зрения тестов любое изменение строк или условия даёт новое правило, поэтому запускайте оба тестовых файла снова.
Это правило выглядит разумно:
rule Too_Broad {
strings: $a = "text"
condition: $a
}Оно совпадёт с nomatch.txt, потому что в предложении ordinary text file есть слово text. Проверить это можно на уже созданном негативном файле. Правило, совпавшее с ним, провалило собственный тест.
Шаблоны, которые совпадают со слишком многим:
text, error, copyright или this program.{ 00 } или { 90 }.nocase на обычном слове.any of them по списку строк, каждая из которых встречается в обычных файлах.filesize < 10KB, которому соответствует большинство небольших файлов./.+/.Как ужесточить правило:
and или 2 of (...), чтобы результат не решала одна обычная строка.at или in, когда знаете, где должна быть строка.uint16(0) == 0x5A4D.$m до того, как YARA прочитает файл. См. шаг 3.Это самое главное правило в статье. Каждому правилу YARA нужны тестовые файлы обоих видов до того, как кто-то его задеплоит.
match.txt. В реальной работе это образцы, которые вы вправе хранить, по правилам обращения вашей организации.near.txt.Правило проходит, когда совпадает со всеми позитивными файлами и ни с одним негативным. Храните оба набора рядом с правилом, в системе контроля версий, если команда ею пользуется, и запускайте их после каждой правки. Правило, которое прошло позитивный тест, но ни разу не запускалось на негативных файлах, не протестировано.
pe, с помощью которого правило проверяет заголовки и секции исполняемого файла Windows вместо сырых байтов.Вредоносное ПО и форензика
Статический triage в sandbox, который никогда не запускает образец, и модель, что объясняет и ложит на ATT&CK без отказа. Детонация в вашей лаборатории.
Вредоносное ПО и форензика
Как хеши идентифицируют файлы, почему SHA-256 сменил MD5, как NSRL отсеивает известное ПО и почему загрузка файла на VirusTotal означает его раскрытие.