Содержание статьи
На практике в большинстве случаев существующая база или ядро вредоноса повторно используется для создания новой разновидности малвари. Вирусописатели особо не заморачиваются с затратной по времени разработкой новых «качественных» вирусов, а просто используют имеющиеся образцы.
Этот повторно используемый код может быть собран заново с помощью другого компилятора, из него могут быть удалены или, наоборот, в него могут быть добавлены новые функции. Обновляются некоторые библиотеки, меняется распределение кода внутри файла (при этом применяются новые компоновщики, пакеры, обфускация и так далее). Смысл таких преобразований — придать хорошо знакомой антивирусу вредоносной программе новый вид. В этом случае видоизмененная версия вируса какое-то время останется необнаруженной. Тем не менее существуют способы детектирования такого рода переупаковок и модификаций.
Эти техники обнаружения зачастую используются для анализа большого массива данных и поиска в нем общих элементов. Практическими примерами использования похожих техник могут быть глобально распределенные базы знаний, такие как Virus Total и базы антивирусных компаний, а также подходы Threat Intelligence.
Хеш «четкий»
Ханс Петер Лун из IBM еще в 1940-е разрабатывал системы для анализа информации, в том числе исследовал вопросы хранения, передачи и поиска текстовых данных. Это привело его к созданию алгоритмов преобразования, а затем и к хешированию информации в качестве способа поиска телефонных номеров и текста. Так индексация и концепция «разделяй и властвуй» сделали свои первые шаги в области вычислительной техники.
Сейчас существует множество алгоритмов хеширования, отличающихся криптостойкостью, скоростью вычисления, разрядностью и другими характеристиками.
Мы привыкли ассоциировать хеш-функции с криптографическими хеш-функциями. Это распространенный инструмент, который используется для решения целого ряда задач, таких как:
- аутентификация;
- электронная подпись;
- обнаружение вредоносного ПО (как файлов, так и их маркеров компрометации).
В сегодняшней статье речь пойдет о том, как различные алгоритмы хеширования помогают нам бороться с зловредным ПО.
Что такое хеш
Криптографическая хеш-функция, чаще называемая просто хешем, — это математическое преобразование, переводящее произвольный входной массив данных в состоящую из букв и цифр строку фиксированной длины. Хеш считается криптостойким, если справедливо следующее:
- по хешу нельзя восстановить исходные данные;
- выполняется устойчивость к коллизиям, то есть невозможно получить из различных входных последовательностей одинаковые хеши.
MD5, SHA-1 и SHA-256 — наиболее популярные криптографические алгоритмы вычисления хеша, которые часто используются в детектировании вредоносного ПО. Еще совсем недавно вредонос опознавали только по сигнатуре (хешу) исполняемого файла.
Но в современных реалиях недостаточно знать просто хеш объекта, так как это слабый индикатор компрометации (IoC). IoC — это все артефакты, на основе которых может быть выявлен вредонос. Например, используемые им ветки реестра, подгружаемые библиотеки, IP-адреса, байтовые последовательности, версии ПО, триггеры даты и времени, задействованные порты, URL.
Рассмотрим «пирамиду боли» для атакующего, придуманную аналитиком в области информационной безопасности Дэвидом Бьянко. Она описывает уровни сложности индикаторов компрометации, которые злоумышленники используют при атаках. Например, если ты знаешь MD5-хеш вредоносного файла, его можно довольно легко и при этом точно обнаружить в системе. Однако это принесет очень мало боли атакующему — достаточно добавить один бит информации к файлу вредоноса, и хеш изменится. Таким образом вирус может переселяться бесконечно, и каждая новая его копия будет иметь отличный от других экземпляров хеш.
Если ты имеешь дело с множеством вредоносных образцов, становится понятно, что большинство из них по сути своей не уникальны. Злоумышленники нередко заимствуют или покупают исходники друг у друга и используют их в своих программах. Очень часто после появления в паблике исходных кодов какого-либо вредоносного ПО в интернете всплывают многочисленные поделки, состряпанные из доступных фрагментов.
Как же определить схожесть между разными образцами малвари одного семейства?
Для поиска такого сходства существуют специальные алгоритмы подсчета хеша, например нечеткое (fuzzy) хеширование и хеш импортируемых библиотек (imphash). Эти два подхода используют разные методы обнаружения для поиска повторно встречающихся фрагментов вредоносных программ, принадлежащих к определенным семействам. Рассмотрим эти два метода подробнее.
«Нечеткий» хеш — SSDeep
Если в криптографических хеш-функциях суть алгоритма состоит в том, что при малейшем изменении входных данных (даже одного бита информации) их хеш также значительно изменяется, то в нечетких хешах результат меняется незначительно или не изменяется вовсе. То есть нечеткие хеши более устойчивы к небольшим изменениям в файле. Поэтому подобные функции позволяют намного более эффективно обнаруживать новые модификации вредоносного ПО и не требуют больших ресурсов для расчета.
Нечеткое хеширование — это метод, при котором программа, такая как, например, SSDeep, вычисляет кусочные хеши от входных данных, то есть использует так называемое контекстно вызываемое кусочное хеширование. В англоязычных источниках этот метод называется context triggered piecewise hashing (CTPH aka fuzzy hashing).
На самом деле классификаций нечетких хешей довольно много. Например, по механизму работы алгоритмы делятся на piecewise hashing, context triggered piecewise hashing, statistically improbable features, block-based rebuilding. По типу обрабатываемой информации их можно разделить на побайтовые, синтаксические и семантические. Но если речь заходит о нечетких хешах, то это, как правило, CTPH.
Алгоритм SSDeep разработан Джесси Корнблюмом для использования в компьютерной криминалистике и основан на алгоритме spamsum. SSDeep вычисляет несколько традиционных криптографических хешей фиксированного размера для отдельных сегментов файла и тем самым позволяет обнаруживать похожие объекты. В алгоритме SSDeep используется механизм скользящего окна rolling hash. Его еще можно назвать рекурсивным кусочным хешированием.
Часто CTPH-подобные хеши лежат в основе алгоритмов локально чувствительных хешей — locality-sensitive hashing (LSH). В их задачи входит поиск ближайших соседей — approximate nearest neighbor (ANN), или, проще говоря, похожих объектов, но с чуть более высокоуровневой абстракцией. Алгоритмы LSH используются не только в борьбе с вредоносным ПО, но и в мультимедиа, при поиске дубликатов, поиске схожих генов в биологии и много где еще.
Алгоритм SSDeep
Как работает SSDeep? На первый взгляд, все довольно просто:
- он разделяет файл на более мелкие части и изучает их, а не файл в целом;
- он может определить фрагменты файлов, которые имеют последовательности одинаковых байтов, расположенных в схожем порядке, либо байты между двумя последовательностями, где они могут различаться как по значению, так и по длине.
Virus Total использует SSDeep, который выполняет нечеткое хеширование на загружаемых пользователями файлах. Пример — по ссылке.
Итак, рубрика э-э-эксперименты! Возьмем по 18 образцов исполняемых файлов нашумевших вирусяк: среди них — MassLogger (имена образцов будут начинаться с аббревиатуры ML), Agent Tesla (AT) и Emotet (EMO). Только вот где мы найдем такое количество малвари? Да на базаре.
Теперь давай посмотрим, что же мы загрузили для испытаний. Agent Tesla — это .NET-кейлоггер и RAT, подробнее о нем рассказано вот в этой статье. Emotet — банковский троян с возможностью червеобразного распространения. При запуске сразу определяет, что работает не в виртуалке, иначе завершается. MassLogger, как и Agent Tesla, представляет собой кейлоггер. При этом он входит в топ-5 по популярности лета и осени 2020 года. Они оба используют механизм доставки вредоносных программ GuLoader, который загружает зашифрованную полезную нагрузку, лежащую на обычных платформах для обмена файлами.
Мы будем работать с .EXE-семплами, у каждого из испытуемых объектов уникальная криптографическая хеш-сумма SHA-1. Перечислим их все (команда для любителей Linux: shasum ML
):
f59a138da63769720e61e37fe52030774472db19 ML1.exe bd57fd4002228352bf60186562d0dde87f4f33e5 ML2.exe 89ebb9ff3ab6c9a3330e798036bb81cec29c417f ML3.exe e9029f66cc313a41b22cb922da7f52a899ac166c ML4.exe 1dde9710a0d780b42678f41bbc949c82f13a74af ML5.exe 8c635bc0aaf4214024cf7342d5f186ebf6171652 ML6.exe 3cb9d16fa0bf3d72f12bf844e0a293d818512c54 ML7.exe 619480abce06d5221c1dd430233fa19ff7f863b5 ML8.exe ab1aed403d37d2f90f2a59505b0724927790841e ML9.exe 65e9d26cf5e6742bdf0a772f6c9692ec533aded7 ML10.exe 3e5b239ddab79130b5b8ffe623c6272d365774d8 ML11.exe c53e68fe71b695e2c7fb6c05aedb422bf5856f7b ML12.exe 6c610f5675f7fb4d78ca2b6e4be9ff43ba47c929 ML13.exe 10cf5e8f60ddac43813e5b8880aa84805e4a30d8 ML14.exe d7a1665e425fe63054c5c836b3807f58da43948a ML15.exe 98e0a38ab5db61a6eb7b50f4e09556af7f46978d ML16.exe 2c2010e2fa02f4c70ea9dd5083026d0138f655d5 ML17.exe 67ee652bc805fc8f5c9c653785b4d82baae0f78e ML18.exe
С использованием SSDeep рассчитаем кусочный хеш каждого из файлов и сохраним результат в файле командой ssdeep MassLogger/* > ML.ssd
. На выходе получим следующее:
ssdeep,1.1--blocksize:hash:hash,filename
24576: uf+B91xtspzq6wqAkSq+EQsnn3OF7dAhaG0K uUKp15AkSTsn3BH0K ML1.exe 24576: DoYHyzf8WEE0us0U5xDO/qLaVGbwfyXQHHNG ECcFEE0Px2qLaVuwagA ML2.exe 12288: OnaPI5TFAYwISkHXqrzcTo4BRzsWnLu8nbFNgreeWhBdgkuAgb6DxlPH9p+iq3T4 OnaQvwImc04Hdu8n5NgjMd26D3+lwt ML3.exe 12288: lDi43RqqJKN07vvaRfdjSGM/lBp62o53T7Q+Xu9BwckDj9F2Tzhs0kf3PYeD0d8t l2UTYy7vQaDiTXuvRMxF2xr6QeIdOV ML4.exe 24576: tGDh1aKoqw13WhVUSQK3+dUrSU4O5kddtp+Gyce 4Dx8h0USQKudUry0ite ML5.exe 12288: bOr02ehwuCC3t9DDnHSHoCdK5fskDfccfUt0IY81e0cXNi/Zb0kk1uuCucUXnwHY 6A2nuhe1dGPD06y0KbT/L8pnuusZdBE ML6.exe 24576: uA2nuhe1dGPD06y/C0UfDcBbcIt/nTh/WeFcLQ7 uvu8d8Aq+BR18eMQ7 ML7.exe 24576: 7Lo4IwxEo1796aAkBWvn7kGg9b5rrd9S/9+ 4nzamn7Hg9bJd92 ML8.exe 24576: NGDh1aKoqw13WhVUSM6j3xwra6hPG2VM+sJRcFpoprV89 YDx8h0USMU3xwO6NTsJymG ML9.exe 24576: KA2nuhe1dGPD06yxaG2acKrXOfIWkV353 Kvu8d8AqlhkV53 ML10.exe 24576: NGDh1aKoqw13WhVUS27LIQ/34mXyx7pxrkkQiD YDx8h0US273f4mXyBpxrkkQiD ML11.exe 24576: 2MOfNQm+7K/rTpVF2RiMKt34x/rrMt2I132fq 5uGKDrF2RiMW34/nf ML12.exe 24576: aA2nuhe1dGPD06yMSW+M8OxwhFTTLMyQkxN avu8d8AMS9MLwffMGxN ML13.exe 24576: dGDh1aKoqw13WhVUSDukbAEXF5Ujj1J21g IDx8h0USKkESqj1L ML14.exe 24576: CA2nuhe1dGPD06yg199oT5gzUmRVUhxfNw Cvu8d8Ag19q+Um0hxNw ML15.exe 12288: m5EaSrUQ9JakMtlDQ8zJQAqpLMyp84JiIQbTVru1YS+Fi75McDxH01YJf mGaSrUipM88zJ8My8IGTdSAil7tJ ML16.exe 24576: OD7tjHvlHj0eU30aD5Q6/0FW//V17rmBlKLsNTy4z OntjPlY3xluFw/V9rmOLsZR ML17.exe 12288: zOr02ehwuCC3t9DDnHSHoCdK5fskDfccfUtlLAQ8H5AbDarsd9Qg9Iu13SOMirut SA2nuhe1dGPD06ylLAQjbj9IyMira ML18.exe
Выглядит пугающе, правда? Давай сравним объекты между собой (в выводе мы предварительно удалили дубли, оставив уникальные совпадения между семплами). Для этого используем следующую команду:
ssdeep -m ML.ssd -s MassLogger/* > ML_COMPARE.txt
В выводе команды правый столбец — процент совпадения между семплами.
| ML10.exe matches ML.ssd:ML13.exe | (49) |
| ML10.exe matches ML.ssd:ML15.exe | (49) |
| ML10.exe matches ML.ssd:ML18.exe | (49) |
| ML10.exe matches ML.ssd:ML6.exe | (47) |
| ML10.exe matches ML.ssd:ML7.exe | (49) |
| ML11.exe matches ML.ssd:ML14.exe | (49) |
| ML11.exe matches ML.ssd:ML5.exe | (54) |
| ML11.exe matches ML.ssd:ML9.exe | (52) |
| ML13.exe matches ML.ssd:ML15.exe | (50) |
| ML13.exe matches ML.ssd:ML18.exe | (50) |
| ML13.exe matches ML.ssd:ML6.exe | (50) |
| ML13.exe matches ML.ssd:ML7.exe | (50) |
| ML14.exe matches ML.ssd:ML5.exe | (47) |
| ML14.exe matches ML.ssd:ML9.exe | (47) |
| ML15.exe matches ML.ssd:ML18.exe | (49) |
| ML15.exe matches ML.ssd:ML6.exe | (47) |
| ML15.exe matches ML.ssd:ML7.exe | (46) |
| ML18.exe matches ML.ssd:ML6.exe | (60) |
| ML18.exe matches ML.ssd:ML7.exe | (49) |
| ML5.exe matches ML.ssd:ML9.exe | (49) |
| ML6.exe matches ML.ssd:ML7.exe | (55) |
Получается, что в исследуемых семплах присутствуют стабильно кочующие участки кода, которые обеспечивают схожесть. Поскольку такой вывод, скажем честно, малоинформативен, для наглядности изобразим связи в виде графа.
Из 18 объектов оказалось всего восемь никак не связанных между собой образцов, но это пока... Тем не менее можно смело утверждать, что мы выявили целое семейство вредоносов. Теперь протестируем остальные объекты из других групп и сравним результаты.
Сразу изобразим граф связности для образцов Agent Tesla. Не будем перечислять хеш-суммы образцов, а сразу приступим к сравнению: сначала файлов между собой, затем с семплами MassLogger.
Для Agent Tesla также обнаружено два семейства взаимосвязанных семплов и десять воинов-одиночек. Что дальше? Сравним SSDeep-хеши MassLogger с объектами Emotet. Пусто, нет совпадений. А если с Agent Tesla? Строим граф.
Бинго! Совпадения есть, и взаимопроникновение фрагментов кода семейств Agent Tesla и MassLogger доказано.
Однако не всегда у исследователя достаточно семплов и образцов вредоносов других семейств — например, для семейства Emotet. На графе видно, что из всех 18 объектов 13 так или иначе связаны между собой, а семплы EMO3, EMO9, EMO11, EMO15 и EMO18 не нашли «друзей», и их мы отражать на рисунке не станем.
Итак, что же в итоге у нас получилось? У групп MassLogger есть пять объектов, связанных с объектами Agent Tesla. Почему так вышло? Во-первых, это два кейлоггера, у них есть пересечения в функциональности. Во-вторых, они оба используют один и тот же загрузчик. В каждом из тестов находились связи (то есть сходства) между объектами более чем на 50%. Иными словами, из 18 образцов так или иначе были связаны между собой как минимум девять. Среди семплов нашлись по меньшей мере две группы связанных объектов, а у Emotet — сразу три группы. Теперь давай рассмотрим другой тип хеш-функций, и, возможно, мы найдем новые взаимосвязи.
Хеш импортируемых библиотек — imphash
Imphash расшифровывается как import hash — «хеш импортов», то есть всех импортируемых программой библиотек, прописанных в исполняемом файле Windows Portable Executable (PE). Чтобы вычислить imphash, все импортированные библиотеки и связанные с ними функции выгружаются в строковом формате, объединяются, а затем криптографически хешируются. Virus Total также высчитывает по этому алгоритму хеш для PE-файлов.
Естественно, злоумышленники знают о таком алгоритме и могут его обойти, сделав свой вирус более модульным. Например, можно загружать каждый модуль в память только при необходимости или динамически загружать библиотеки, сохраняя объем импорта настолько малым, насколько позволяет компилятор. При этом любой импорт переносится в память только во время выполнения, а не транслируется в таблице импорта в PE-файле. Вирусы пишут люди, а люди — существа ленивые, нужно немного потрудиться, чтобы перевести работу программы в такой формат.
Перейдем к практике и найдем взаимосвязи среди наших исследуемых групп объектов. Начнем с MassLogger. Появились ли новые связи? Да, мы получили три группы связанных объектов — их imphash идентичны!
Изобразим общие imphash файлов в виде графа. Тут со всеми объектами получается полносвязный граф, так что не суди строго, если какого-то ребра графа не будет! 🙂
Сравним с предыдущим графом из секции экспериментов с SSDeep.
Теперь объединим два получившихся графа в группы по их вершинам.
Получается, что среди 18 образцов MassLogger не нашли себе «друзей» всего три объекта: ML1, ML2 и ML4, а это всего 17% от общего количества. Таким образом, используя две техники, мы выявили и подтвердили взаимосвязи вредоносных семплов и их «группировки».
Далее разберем остальные семейства вредоносных файлов. Agent Tesla по imphash разделился на две большие группы.
Сравним с предыдущим графом из секции тестов с SSDeep.
Объединим два получившихся графа в группы по их вершинам.
Imphash дополнил связи, которые были выявлены на этапе тестирования с SSDeep, и продемонстрировал более целостную картину. Идентичный с левой группой imphash присутствует в образцах группы MassLogger — ML5, ML9, ML11 и ML14.
Далее рассмотрим группу малвари Emotet.
Сравни с предыдущим графом из секции тестов с SSDeep. Напомним, что семплы EMO3, EMO9, EMO11, EMO15 и EMO18 не нашли себе «друзей» в прошлом тесте.
Объединим два получившихся графа в группы по их вершинам.
Опа! Недаром червь Emotet получил такое распространение. В наш тест попали довольно хитрые образцы, у которых, судя по всему, в явном виде не присутствует таблица импортов, а следовательно, отсутствует imphash. Скорее всего, в них используется одна из техник, которые мы перечисляли в разделе об этом типе хеширования.
Анализируя графы взаимосвязей, можно заметить, что благодаря комбинации imphash и SSDeep мы получили новые взаимосвязи между объектами, тем самым значительно расширив базу знаний об исследуемых образцах. И это знание позволяет с относительно малыми затратами эффективно дополнять сигнатурный анализ вредоносного ПО достаточно надежными отпечатками образцов по классу, семейству или типу малвари.