08.06.2015

Yara - knife for malware researchers + Flowinspect

http://plusvic.github.io/yara/
https://xakep.ru/2011/10/31/57409/
https://yaragenerator.com/
https://github.com/Xen0ph0n/YaraGenerator
https://github.com/Yara-Rules/rules


$ yara
usage: yara [OPTION]... [RULEFILE]... FILE | PID

Сценарий называется clamav_to_ yara.py и написан Мэтью Ричардом (bit.ly/ij5HVs). Скачиваем скрипт и конвертируем базы:
$ python clamav_to_yara.py -f daily.cvd -o clamav.yara
Сканирование папки с использованием сигнатуры выполняется одной единственной командой:
$ yara -r clamav.yara /pentest/msf3/data

Простой пример правила:
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 + MD5

Yara does not support MD5 hashing.
We will now need to create a Yara rule with the MD5 hash as a string:
rule MD5_BAD_FILE
{  
strings:  
    $md5 = "A1EB325F994E5A1720C0E401731B5ED9" nocase
condition:  
    $md5
}

The Yara rule will alert on the string of the MD5 hash. Now we need some code that will open a file, hash the file and then scan the hash value using the Yara rule. (python)

import hashlib
import sys
import imp
import yara 
from StringIO import StringIO

def MD5(d):
# d = buffer of the read file 
# This function hashes the buffer
# source: http://stackoverflow.com/q/5853830
    if type(d) is str:
      d = StringIO(d)
    md5 = hashlib.md5()
    while True:
        data = d.read(128)
        if not data:
            break
        md5.update(data)
    return md5.hexdigest()


def yaraScan(d):
# d = buffer of the read file 
# Scans SWF using Yara
    # test if yara module is installed
    # if not Yara can be downloaded from http://code.google.com/p/yara-project/
    try:
        imp.find_module('yara')
        import yara 
    except ImportError:
        print '\t[ERROR] Yara module not installed - aborting scan'
        return
    # test for yara compile errors
    try:
        r = yara.compile(r'md5.yara')
    except:
        pass
        print '\t[ERROR] Yara compile error - aborting scan'
        return
    # get matches
    m = r.match(data=d)
    # print matches
    for X in m:
        print '\t[BAD] Yara Signature Hit:', X
    return

def main():
    try:
        f = open(sys.argv[len(sys.argv)-1],'rb+')
    except Exception:
        print '[ERROR] File can not be opended/accessed'
        return
    yaraScan(MD5(f))    

if __name__ == '__main__':
   main()
  
Example:
python yaraMD5.py "6UHp0dCM12c[1].swf"

Flowinspect:

Look at live HTTP sessions:

./flowinspect.py -d eth0 -c "^(GET|POST|HEAD|PUT).*" -f "tcp and port 80" -o print
Inspect HTTP streams for Metasploit ie_cgenericelement_uaf exploit (CVE-2013-1347):

./flowinspect.py -p cgenericelement.pcap -s 'CollectGarbage\(\).*mstime_malloc\({shellcode:' -b32
Use a Yara signature to look for UPX packed binaries on STC direction:

./flowinspect.py -p e03a7f89a6cbc45144aafac2779c7b6d.pcap -R upx.yara
Obtain and install pynids. For those on Ubuntu, please make sure you have libpcap-dev, libnet1, libnet1-dev, and libglib2.0-dev packages pre-installed before installing pynids. Also, you might have to manually install libnids that comes bundled with pynids using the usual configure && make && make install process.

https://code.google.com/p/malwarecookbook/source/browse/trunk/3/3/clamav_to_yara.py


Install:
sudo apt-get install libpcre3 libpcre3-dev

Download:

Untar and configure YARA.

$ tar xvfz yara-1.4.tar.gz
$ cd yara-1.4
$ ./configure

If there are no errors, make the executables:

$ make
$ make check
$ sudo make install

Now we add python support :

$ cd ..
$ tar xvfz yara-python-1.4.tar.gz
$ cd yara-python-1.4.tar.gz
$ python setup.py build
$ sudo python setup.py install

If you have no problem you will be able to run YARA:
$ yara -v

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

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

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 говорит уже даже список проектов, которые его используют, а это:

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

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


Установка

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

$ yara
usage: yara [OPTION]... [RULEFILE]... 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 [4-6] 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 сигнатур.

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

[Name of the Packer v1.0]
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 оказался на редкость понятным и прозрачным инструментом. Мне не составило большого труда написать для него вебадминку и наладить работу в качестве веб-сервиса. Немного креатива, и сухие результаты анализатора уже раскрашиваются разными цветами, обозначая степень опасности найденного зловреда. Небольшое обновление базы, и для многих из крипторов доступно краткое описание, а иногда даже и инструкция по распаковке. Прототип создан и работает отменно, а начальство пляшет от восторга!