Всех с пятницей, друзья. Сегодня делимся с вами еще одним материалом, переведенным в преддверии запуска курса «Реверс-инжиниринг».
У меня была классная идея, как заставить пользователя запустить ваше приложение без социальной инженерии или применения сторонних эксплойтов. Дальше вы сможете просто двигаться вперед и инициировать массовое заражение исполняемых файлов, но это может вызвать множество непредвиденных проблем, а также будет означать, что приложения с цифровой подписью от доверенных поставщиков будут отображаться как ненадежные файлы. Хорошей идеей будет «захват» всего одной dll. Я не буду называть этот метод обходом UAC(User account Control), поскольку все равно потребуется получить разрешение на запуск приложения (только не вашего).
LoadLibrary
Возможно, вы уже знакомы с этим понятием, но я все же объясню, что это такое. Когда приложение вызывает LoadLibrary в dll, но не предоставляет полный путь к файлу, система сначала проверяет раздел реестра KnownDlls, в котором она ищет путь, если там его нет, система будет искать в каталоге, из которого было выполнено приложение, а уже затем будет искать в системных путях, таких как system32/syswow64.
Вы вполне можете поместить вашу dll в ту же директорию, что и приложение, и дать ей то же самое имя, какое было бы у обычно загружаемой системной dll, но в любом случае, ваша dll должна отвечать следующим требованиям:
- Приложение должно загружать dll по имени, а не по полному пути (как бывает часто);
- Требуемая библиотека не должна существовать в HKLMSYSTEMControlSession ManagerKnownDLLs;
- Ваша dll должна соответствовать архитектуре процессора (помните о том, что 64-разрядные процессоры будут просто пропускать 32-х разрядные библиотеки и наоборот);
- Библиотека находится в System32 или Syswow64, поскольку специфические пути часто не работают.
Вирус ZeroAccess использовал этот метод, чтобы воспользоваться «социальной инженерией» и заставить пользователя запустить файл. Для начала с официального был скачан установщик Adobe Flash, dll бота была записана в ту же директорию, где лежал установщик, а потом установщик запустили. Когда установщик выполнился, контроль учетных записей пользователей выдает сообщение, что приложение поставляется доверенным источником “Adobe Systems Incorporated”, а пользователь с наибольшей вероятностью ставит это приложение (это приводит к тому, что выполняется вредоносная dll бота).
Это настоящее обновление Flash Player? Или ZeroAccess? Никто не знает.
Менее инвазивный метод
Представьте, что существует папка, в которой находятся 90% приложений, которые требуют повышенных прав учетной записи, и что она доступна для записи без такого рода прав. Что ж, такая папка существует и это папка %userprofile%Downloads
. Наверное, вы понимаете, к чему я клоню.
Я не ожидал найти dll, которая загружается большинством приложений и при этом соответствует всем критериям вредоносной dll, и примерно через пять минут поиска я нашел золотую жилу: dwmapi.dll
. Эта библиотека не только соответствовала всем критериям, но и загружалась всеми установочными файлами. Теперь давайте создадим нашу собственную dll, назовем “dwmapi.dll”
, поместим ее в папку Загрузки и запустим установочный файл.
Успех! Но дело в том, что как только мы начнем установку, она не заработает, поскольку мы заменили важную библиотеку, но это легко исправить. Мы инфицируем dll.
Создание DLL инфектора
Сначала я хотел просто добавить новый заголовок раздела, изменить поле NumberOfSections в заголовке PE, а затем просто добавить свой раздел в конец файла PE. Оказалось, что непосредственно после последнего заголовка раздела находится директория связанного импорта, которая будет перезаписан нашим заголовком раздела. Поэтому примерно через 2 часа написания приложения для восстановления всего РЕ с нуля кто-то напомнил мне, что директория связанного импорта существует лишь для того, чтобы ускорить загрузку импортируемых файлов и может быть перезаписана, а затем просто отключена в заголовке РЕ.
Следующие 15 минут я держал CTRL+Z, чтобы вернуться к тому, с чего начал и чувствовал себя глупо. Спустя две строчки кода мой инфектор заработал как надо, и я мог перейти к следующему шагу. Сейчас инфектор просто отключает и перезаписывает директорию связанного импорта новым заголовком раздела, добавляет новый раздел в конец РЕ-файла, корректирует SizeOfImage для размещения нового раздела, а затем изменяет AddressOfEntryPoint, чтобы указать на наш новый раздел.
Все, что нам сейчас нужно, это код, который мы туда поместим.
Шелл-код
Очевидным выбором было заставить добавленный раздел выполнять шелл-код, поэтому нам не нужно беспокоиться о релокациях и импорте. Фактический код довольно прост и написан с использованием некоторых удобных макросов FASM, я быстро пробегусь по тому, как он работает.
- Проверяется стек, чтобы убедиться, что dwmapi.dll была вызвана DLL_PROCESS_ATTACH;
- Используется структура Ldr PEB для получения базового адреса Kernel32 и Ntdll;
- Используется простая реализация GetProcAddress для импорта следующих функций: NtOpenProcessToken, NtQueryInformationToken, NtClose, ExpandEnvironmentStringsA, CreateProcessA;
- Открывается текущий токен процесса и код запрашивает его, чтобы подтвердить, что приложение, из которого мы запускаемся, имеет права администратора UAC;
- Получается путь cmd.exe, а затем вызывается командная строка;
- Выполнение передается обратно в реальную точку входа dwmapi.dll, именно поэтому выполнение может продолжаться.
Соберем все вместе
Конечный результат работы инфицирует dwmapi.dll нашим шелл-кодом и помещает ее в папку загрузок, как только пользователь загружает и запускает установщик, который требует прав администратора, будет вызвана командная строка, запущенная от имени администратора (из-за Wow64FsRedirect и того факта, что большинство настроек работают под wow64, мы можем использовать один и тот же код на 32-разрядных и 64-разрядных системах Windows).
Полный инфектор и шелл-код вы можете найти на моем github: https://github.com/MalwareTech/UACElevator.
На этом все. До встречи на курсе!
Автор: MaxRokatansky