Главная

Friday, 18 March 2022

Пишем правило для Snort.

Всем привет.

Загляняем сегодня к одной из самых популярных систем IDS в инфомире - Snort. Snort используется для сигнатур или правил, которые связывают между собой группу элементов (так называемые параметры правил), истинность которых является обязательным условием срабатывания правила. Основные параметры занимаются распознаванием элементов, которые либо относятся к содержимому (параметры правил содержимого в терминологии Snort), либо нет (параметры правил вне содержимого). Примерами параметров правил вне содержимого могут служить определенные флаги, значения TCP- или IP-заголовков и размер пакета. Например, параметр flow:established,to_client выбирает пакеты, которые входят в сеанс TCP, инициированный сервером, и предназначены для клиента. Еще один пример, dsize:200, выбирает пакеты, содержимое которых равно 200 байт.

Как я писал ранее, IDS Suricata, она же является развитием Snort, и которая является основой в пакете SELKS использует синтаксис правил Snort. Поэтому давайте в качестве примера создадим для Snort простое правило, которое позволяет обнаружить вредонос, который генерирует сетевой трафик, состоящий из HTTP-запроса типа GET. Когда браузеры или другие HTTP-приложения делают запрос, они указывают поле заголовка User-Agent, чтобы связаться с программой, которая используется для этого запроса. Обычно данное поле начинается со слова Mozilla (по историческим причинам) и может выглядеть как Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1). Здесь содержится информация о версии браузера и ОС.

Пусть наш вредонос формирует такой GET-запрос:

GET /index.htm HTTP 1.1

