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

Это часть 4 из серии, описанной ниже:

Часть 1. Интуиция и как мы работаем с документами?

Часть 2. Обработка текста (модель N-грамм и модель TF-IDF)

Часть 3. Алгоритм обнаружения (машины опорных векторов и градиентный спуск)

Часть 4. Варианты этого подхода (обнаружение вредоносных программ с помощью классификации документов)

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

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

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

Статический анализ против динамического анализа

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

Очевидная проблема в том, что по мере того, как вредоносные программы становятся все более продвинутыми, они могут адаптироваться к этим механизмам. Например, в примере с хешем из-за того, что хеши так чувствительны к изменениям (чего еще можно ожидать от длинной строки, содержащей сотни тысяч строк кода?), Некоторые программы могут изменять свои собственные код автоматически и перекомпилируйте, чтобы получить вредоносное ПО, которое технически никогда ранее не встречалось. Также учтите, что если вы сравниваете данное вредоносное ПО с тем, что было замечено ранее, новый вариант в этом отношении будет практически необнаружимым.

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

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

Системные вызовы

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

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

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

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

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

Мы собрали около 250 следов доброкачественных и вредоносных программ. Мы сделали это, собрав образцы вредоносных программ в Интернете и запустив их на закрытой виртуальной машине. Говорят, что вредоносное ПО стало достаточно продвинутым, чтобы сбежать с виртуальной машины и заразить хост, но у меня не было другого выбора (не знаю, случайно ли клавиатура моего компьютера перестала работать из-за проблемы с программным обеспечением).

Вот пример трассировки системного вызова, взятой прямо из папки моего проекта:

С этим нельзя работать!

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

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

NtTraceControl (CtrlCode=0xf, InputBuffer=0x19f748, InputBufferLength=0xa0, OutputBuffer=0x19f748, OutputBufferLength=0xa0, ReturnLength=0x19f73c [0xa0]) => 0

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

Before: 
NtTraceControl (CtrlCode=0xf, InputBuffer=0x19f748, InputBufferLength=0xa0, OutputBuffer=0x19f748, OutputBufferLength=0xa0, ReturnLength=0x19f73c [0xa0]) => 0
After:
NtTraceControl

Таким образом, трассировка, с которой работали программы машинного обучения, выглядела скорее так:

Это лишь часть моей папки журналов вредоносных программ:

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

N-граммы и TF-IDF

Эти концепции объясняются во части 2 этой серии.

Microsoft не собирается создавать системный вызов специально для злонамеренных целей. Именно особый порядок использования этих системных вызовов может представлять собой вредоносный процесс. Вот почему мы интегрировали использование N-Grams:

Мы хотим проанализировать последовательности системных вызовов, а не только отдельные системные вызовы. Вот почему мы использовали n-граммовые представления системных вызовов. Фактически мы использовали 8 граммов.

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

Итак, наши векторные представления системных вызовов состояли из значений TF-IDF 8-граммовых системных вызовов. Эти данные были введены в алгоритм машины опорных векторов, оптимизированный с помощью стохастического градиентного спуска.

Тестирование и результаты

Мы разбиваем набор данных в соотношении 1: 4. 80% данных было использовано для обучения классификаторов, а 20% - для проверки их качества. Ниже приводится результат наиболее эффективного классификатора:

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

Прохладный! Таким образом, этот проект был участием меня и моего друга на Международной выставке науки и техники Intel 2018. Наш проект был назван одним из пяти лучших проектов регионального раунда Intel Cup в Чэнду, Китай, и мы собираемся принять участие в финале в Питтсбурге, штат Пенсильвания, через два месяца! На местной ярмарке мы также выиграли Йельскую премию науки и техники.

Эта статья была просто интуитивно понятным и упрощенным объяснением исследовательского проекта.

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