Файл: Изучение методов детектирования ВПО, методов противодействия детектированию ВПО и создание программы для анализа эффективности антивирусов, применяющих те или иные подходы к обнаружению угроз.pdf
Добавлен: 30.06.2023
Просмотров: 84
Скачиваний: 2
По описанию, представленному производителем на официальном сайте продукта - Kaspersky Internet Security 2017 — это надежная защита для компьютера. В состав продукта помимо базовой входит защита интернетсоединения, веб-камеры, платежей в интернете, детей от нежелательной информации, а также возможность поиска и установки обновлений программ и удаления неиспользуемых программ. Выделим основной функционал, который предоставляет данный продукт:
- Выполняет защиту интернет-соединений благодаря встроенной виртуальной сети VPN
- Производит защиту финансовых и банковских операций
- Имеет встроенную функцию родительского контроля, благодаря которой можно ограничить доступ ребенка к нежелательному контенту
Avast Free Antivirus 2017
Приложение распространяется бесплатно и содержит обширную вирусную базу, благодаря чему настолько популярно не только среди пользователей России, но и во всем мире. В Avast встроены модули, которые не предусмотрены даже в некоторых платных программах. Выделим основной функционал, который предоставляет данный продукт:
- Защита компьютера от вирусов
- Безопасная работа в сети Интернет
- Защита проведения финансовых и банковских операций
- Проверка и контроль безопасности сети Wi-Fi
- Поиск ненужных плагинов и расширений в веб-браузере
AVG Internet Security 2017
Платное приложение, подкупающее своим быстродействием. Тем не менее, имеет ярко выраженный минус - возникновение конфликтов при взаимодействии с другими антивирусными приложениями, например, с Windows Defender. Выделим основной функционал, который предоставляет данный продукт:
- Выполняет защиту личной информации
- Контролирует работу в сети интернет, предотвращая вирусные атаки
- Позволяет осуществлять контроль над устройствами через интернет-соединение, которые защищены данным антивирусом Windows Defender
Встроенный в последние версии ОС Windows защитник от компании Microsoft, созданный для того, чтобы удалять, помещать в карантин или
предотвращать появление spyware-модулей в операционных системах Microsoft Windows. Выделим основной функционал, который предоставляет данный продукт:
- Отслеживание подозрительных изменений в определённых сегментах системы в режиме реального времени
- Удаление установленных приложений ActiveX
- Возможность отправлять сообщения о подозрительных объектах в Microsoft для определения его возможной принадлежности к spyware
1.4. Постановка задачи
Таким образом можно сделать следующие выводы. На данный момент необходимым становится своевременное обнаружение ВПО, и применение комплексных мер, направленных на защиту от деструктивных свойств подобных объектов. Этой задачей занимаются антивирусные программы. На сегодняшний день остро встает вопрос о возможностях антивирусных программ. Кроме самих разработчиков антивирусного ПО, которым не выгодно выставлять минусы своей продукции на показ, если о них вообще известно, вопросом безопасности персональных данных в достаточных объемах почти никто не занимается.
ГЛАВА 2. РАЗРАБОТКА И ТЕСТИРОВАНИЕ ПО
2.1. Разработка
Прежде чем начать работу необходимо оговорить функционал разрабатываемого приложения. Главными требованиями к предлагаемому ПО функционалу определим реализацию упаковки исполняемых файлов и обфускацию бинарного кода файла. Почему именно такие требования? Вопервых, это два наиболее исторически возрастных подхода к сокрытию ВПО от АС, а значит и наиболее изученных, следовательно, борьба с данными методами противодействия обнаружению является минимальной планкой для современных АС, во-вторых именно эти способы являются наиболее универсальными, те не требуется реализация под конкретно взятый пример, и в-третьих относительно просты в реализации по сравнению с более современными способами противодействия обнаружению. Разработка приложения будет идти в два этапа: первый – упаковщик, второй – распаковщик. Схема работы разрабатываемого ПО приведена на рис.2.1.
Рисунок
Начать разработку стоит с понимания того, что такое упаковка и как это работает. (см.рис.2.1) Упаковка ни что иное, как уменьшение размера файла с сохранением его работоспособности.
Последовательность действий при упаковке следующая:
1. Считывание бинарного кода приложения в специально отведенный для этого буфер(массив) с последующим сжатием любым удобным для тех или иных целей алгоритмом.
2. Написание распаковщика, который впоследствии будет превращать упакованный на первом этапе массив в исходный байт-код и запускать.
3. Добавление полезной нагрузки в виде полученного на первом этапе массива к распаковщику.
Выглядит довольно просто для понимания, поэтому останавливаться на алгоритме работы упаковщика подробнее не имеет смысла. Приступим непосредственно к реализации, которая как мы поняли будет разбита на 2 этапа – упаковка файла и написание распаковщика. Начнем конечно же с написания упаковщика. Так как нашей конечной целью является обман АС необходимо выбрать такой алгоритм, который будет иметь достаточно высокую степень сжатия при довольно-таки быстрой распаковке. Остановимся на алгоритме LZO, чья эффективность не многим уступает, а распаковщик даже превосходит по скорости zip.
Реализовывать алгоритм LZO не имеет большого смысла, поэтому возьмем готовый реализованный алгоритм, в моем случае версии 2.06. Также при разработке проекта будем использовать готовую библиотеку для работы с PE-файлами. Первое на что следует обратить внимание – структура PE-файла. В силу особенностей строения исполняемых файлов в windows мы не можем просто сжать байт-код и при распаковке получить приложение с исходным функционалом. Со структурой строения PE-файла надо считаться, поэтому нам не остается ничего другого как разобраться в том, как устроены PEфайлы. На рис.2.2 приведено схематическое устройство PE-файла. Забегая вперед хочется отметить, что сохранение именно такой структуры является залогом успешной распаковки.
Рисунок
Итак, что же нам нужно учесть для успешной распаковки. Первое, на что следует обратить внимание – DOS заголовок. Для нашей работы не обязательно подробное изучение этой структуры, достаточно лишь упомянуть, что первое поле e_magic находится по смещению 0 от начала файла и всегда равно “MZ”, а последнее поле e_ifnew содержит в себе смещение PE-заголовка относительно начала файла. DOS-заглушка не представляет для нас никакого интереса, зачастую просто заполнена нулями, поэтому идем дальше. По смещению e_ifnew от начала файла располагается PE – сигнатура. Ее отличительной характеристикой являются неизменные для PE-файлов 4 байта, чьи значения ’P’, ‘E’, 0, 0. Далее идет PE-заголовок или заголовок файла, в нем указываются базовые характеристики файла. Затем опциональный заголовок, он является обязательным, содержит формат файла и необходимую для загрузки файла информацию. Заголовок секций содержит таблицы секций с соответствующими именами, размерами и адресами.
Вышеизложенной информации достаточно для понимания того, что мы будем делать. Процесс создания программы будет описан лишь в ключевых моментах, имеющих отношение к реализации алгоритмов упаковки и распаковки, остальная информация является тривиальной и не имеет смысловой нагрузки на данном этапе работы. Итак, начинаем. Первое, что хочется сделать после открытия файла, это проверить, а требуется ли нам упаковка или файл уже заведомо сжат.
В этом нам поможет энтропия. Реализуем проверку энтропии сразу после открытия файла. Считается, что нормальная энтропия PE-файлов принимает значения до 6.8. Именно с этим значением мы и будем сравнивать полученную энтропию входного файла. Также было бы неплохо проверить не является ли входной файл .NET. Работать с такими файлами мы не будем. Алгоритм работы упаковщика можно описать следующей последовательностью действий:
- Считываем все секции файла
- Компоновка данных в один буфер с последующей упаковкой
- Расположение буфера в новой секции
- Удаление старых секций
Проиллюстрируем вышеупомянутую последовательность действий. (рис.2.3)
Рисунок
Ближайший план действий понятен, приступим непосредственно к реализации. Для начала напишем структуру, для хранения всех параметров существовавших секций оригинального файла, чтобы впоследствии распаковщик мог их восстановить.
Эту структуру мы будем записывать в любое место упакованного файла для каждой секции, а код распаковщика будет эти структуры считывать. В этой структуре будет храниться вся необходимая информация для восстановления секций PE-файла. Кроме того, нам пригодится структура, которая хранит различную полезную информацию об оригинальном файле, которая также понадобится распаковщику. Теперь мы можем приступать к считыванию секций файла. Как только мы это сделаем, нам ничто не помешает перейти непосредственно к упаковке.
Создаем два буфера - packed_sections_info и raw_section_data. Первый буфер хранит идущие подряд структуры packed_section, создаваемые и заполняемые нами для всех имеющихся в PE-файле секций. Второй хранит непосредственно данные всех секций, собранные вместе. Эти данные после распаковки мы без проблем сможем разделить и разложить по секциям заново, потому что информация о размере файловых данных секций хранится в первом буфере и будет доступна распаковщику. Далее будем упаковывать полученные буферы raw_section_data и packed_sections_info. Теперь мы можем создать новую секцию PE-файла, в которой и разместим наши упакованные данные.
Стоит уточнить, что имя секции безусловно должно быть «.rsrc» так как именно это имя зарезервировано под секцию ресурсов, в противном случае они не будут подгружены. И непосредственно сама упаковка. Остается только удалить уже ненужные нам секции PE-файла и добавить в него нашу новую секцию. Немного пояснений о том, что конкретно делаем. Начнем с того, что мы определили виртуальный адрес самой первой секции в PE-файле. Затем, зная выровненный виртуальный размер секций, путем несложных вычислений считаем виртуальный суммарный размер всех секций. Далее мы удалили все существующие секции PE-файла.
После этого добавили нашу секцию в PE-файл и получили ссылку на добавленную секцию с пересчитанными адресами и размерами. Именно с этой ссылкой мы и будем работать дальше. Затем мы меняем виртуальный размер добавленной секции на общий размер всех ранее существовавших секций. Виртуальный адрес добавленной секции будет вычислен автоматически по умолчанию. Но мы должны оставить себе достаточное количество памяти, чтобы потом в нее распаковать все исходные секции. Нас это не очень устраивает, отсюда необходимость в том, чтобы область в памяти, занимаемая нашей секцией, полностью совпала с областью, которую занимали все секции оригинального файла.
Функционал библиотеки для работы с PE-файлами позволяет явно указать виртуальный адрес секции, если она будет первой в файле. Это как раз то, что нам нужно. Теперь нам понадобится еще одна секция. В ней будет располагаться распаковщик. Итак, подытожим проделанные действия. Блок-схема работы упаковщика представлена на рисунке 2.4.
Рисунок
Затем удаляем все используемые директории из заголовков, кроме директории импорта. И сохраняем упакованный файл. Структурная схема полученного упакованного файла приведена на рис.2.5.
Рисунок
Для работы распаковщика нам потребуются две WinAPI-функции: LoadLibraryA и GetProcAddress. Встает вопрос о том, куда загрузчик будет записывать адреса этих двух функций. Решением этой проблемы станет расширение вышеупомянутой структуры packed_file_info. Теперь необходимо создать новую таблицу импорта. В этом нам сильно поможет библиотека для работы с PE-файлами. Поясним, как именно мы это делаем. Для каждой импортируемой библиотеке в PE-файлах создается структура, полями которой являются таблицы IAT и Orignal IAT.
В первую загрузчик записывает адреса импортируемых функций, вторая же хранит их имена или ординалы. Мы будем использовать одну таблицу. Вызов settings.save_iat_and_original_iat_rvas настраивает пересборщик таким образом, что он не будет создавать свои собственные IAT и Original IAT, а запишет все по тем адресам, которые уже указаны в каждой библиотеке. Далее мы просто пересобираем таблицу импортов. Теперь преступаем непосредственно к распаковщику. Стоит обратить внимание на то, что функция объявлена как naked. Это говорит компилятору о том, что не нужно создавать для этой функции пролог и эпилог (стековый фрейм) автоматически. Сделано это для того, чтобы можно было увеличить количество данных, выделяемых на стеке с мыслью о том, что локальных переменных много, и стандартных 128 байт может не хватить. Идем дальше и добавим в тело функции 2 переменные: Первая будет содержать действительный адрес загрузки образа, а вторая - относительный адрес самой первой секции. Далее нам необходимо получить значения полей структуры packed_file_info, которые заполняет загрузчик.