Accept: */*

User-Agent: Wefa7e

Cache-Control: no

Поле User-Agent, которое используется рассмотренным вредоносом, равно Wefa7e. Это характерное значение, и с его помощью можно распознавать вредоносный трафик. Разумеется более надежный вредонос сформирует это поле под любой браузер, но для нашего примера он будет таким простым. Следующая сигнатура нацелена на необычные строки User-Agent, которые использовались запущенным нами вредоносом:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"TROJAN Malicious User-Agent"; content:"|0d 0a|User-Agent\: Wefa7e"; classtype:trojan-activity; sid:2000001; rev:1;)

В Snort правила состоят из двух частей: заголовка и параметров. Заголовок содержит действие (обычно alert), протокол, исходный и конечный IP-адреса, а также порты источника и адресата.

В правилах принято использовать переменные, которые позволяют адаптироваться под текущую среду: $HOME_NET и $EXTERNAL_NET определяют внутренний и внешний диапазоны IP-адресов, а $HTTP_PORTS указывает порты, которые следует интерпретировать как HTTP-трафик. В данном случае заголовок $HOME_NET any ->$EXTERNAL_NET $HTTP_PORTS соответствует исходящему трафику, проходящему через HTTP-порты, так как знак -> говорит о том, что правило относится лишь к одному направлению передачи данных.

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


В сочетании с sid служит уникальным идентификатором версии правила Внутри выражения content используется вертикальная черта (|), которая определяет начало и конец записи в шестнадцатеричном формате. Все, что находится между этими символами, интерпретируется в качестве шестнадцатеричных значений. Таким образом, |0d 0a| представляет разрыв между HTTP-заголовками.

В данной сигнатуре параметр правила content соответствует полю HTTP-заголовка User-Agent: Wefa7e, поскольку заголовки в этом протоколе разделяются символами 0d и 0a.

Теперь у нас есть оригинальные признаки и сигнатура системы Snort. На этом этапе  исследование сетевых индикаторов, особенно с применением автоматических методик анализа вроде так называемых песочниц, часто считается завершенным. Мы получили IP-адреса, которые следует заблокировать в брандмауэре, доменные имена, подлежащие блокировке на уровне прокси-серверов, и сетевую сигнатуру для системы IDS. Однако не стоит на этом останавливаться, ведь текущие меры дают нам лишь ложное ощущение безопасности.

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

Ранее в качестве примера приводилась настоящая вредоносная программа, Snort-сигнатура для которой была подана в так называемый список новых угроз. В этом списке содержится набор общедоступных правил, которые разрабатываются сообществом. В своем представлении предложенной сигнатуры ее автор утверждает, что он видел в реальном трафике два значения поля User-Agent: Wefa7e и Wee6a3. Он подал на утверждение следующее правило, которое основано на его собственных наблюдениях:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"ET TROJAN WindowsEnterpriseSuite FakeAV Dynamic User-Agent"; flow:established,to_server; content:"|0d 0a|User-Agent\: We"; isdataat:6,relative; content:"|0d 0a|"; distance:0; pcre:"/User-Agent\: We[a-z0-9]{4}\x0d\x0a/"; classtype:trojan-activity; reference:url,www.threatexpert.com/report.aspx?md5=d9bcb4e

4d650a6ed4402fab8f9ef1387; sid:2010262; rev:1;)

Это правило содержит несколько дополнительных ключевых слов, которые описаны ниже:


Само правило выглядит довольно длинным, но его основная часть состоит лишь из строки User-Agent и отрезка We, за которым ровно следует четыре алфавитноцифровых символа (We[a-z0-9]{4}). В формате регулярных выражений, совместимых с Perl (Perl compatible regular expression, PCRE), который применяется в Snort, используются следующие обозначения:

- квадратные скобки ([ и ]) обозначают набор возможных символов;

- фигурные скобки ({ и }) обозначают количество символов;

- шестнадцатеричная запись байтов имеет вид \xHH.

Как отмечалось ранее, заголовок правила содержит базовую информацию, такую как IP-адрес (исходный и конечный), порт и протокол. Snort отслеживает TCP-сеансы и, в зависимости от того, кто их инициировал, позволяет вам создавать правила для клиентского или серверного трафика. Благодаря ключевому слову flow данное правило будет срабатывать только для информации, сгенерированной клиентом.

Со временем правило было несколько изменено, чтобы избавиться от ложных срабатываний, связанных с популярным программным пакетом Webmin, значение User-Agent которого совпадает с шаблоном вредоноса. Ниже представлена финальная версия данного правила:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"ET TROJAN WindowsEnterpriseSuite FakeAV Dynamic User-Agent"; flow:established,to_server; content:"|0d 0a|User-Agent|3a| We"; isdataat:6,relative; content:"|0d 0a|"; distance:0; content:!"User-Agent|3a| Webmin|0d 0a|"; pcre:"/User-Agent\: We[a-z0-9]{4}\x0d\x0a/"; classtype:trojan-activity; reference:url,www.threatexpert.com/report.aspx?md5=d9bcb4e4d650a6ed4402fab8f9ef1387; reference:url,doc.emergingthreats.net/2010262; reference:url,www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/VIRUS/TROJAN_WindowsEnterpriseFakeAV; sid:2010262; rev:4;)

Знак восклицания (!) перед выражением content (content:!"UserAgent|3a|Webmin|0d 0a|") означает логически обратную выборку (то есть слово «не»), поэтому правило сработает только в случае отсутствия описанного содержимого. Этот пример иллюстрирует несколько атрибутов, характерных для процесса разработки сигнатуры. 

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

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

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

We4b58 We7d7f Wea4ee

We70d3 Wea508 We6853

Это позволяет легко распознать случайные элементы в трафике, который сгенерировала вредоносная программа. Полученные результаты подтверждают, что предположение, лежащее в основе официальной сигнатуры из списка новых угроз, было верным. Можно сделать вывод о том, что последние четыре символа состоят из букв и цифр, распределенных случайным образом. Однако у данной сигнатуры есть еще одна проблема (если исходить из того, что это настоящие результаты): диапазон символов в представленных выше строках явля ется более ограниченным, чем тот, что указан в шаблоне. PCRE-выражение имеет вид /User-Agent\: We[a-z0-9]{4}\x0d\x0a/, но полученные результаты говорят о том, что здесь используются лишь буквы от а до f (а не a–z). Такое распределение символов часто применяется при переводе двоичных значений непосредственно в шестнадцатеричный формат.

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

Wfbcc5 Wf4abd Wea4ee

Wfa78f Wedb29 W101280

W101e0f Wfa72f Wefd95

Наша сигнатура отлавливает некоторые случаи, но она далеко не идеальна, так как помимо We источник этого трафика генерирует как минимум префиксы Wf и W1. К тому же по этой выборке четко видно, что поле User-Agent может состоять как из шести, так и из семи символов.

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

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

Представьте, к примеру, что после многократного запуска вредоноса в одной и той же системе мы получили следующие результаты:

Wefd95 Wefd95 Wefd95

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

We9753 We9753 We9753

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

Все приведенные примеры кода найдены в источнике.

Успехов.
Слава Украине!

No comments:

Post a Comment

А что вы думаете по этому поводу?