[Из песочницы] Как Elasticsearch может помочь в поиске подозрительной активности на сайте
Предлагаю читателям «Хабрахабра» перевод статьи «Spotting bad actors: what your logs can tell you about protecting your business» из официального блога Elasticsearch. Статья рассказывает о том, как можно использовать возможности Elasticsearch для анализа логов веб-сервера с целью обнаружения подозрительной активности на сайте.Давайте подумаем, что и когда мы делаем в случае попыток взломать наш сайт? Во-первых, чаще всего мы пытаемся устранить угрозу уже тогда, когда злоумышленники нашли уязвимость на сайте и воспользовались ей. Во-вторых, зачастую единственный оперативный инструмент борьбы со злоумышленниками — это блокировка IP-адресов, но это мало эффективный инструмент, если мы не владеем развернутой информацией обо всех адресах, с которых ведется атака на сайт.
Но на сколько бы изменилась ситуация, если бы мы могли заблаговременно получать развернутую информацию обо всех IP-адресах и подсетях, которые проявляют подозрительную активность и блокировать именно их? Звучит здорово, не правда ли?
Мы можем легко сделать это вместе с Elasticsearch.В арсенале этого поискового движка есть замечательный плагин Netrisk, который берет на себя все хлопоты по анализу логов и, используя «Sankey» диаграмму (см. картинку), демонстрирует нам размер и концентрацию подозрительной активности в различных сегментах трафика.
ПодготовкаНачнем с установки Netrisk. Для этого вам следует запустить следующую команду, находясь в домашней директории Elasticsearch (необходима версия не ниже 1.4.0): bin/plugin -install markharwood/netrisk Отлично, теперь плагин установлен. Но это не всё. Он ожидает, что мы предоставим ему индекс с правильно настроенным меппингом для поля, в котором будут храниться IP-адреса. Я объясню детали позже, а сейчас необходимо просто создать индекс и заполнить его небольшим объемом тестовых данных, запустив следующий shell скрипт: $ES_HOME/plugins/netrisk/exampleData/indexAnonData.sh Внимание! Этот скрипт создаст индекс «mylogs», при этом, если у вас уже есть индекс с таким названием — он будет удален.Если вы выполнили все вышеописанные инструкции, то можете открыть страницу плагина: localhost:9200/_plugin/netrisk/
Запуск Если посмотреть на сгенерированные скриптом данные, то может показаться, что этого мало для серьезного анализа, ведь, по сути, из ценного мы имеем только статусы HTTP ответов сервера. На самом деле этого достаточно, чтоб обнаружить подозрительное поведение. Обычно веб-сервер генерирует ответы в диапазоне от 200 до 300, но в случае возникновения проблем он может присвоить ответу статус от 400 до 500. Например, это может случиться, когда кто-то пытается обратиться к несуществующей странице. Выходит, что мы уже можем получить список всех подозрительных обращений к серверу с помощью запроса: status:[400 TO 599] Netrisk использует стандартный Lucene парсер запросов (тот же самый, что и Kibana), поэтому вы можете дополнить запрос, выявляющий подозрительный трафик дополнительными фильтрами через условие OR. Например, таким образом, мы можем сообщить системе, что обращения к сайту без указания UserAgent тоже следует считать подозрительными.Важно понимать, что запрос, составленный на этом этапе, не будет однозначно определять, что все записи в журнале, подходящие под него являются плохими. Нет, мы просто делаем предположение о том, что может быть подозрительным, чтоб в последствие Elasticsearch проанализировал весь журнал на предмет высокой концентрации подозрительных обращений к серверу с конкретных IP или подсетей.
Если мы запустим плагин, используя вышеупомянутый запрос, то Netrisk продемонстрирует нам Sankey диаграмму подозрительного трафика, ведущего на ваш сайт. Вот некоторая информация для чтения диаграммы:
Толщина линии представляет количество «плохих» запросов, но это не самое важное! Куда важнее цвет линии — он зависит от того, какие запросы преобладают: ярко красный цвет — означает, что почти все запросы являются плохими, в то время как зеленые означает, что почти все запросы мы можем считать хорошими. Если навести курсор на линию, то можно увидеть реальные цифры, лежащие в основе определения цвета. На диаграмме отображено, какие IP-адреса входят в каждую подсеть. Эта информация может быть очень ценной для веб-мастера при определение того от куда идет вредоносный трафик: от конкретных IPадресов или из подсети? Клик на конкретный IP-адрес откроет сайт проекта Honey Pot, на котором вы сможете ознакомиться с комментариями других веб-мастеров касательно этого IP-адреса. Вероятно, вы заметили, что цвет линии может меняться от красного к зеленому в направлении слева направо. Это связанно с тем, что в левой стороне диаграммы каждый нод обычно представляет небольшую группу IP-адресов, запросы с которых были определены как подозрительное. Следующие ноды диаграммы представляют подсети, включающие большие число IP -адресов с разным поведением. Однако некоторые подсети будут полностью красными. Скорее всего это означает, что никто, кроме злоумышленников, не интересуется вашим сайтом в этом регионе (напримерб если вы имеете русскоязычный сайт, а к вам приходит красный трафик из Китая, тоб скорее всегоб это означает, что китайские хакеры хотят навредить вашему ресурсу).
Как это работает? Немного о меппинге данных Запросы, которые делает Netrisk, полагаются на имеющуюся статистику об IP-адресах и подсетях, хранящуюся в индексе. Для такого анализа мы не можем просто индексировать каждый IP-адрес как строку, мы должны разделить его на токены, которые будут представлять сам IP-адрес и подсети, в которые он входит (например, IP-адрес типа 186.28.25.186 будет разделен на следующие токены: 186.28.25.186, 186.28.25, 186.28 и 186). Это можно реализовать с помощью следующего правила меппинга: Правило меппинга curl -XPOST «http://localhost:9200/mylogs» -d '{ «settings»: { «analysis»: { «analyzer»: { «ip4_analyzer»: { «tokenizer»: «ip4_hierarchy» } }, «tokenizer»: { «ip4_hierarchy»: { «type»: «PathHierarchy», «delimiter»:».» } } } }, «mappings»: { «log»: { «properties»: { «remote_host»: { «type»: «string», «index»: «not_analyzed», «fields»: { «subs»: { «type»: «string», «index_analyzer»: «ip4_analyzer», «search_analyzer»: «keyword» } } } } } } }' Такой подход дает нам возможность совершать быстрый поиск одновременно на всех 4 уровнях иеархии каждого IP-адреса. (это применимо и для IPv6 адресов)Что внутри? Netrisk получает от вас запрос, который определяет, что именно следует считать «плохими обращениями» (или говоря точнее «потенциально плохими обращениями»). Отфильтровав данные, Netrisk использует significant_terms агрегацию для определение с каких IP адресов или подсетей чаще всего приходят подозрительные обращения. Шаблон запроса выглядит следующим образом: curl -XGET «http://localhost:9200/anonlogs/_search? search_type=count» -d'{ «query»: { «query_string»: { «query»: «status:[400 TO 599]» } }, «aggs»: { «sigIps»: { «significant_terms»: { «field»: «remote_host.subs», «size»: 50, «shard_size»: 50000, «gnd»: {} } } } }' Этот запрос выбирает 50 наиболее подозрительных IP-адресов и подсетей. Есть несколько моментов, заслуживающих внимания:
Для получения корректных данных мы нуждаемся в высоком значении shard_size. Это будет серьезно нагружать память и сеть, так же потребуется дисковое пространство для большого количества уникальных записей в индексе. Если мы не индексируем IP адреса полностью в поле remote_host.subs — то это это уменьшит нагрузку, но уменьшит и глубину получаемого результата. ElasticSearch для эвристического анализа по умолчанию использует алгоритм JLH, но для рассматриваемой нами задачи куда лучше подойдет алгоритм GND. Обычно при анализе нас интересуют редкие слова, например, нам важно определить, что слова «Носферату» и «Хельсинг» связаны с набором документов о фильме Дракула, но нас мало интересует, с чем связано распространённое слово «он». В задаче анализа IP-адресов мы можем пренебречь возможностями, которые нам дает JLH алгоритм и воспользоваться менее функциональным, но более быстрым GND. Этот единственный запрос сделает массовый анализ и предоставит нам основную информацию о нарушителях в нашей системе, но желательно уточнить некоторую информацию прежде, чем принимать решение по блокировке IP-адресов. Для этого мы можем воспользоваться следующим запросом:
Запрос { «query»: { «terms»: { «remote_host.subs»: [ »256.52», »186.34.56» ] } }, «aggs»: { «ips»: { «filters»: { «filters»: { »256.52»: { «term»: { «remote_host.subs»:»256.52» } }, »186.34.56»: { «term»: { «remote_host.subs»:»186.34.56» } } } }, «aggs»: { «badTraffic»: { «filter»: { «query»: { «query_string»: { «query»: «status:[400 TO 599]» } } } }, «uniqueIps»: { «cardinality»: { «field»: «remote_host» } } } } } } Для каждого указанного подозрительного IP или подсети мы получим массив со следующей информацией:
Общее количество запросов (плохих и хороших); Общее количество плохих запросов; Общее количество уникальных IP адресов в подсети; Теперь, когда у нас есть диаграмма и подробная статистика о сомнительных IP-адресах, мы можем принять конечное решение по блокировке.Заключение Отслеживание поведения таких сущностей, как IP-адреса посредством анализа журнала веб-сервера — это комплексная вычислительная задача, но полученные нами данные — это лишь вершина айсберга.Приведу еще несколько более интересных примеров поведенческого анализа, которые вы можете реализовать самостоятельно:
Сколько времени проводят посетители на моем сайте? Какие IP-адреса ведут себя как боты (не подгружают CSS и JavaScript — только саму разметку страницы)? Какая страница сайта чаще других бывает первой/последней при посещение сайта?