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

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

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

Итак, я решил поделиться тем, как я это делаю, используя очень простой веб-стек на основе Ruby, который — да — не имеет ничего общего с Rails.

Чтобы делать вещи, которые я бы не хотел делать, я использую Sinatra, чтобы предоставить чрезвычайно элегантный DSL для быстрого создания веб-приложений на Ruby с минимальными усилиями. Я использую Bootstrap для внешнего интерфейса, чтобы сделать вещи отзывчивыми и довольно терпимыми из коробки; а затем я соединяю это с Chartkick для создания красивых диаграмм JS… таких как эта, которая сделала следующую круговую диаграмму:

<%= pie_chart(@data) %>

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

Данные, о которых я буду говорить, — это данные, которые можно проанализировать из журналов. Что-то вроде журнала SSH или журнала FTP. В этом случае мы сосредоточимся на злонамеренных попытках входа в систему из этого примера журнала, который я составил. Я хотел бы отметить, что эти IP-адреса/данные были сгенерированы случайным образом. Значит, они не настоящие нападающие. Журнал отражает — по общему признанию — довольно индивидуальный — журнал приложения, который вы можете найти в реальном мире.

Мы также можем работать под предлогом того, что он уже был grep для неудачных попыток входа в систему, чтобы сосредоточиться на этом.

Разбор

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

Grep и awk могут помочь вам в предварительном анализе данных журнала, которые могут вас заинтересовать, если вы в этом заинтересованы.

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

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

Прежде чем приступить к анализу информации, обязательно просмотрите часть информации вручную (или с помощью таких инструментов, как grep и awk), чтобы получить представление об общей структуре формата журнала, с которым вы собираетесь работать.

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

В нашем случае образец журнала, который я предоставил имеет следующий вид:

2016-12-22 05:12:43 | W | Failed login 'admin' from 192.168.1.1

Мы видим, что для неудачных попыток входа IP-адрес находится в конце строки. Время события указано в начале строки; и после этого указывается тип сообщения журнала, которым оно является, то есть W. Мы можем предположить — поскольку я сделал это — W означает «Предупреждение».

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

Повторное использование логики может быть полезным. Судя по журналу выборки, там не так много всего происходит. Мы знаем, что все они являются предупреждениями. Мы знаем, что все они содержат имя пользователя, который был опробован, IP-адрес этой попытки и время события. Итак, у нас есть три основные характеристики, которые мы можем вывести из каждой линии.

Сборка парсера

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

Мы можем создать собственный API, который поможет нам работать с нашими данными. Мы можем хранить его как угодно или где угодно. Для этого примера я решил просто очень легко засунуть все в хэш. Затем засунуть все эти хэши в массив.

Для этого класса он рассматривает синтаксический анализ в двух формах. У него есть метод parse_file() и метод parse_line(), которые, как и следовало ожидать, анализируют файл и строку в этом файле соответственно.

Анализ строки приводит к паре ключ/значение, которую очень легко запросить для создания других методов, таких как usernames(), ip() и раз().

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

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

Фактическое поведение и способ, которым вы хотите хранить свои данные, могут сделать некоторые процессы проще, чем другие. Мне нравится делать вещи простыми — если я могу.

Расширение парсера

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

Это дает нам представление наших проанализированных данных с — надеюсь — правильной информацией для использования функции временной шкалы Chartkick! Вывод метода timeline() с pry будет выглядеть примерно так:

Создание веб-приложения

Создание веб-приложения с помощью Sinatra невероятно просто. Собственно, начнем со следующего:

Мы можем запустить это приложение из командной строки:

$ ruby simple_sinatra_app.rb
== Sinatra (v1.4.6) has taken the stage on 4567
Thin web server (v1.7.0 codename Dunder Mifflin)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop

Итак, если бы мы открыли наш веб-браузер и перешли к 0.0.0.0:4567, мы бы нашли там наше приложение — и, надеюсь, работающее вот так:

Bootstrap’n Sinatra

Sinatra можно довольно легко использовать как фреймворк MVC. Мы можем редактировать представления — то, как выглядит материал; интерфейс — всевозможные способы с Синатрой. Встроенные, с шаблонами, без шаблонов, как вам нравится… Давайте создадим действительно простой шаблон Bootstrap для использования в Sinatra!

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

Нам нужно создать новый каталог в той же папке, что и наше приложение Sinatra, под названием «представления» — совершенно очевидно, что он будет содержать шаблоны (или «представления»), которые мы будем использовать для нашего приложения. Доступно множество вариантов синтаксиса шаблона.

В этом случае мы будем использовать erb. Он очень похож на HTML, потому что в нем смешаны рубины. Структура каталогов для нашего веб-приложения должна выглядеть так:

web_app_dir/
├── app.rb
└── views
    └── layout.erb
1 directory, 2 files

Шаблон layout.erb будет применяться ко всем веб-страницам нашего приложения. Итак, давайте воспользуемся этим, чтобы определить HTML, CSS и JS, которые нам нужны практически для каждой страницы.

На этом этапе вам, возможно, придется загрузить Bootstrap, Chartkick, а затем создать новый каталог с именем public для Sinatra, после чего вы можете поместить все материалы JS и CSS, которые хотите включить, на локальный сервер, с которого вы обслуживаете страницы. .

Но, нах. Я не об этой семье. Йоло. Братан. Я модный. Мы будем использовать CDN, чтобы упростить создание чего-то вроде этого:

Мы также можем создать еще один шаблон erb для нашего приложения — на этот раз как насчет нашей индексной/домашней страницы? Мы можем довольно легко сделать так, чтобы вещи выглядели довольно профессионально — при этом оставаясь красивыми, ну… красивыми!:

