Криптография: палка о двух концах, часть 2
Автор: Frederic Raynal, перевод Logos
В первой части статьи мы обсудили основные понятия криптовирологии. В качестве примеров злонамеренного использования криптографии были рассмотрены слабые места руткита SuckIt, а также принципы написания эффективного SSH-червя. В конце статьи мы начали рассматривать «бронированные» (armored) вирусы.
Во второй части мы продолжим дискуссию о «бронированных» вирусах (использующих полиморфизм и метаморфизм) рассмотрением принципов работы червя Bradley, который использует криптографию, чтобы предотвратить анализ свого кода. А потом сделаем краткий обзор известного приложения Skype, как пример использования встроенного шифрования и закрытого протокола, которые, тем не менее, могут быть эксплуатированы в злонамеренных целях.
Коротко о главном: «бронированные» вирусы
В первой части мы начали рассматривать «бронированные» вирусы, давайте обобщим эти данные. Мы знаем, что время критический фактор, как в наступательной, так и в оборонительной составляющей вируса. Методы защиты интеллектуальной собственности, используемые разработчиками легального программного обеспечения, с таким же успехом используются и вирусописателями. Вирус, использующий технологии предотвращения или задержки анализа своего кода, называется «бронированным». Первый известный вирус этого класса назывался Whale и впервые распространился где-то в сентябре 1990 г. Он совмещал в себе следующие технологии:
- Полиморфизм: и бинарный файл, и процесс были зашифрованы (около 30 жестко закодированных версий).
- Технология стелс (stealth): несколько прерываний, включая отладочные, перехватывались Whale. Также вирус прятался в высшей памяти до уменьшения предела памяти, известной DOS.
- Бронирование: изменения кода зависели от архитектуры системы (8088 или 8086), интенсивно использовалась обфускация (запутывание) кода, а также имелся анти-отладчик (anti-debugger) (если обнаруживался отладчик, блокировалась клавиатура, и Whale уничтожал себя). Если сегодня эти технологии используются чуть ли не в каждом вирусе, можно представить себе, с какими проблемами сталкиваются аналитики антивирусных лабораторий.
Теперь продолжим изучение «бронированных» вирусов.
Изменение формы (полиморфизм и метаморфизм)
Фред Коэн (Fred Cohen) дал довольно четкое определение вируса:
Вирус – это последовательность инструкций, которая при интерпретации в правильной среде меняет другие последовательности инструкций так, что создает в этой среде свою копию.
Это определение подразумевает, что у единичного вируса может быть много представлений. Поэтому Коэн определяет два других важных понятия: вирусный набор и эволюция:
- Вирус определяется не единичным представлением, но набором всех семантически эквивалентных представлений.
- Эволюция вируса – это его действия по превращению из одного представления в другое в одном вирусном наборе.
Таким образом, известные реализации полиморфизма и метаморфизма – всего лишь способы сделать копию вируса, отличную от исходной. Давайте познакомимся с этими методами поближе.
Полиморфизм – технология, используемая для шифрования тела вируса и создания нового механизма шифрования и нового ключа каждый раз, когда вирус копирует себя (Рис. 1). В качестве элементарного примера представьте, что шифрующими инструкциями являются последовательные команды ADD, XOR и т.п., и ключ меняется при каждом исполнении. Более продвинутые (и эффективные) методы включают:
- Беспорядочность кода дешифровщика: изменение последовательности инструкций (вычисление длины, восстановление esp, дешифрующая инструкция, цикл, и т.д.).
- Псевдо-случайная дешифровка по указателю: вместо последовательной дешифровки, код дешифруется по изменяемому указателю.
- Разнообразность инструкций: представление одних и тех же инструкций разными способами (например, xor \%eax, \%eax и movl \$0, \%eax).
- Мусорные инструкции: вставка бесполезных инструкций между полезных.
- Случайность регистров: в новых копиях вируса используются различные регистры в определенных инструкциях.
Рис. 1: Разные полиморфные копии одного вируса.
Главная слабость полиморфизма в том, что дешифрованный код всегда один и тот же, что облегчает обнаружение вируса во время его выполнения. Чтобы избежать этого, метаморфизм делает следующий шаг.
Метаморфизм – технология, изменяющая весь исходный код вируса при создании новых копий (Рис. 2). Полиморфизм можно рассматривать как метаморфизм со специализированной дешифрующей процедурой. Самая элементарная реализация метаморфизма может быть осуществлена добавлением мусорных инструкций, использованием разных регистров и т.д. Более продвинутые (и эффективные) методы включают:
- Перемешивание кода: изменение последовательности процедур, блоков процедур и т.п.
- Модификация исполняемого потока: вставка jmp и call, test и т.п.
- Интеграция кода: код вставляется в другие куски кода, и все указатели на данные изменяются соответственно (примером служит вирус ZMist).
Рис. 2: Копии одного и того же вируса с разным синтаксисом.
Последние слова о полиморфизме. Эта технология используется не только в вирусах, но и в шеллкодах (shellcode). Однако, разработка эффективного полиморфного механизма задача не простая. Для вирусов важно, чтобы их копии были как можно более случайными (различными), т.к. «фиксированные» точки могут быть использованы как сигнатуры для антивирусов. Достижение этого за пределами возможностей большинства вирусописателей.
Что касается шеллкодов, шифрующие инструкции могут создать недопустимые результаты (например, 0x00 в середине strcpy()). Более того, многочисленные NOP, обычно размещаемые перед шеллкодом, не являются шифрующими инструкциями и должны быть видоизменены. Но главная криптографическая слабость в обоих случаях в том, что ключ присутствует в коде, что упрощает анализ, как для людей, так и для эмуляторов.
Поэтому следующий вопрос, который нам необходимо задать: можно ли создать вирус без использования ключа или его дешифровщика? Вы, наверное, спросите, зачем вообще это нужно? Это всего лишь дело тактики. Если злоумышленник удалит ключ, и пространство ключа достаточно большое, то невозможно будет извлечь правильный ключ. Если он удалит дешифрующую процедуру, то ключ станет бесполезным, если, конечно, криптоаналитик не угадает используемый метод шифрования. Таким образом, вирус может избежать обнаружения (эмуляторами, IDS, антивирусами) и анализа (или предотвратить анализ). Но существуют и другие варианты.
Куда подевались ключи?
Не все криптоалгоритмы равносильны. Некоторые проще анализировать, например шифрование методом XOR (исключающее ИЛИ) с коротким ключом. Однако если вирусописатель использует хорошо зарекомендованный алгоритм, то ключ вряд ли получится извлечь. Назовём первую ситуацию слабым шифрованием, а вторую сильным.
Если вирусописатель собирается удалить ключ, то он должен каким-то образом передать его дешифрующей процедуре. Таким образом, дешифрующей процедуре должна предшествовать процедура генерации ключа.
Когда мы используем слабое шифрование, мы можем взломать шифр, используя исчерпывающую атаку. Эта атака извлекает ключ, исследуя поисковое пространство. Этот метод называется Алгоритм Случайной Расшифровки, АСР (RDA – Random Decryption Algorithm). Существует два вида RDA:
- Детерминированный АСР: время вычислений всегда одинаково.
- Недетерминированный АСР: время вычислений нельзя предугадать.
Вернемся в тактическим соображениям. Слабые шифры можно взломать, но всё равно они дают вирусу достаточно времени для распространения. Они также усложняют работу эмуляторов, особенно если цикл вычислений длится слишком долго. Следующий вопрос, конечно же: может ли вирусописатель добиться больших успехов с использованием сильного шифрования?
Bradley
Bradley – вирус, не поддающийся анализу. Общая структура вируса Bradley состоит из четырех частей (смотрите Рис. 3, EVP – Environmental Viral Payload, начинка вируса в соответствующей среде):
- Дешифрующая функция D собирает информацию для создания ключа и расшифровки соответствующего кода.
- Зашифрованный код EVP1 (ключ k1) содержит все анти-антивирусные механизмы.
- Зашифрованный код EVP2 (ключ k2) отвечает за распространение и механизмы полиморфизма/метаморфизма.
- Зашифрованный код EVP3 (ключ k3) содержит любую дополнительную начинку.
Рис. 3: Структура вируса Bradley.
Большая часть шифрования в Bradley основана на использовании ключей, соответствующих определенной среде. Идея начинается с защиты ключей: вирус, действующий в реальных условиях, не может нести с собой ключи, потому что в случае поимки, аналитики получают их и анализируют вирус.
Исходя из этого, идея состояла в создании ключей «по требованию», в зависимости от среды, в которой распространяется вирус. Пусть n будет числом, соответствующим определенной среде, H будет хеш-функцией, m – хеш этой функции от среды n, и k будет ключом. Мы можем определить несколько протоколов для создания ключа. Возьмем два примера:
- Если H(n)==m, то k=n (проблема: ключ в открытом виде).
- Если H(H(n))==m, то k=H(n). Здесь надежность k зависит от надежности H.
Эти два примера не самые стойкие к расшифровке, они представлены здесь, чтобы дать основную идею.
А что насчет использования среды, в которой действует вирус? Вариантов много: системное время, хеш-значение определенной web-страницы, хеш RR элемента DNS ответа, содержимое определенного файла, информация в почтовом сообщении, погодные условия (температура) или значения других web-сервисов (например, рынок валюты), и т.д.
Т.е. вирусу Bradley (дешифрующей функции D) необходима какая-либо информация, которая также доступна вирусописателю, для создания правильных ключей.
Наибольшие сложности возникают с эффективным управлением ключами. Допустим, D собирает всю необходимую информацию, включая ту, что находится под контролем вирусописателя (назовем её a). Далее вычисляется H(H(n+a)+e1), где е1 обозначает первые 512 битов зашифрованного кода EVP1, и если значение функции равно m, то искомый ключ равен H(n+a). В противном случае D полностью очищает систему от вируса. Далее, ключ k2 вычисляется как k2=H(c1+k1) (с1 – последние 512 бит расшифрованного EVP1). Т то же самое для EVP3 (k3).
При самовоспроизведении следует изменить всё, включая значение m. Это можно достичь обновлением информации о среде n и созданием новых m’ и k1’. А так как EVP1 также меняется, соответственно меняются и остальные данные и ключи.
С оперативной точки зрения, утечка информации ограничена EVP1 и поиском заданной информации a, которая не может быть извлечена благодаря хеш-функции. Так что, даже если код будет обнаружен и доставлен для анализа в лабораторию, его невозможно будет анализировать без информации a.
Это свойство интересно само по себе. Но злоумышленник может выжать из Bradley гораздо больше. Он может комбинировать ключи среды и полиморфизм. Если предположить, что ключи среды зависят от свойств/настроек системы жертвы, то:
- Аналитик не сможет определить, на какие системы нацелен вирус.
- Злоумышленник получает эффективный контроль над распространением вируса:
- Если жертва человек, вирус может использовать его почтовый адрес, а еще лучше его открытый ключ (GPG или SSH, например).
- Если жертва является «группой», вирусу необходимо найти специфичную для этой группы информацию, типа доменного имени компании и т.п.
Аналитики должны исследовать последствия работы вируса Bradley и то, как злоумышленники могут использовать его в злонамеренных целях.
Вопросы скрытности
Для того чтобы избежать уничтожения и анализа, вирусу достаточно оставаться незамеченным. Давайте теперь посмотрим, как вирусописатели улучшают скрытность своих творений, используя криптографию.
Отсутствие процедуры дешифровки
Вернемся к механизму полиморфизма, который мы рассматривали выше. Мы уже знаем, что можно избежать внедрения ключа в вирус.
Мы имеем ключ и зашифрованные данные, которые требуется расшифровать. Соответственно, нам необходимо найти процедуру дешифровки (более того, она должна быть точной противоположностью шифрующей процедуры). Вирус является паразитом, и вирусописатели делают их еще более паразитными: в нашем примере мы воспользуемся шифрованием, предоставляемым зараженной системой (типа CryptoAPI в Windows и OpenSSL в Unix). Мы будем использовать CryptoAPI в нашем примере:
int main(int argc, char *argv[])
{
HCRYPTPROV hCryptProv;
HCRYPTHASH hCryptHash;
HCRYPTKEY hCryptKey;
BYTE szPassword[] = "...";
DWORD i, dwLength = strlen(szPassword);
BYTE pbData[] = "...";
CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hCryptHash);
CryptHashData(hCryptHash, szPassword, dwLength, 0);
CryptDeriveKey(hCryptProv, CALG_RC4, hCryptHash,
CRYPT_EXPORTABLE, &hCryptKey);
CryptEncrypt(hCryptKey, 0, TRUE, 0, pbData, &dwLength, dwLength);
}
Дешифровка осуществляется заменой CryptEncrypt() на CryptDecrypt(), а алгоритм изменяется модификацией одной константы.
Создание шеллкода с помощью CryptoAPI ничем не отличается от того что делается при создании шеллкода для Windows. Начинается всё с поиска kernel32.dll, а затем GetProcAddress() и LoadLibrary(). Теперь следует подгрузить advapi32.dll и найти выше упомянутые функции, а затем вызвать их для дешифровки кода перед выполнением.
Этот общий подход может быть интересен при создании многоступенчатого шеллкода, который будет защищать информацию, посылаемую жертве. В случае с вирусами, использование больших и сложных внешних библиотек усложнит работу эмуляторов. Проблема с таким подходом в том, что последовательность функций легко узнаваема.
Эксплуатирование встроенной криптографии
Некоторые исследователи считают Skype естественным образом «бронированным», размножающимся с помощью человека вирусом. Конечно, это прежде всего шутка, но в каждой шутке есть доля правды. В нашем обзоре мы увидим, что можно сделать с помощью многочисленных возможностей Skype и его встроенного шифрования.
Исполняемые модули Skype защищены несколькими уровнями шифрования, и множество проверок целостности расположены в разных частях кода. С сетевой точки зрения, Skype может побороть любой брандмауэр туннелированием своего трафика. Он пытается соединиться с сервером авторизации и другим специфичным сервисам через 80 и 443 порты. Однако если эти порты не открыты, Skype пробует другие TCP и UDP порты. Более того, его протокол полностью закрыт: для него нет никакой доступной документации. И в довершение всего, пользователи с полной уверенностью устанавливают это приложение.
Авторизация осуществляется через центральный сервер, принадлежащий Skype (и его родительской компании eBay). Исполняемый модуль содержит 13 открытых ключей, связанных со Skype и сервером авторизации. Когда пользователь авторизуется:
- Генерируется 1024-битный RSA ключ (p, s).
- Генерируется ключ сессии k.
- Пользователь предоставляет свой пароль.
Затем происходит вычисление, и данные авторизации отправляются серверу:
RSAskype(k || AES256k(p || MD5( || "\nskyper\n" || ))))
Значит, используется RSA с одним из открытых ключей Skype. Таким образом, шифруется ключ сессии k. Этот ключ k используется для шифрования нового открытого ключа p с помощью AES256. После всего этого отсылается MD5-хеш данных авторизации. Т. е. злоумышленнику требуется достать MD5( || "\nskyper\n" || ), чтобы авторизоваться в качестве определенного пользователя. Вся остальная информация либо открыта (ключи), либо предоставляется по востребованию.
С точки зрения криптографии главная слабость в том, что существует возможность «переиграть». Т.е. если кто-то (помимо Skype) может говорить по Skype и перехватывать трафик, он может использовать данные авторизации, чтобы притвориться другим пользователем.
Теперь посмотрим, что же может сделать злоумышленник с помощью Skype.
С внутренней стороны используется множество различных видов шифрования, но также присутствует сжатие данных, и всё это вместе с недокументированным протоколом: никто не сможет определить злонамеренный трафик, а это как раз то, что нужно вирусам, червям и другим malware. Но в отличие от SuckIt и SHH, как мы видели раньше, нет никакой возможности выполнить произвольный код на стороне клиента, т.к. злоумышленнику необходима уязвимость в приложении.
С внешней стороны соединение между двумя клиентами выглядит прямым, даже если оно перенаправляется другими узлами. Это, к сожалению, повысит точность работы червя в данной среде. И, наконец, сама P2P-структура очень избыточна и динамична, что повышает выживаемость червей. Таким образом, как только в Skype (или внешней библиотеке, используемой Skype) обнаружится уязвимость, у червей появится очень и очень хороший полигон для действий.
Давайте представим вариант червя для этой ситуации. Он может эксплуатировать уязвимость в UDP-пакете или в нескольких TCP-пакетах (это не выдумка, смотрите Silver Needle in the Skype, Black Hat Amsterdam, 2006). Червь может обходить сетевые фильтры, чтобы достичь локальных сетей и от них соединяться с любой точкой в Интернете. Конечно же, он может использовать «защищенный канал», используемый Skype закрытый и шифруемый протокол, чтобы избегать обнаружения IDS/IPS. А благодаря структуре P2P-сетей и некоторым их свойствам, точность его работы будет близка к 100%:
- Если червь находится на машине клиента, он может распространяться с помощью функции поиска.
- Если червь находится на одном из главных узлов, он может заразить всех клиентов этого узла.
Если в каждый момент времени около пяти миллионов пользователей используют Skype, можно себе представить, какие перспективы открываются для червя. В качестве начинки червь может нести что угодно, например она может изменять открытые ключи Skype так, что пользователь больше не сможет соединяться с сетью.
В этом основа идеи создания Частной Сети Skype. Если кто-то «вычистит» исполняемый модуль (уберет уровни шифрования, проверки целостности и т.п.), изменит открытые ключи и IP-адреса главных сервисов и заменит их на свои, то получит в свое распоряжение частную сеть. Из этого исходит большая часть критики в адрес Skype. Т.к. Skype никем не сертифицируется (кроме своих разработчиков), то может делать все что угодно. Будем надеяться, что security-сообщество откроет глаза разработчикам Skype.
Заключение
Существует много других способов использования криптографии в злонамеренных целях. Возьмем, к примеру, выживаемость вирусов. Вирусописатель может создать что-то бессмертное («неубиваемое»), что-то, без чего не сможет функционировать операционная система, типа Explorer в Windows. Но можно сделать и так, что сам пользователь не захочет уничтожать вирус, т.к. в результате этого потеряются важные данные или нарушится работоспособность системы.
Нужно смотреть на эту проблему в перспективе. Следует понять подходы, которые используются искушенными злоумышленниками, чтобы уметь защищаться от них.
Ссылки:
- Криптография: палка о двух концах, часть 1
www.securitylab.ru