Итак, у нас должна быть структура каталогов, которая сейчас выглядит так:

web_app_dir/
├── app.rb
└── views
    ├── index.erb
    └── layout.erb
1 directory, 3 files

Теперь нам нужно обновить наш файл app.rb, чтобы он знал, как обслуживать шаблон erb для нашей индексной страницы, и включить гем Chartkick для его использования:

Когда мы раскручиваем этого плохого мальчика, мы получаем что-то аккуратное:

Теперь давайте начнем визуализировать некоторые из этих данных, а что нет!

Поместите парсер в веб-приложение и встряхните его!

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

Лента новостей

Поскольку мы уже написали метод временной шкалы для Chartkick, мы редактируем файл app.rb, чтобы он выглядел так, чтобы наша функция временной шкалы работала:

Нам также нужно добавить файл timeline.erb в наш каталог представлений:

Когда мы снова запустим наше веб-приложение и перейдем к /timeline, мы увидим первые плоды нашего труда по синтаксическому анализу!

Этот тип временной шкалы действительно полезен для сравнения того, как долго злоумышленник существует по сравнению с другими.

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

Что ж, давайте добавим параметр таргетинга, чтобы посмотреть временную шкалу для определенного IP-адреса с помощью линейного графика.

Линейный график

Чтобы добавить функцию для таргетинга на определенный IP-адрес, давайте добавим форму на страницу временной шкалы, изменив шаблон erb следующим образом:

По сути, мы просто поместили форму с полем ввода прямо над графиком. Когда пользователь публикует один IP-адрес, мы собираемся показать ему один линейный график временной шкалы, поэтому мы обновили нашу логику erb, чтобы отразить это. Нам нужно убедиться, что наша логика Sinatra и логика парсера работают правильно.

Давайте удостоверимся, что Sinatra знает, как обращаться с этим параметром POST. Мы также не написали метод, который будет получать события временной шкалы для определенного IP-адреса… Но это очень просто:

Затем, допустим, у нас есть вопрос об этой подозрительно выглядящей временной шкале в самом верху для IP-адреса (не настоящего злоумышленника): 100.210.123.5

Итак, давайте поместим этот IP-адрес в нашу новую форму в верхней части страницы!

Мы видим, что следующая диаграмма менее пугающая — и теперь мы знаем, что да, атакующий существует уже какое-то время, — но он также не был таким настойчивым. Может быть, это просто кто-то перепутал свой пароль?

Круговая диаграмма

Может быть, я хочу знать, какой IP-адрес чаще всего атаковал эту страницу входа? Было бы неплохо иметь круговую диаграмму для сравнения наших результатов!

Чтобы это произошло, нам нужен файл piechart.erb в каталоге представлений, который мы создали ранее, а затем нам понадобится некоторая логика Sinatra и некоторая новая логика синтаксического анализатора для размещения Chartkick pie_chart( ) метод.

Нам нужно обновить наш app.rb следующим образом:

Затем нам нужно создать шаблон piechart.erb, который может обслуживать Sinatra:

Что при запуске выглядит так:

Проверка единой временной шкалы для 157.160.48.237 может помочь выяснить, когда произошли все эти атаки:

Так как я ушел в той же форме из временной шкалы, он должен работать точно так же, чтобы просмотреть временную шкалу этого одного IP-адреса, верно? Я мог бы просто ввести IP-адрес в строку поиска, верно?

Бинго, мы получили ответы! Работает как шарм.

Если бы я хотел помочь сопоставить это на временной шкале, это тоже было бы просто:

Изящные шаблоны для обнаружения

Иногда вы наверняка сталкиваетесь с некоторыми интересными данными… Для этого IP-адреса 105.22.61.253 кажется, что в этом шаблоне атаки есть законная синусоида…

September  9th : 1 attempt(s)
October   10th : 4 attempt(s)
November  11th : 3 attempt(s)
December  12th : 5 attempt(s)

Некоторые злоумышленники, кажется, пытаются реже или сначала будут пытаться больше, а затем, похоже, перейдут к более медленной атаке — может быть, с паролями по умолчанию? Или, может быть, это просто пользователь, который забыл свой пароль? Я не знаю.

Расположение IP-адреса может помочь определить такие вещи. Но этот IP был сгенерирован случайным образом — так что в этом нет ничего страшного.

Результаты

Я люблю Ruby (и сообщество)! Вы можете сделать все это так легко. Конечно, вы можете сделать то же самое практически с любым языком программирования.

Несмотря на это, я нахожу простоту и быстроту прототипирования, которые я могу выполнить с Ruby, легкими и безумно удовлетворительными. Я чувствую себя очень счастливым, занимаясь этим, и рад копаться в данных!

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

Я нахожу веб-приложения своего рода интересным цифровым «холстом», позволяющим создавать замечательные новые визуальные представления данных и способы взаимодействия с данными, которые мне интересны. Синатра, Bootstrap, Chartkick; и, конечно же, Ruby — замечательные среды для работы на этом холсте.

Я действительно думаю, что вы должны проверить их!

Быстрое предупреждение о безопасности

Просто потому, что это легко сделать, это не делает его на 100% безопасным. Подождите… когда простота всегда означала безопасность? Например, у вас, вероятно, все в порядке, если вы не открываете что-то в Интернете.

Я показывал вам, как начать создавать приложения, но на самом деле я не говорил о безопасности. Эмпирическое правило: не доверяйте пользовательскому вводу и просто не открывайте подобные веб-приложения в Интернете, да? Просто будь осторожен.

Кулио.