![]() |
В мире низкоуровневого программирования существует категория задач, где требуется выйти за пределы собственного процесса и взаимодействовать с чужим адресным пространством. В этой статье мы разберём, зачем это может понадобиться, какие методы инъекции существуют, и как реализовать базовую DLL для внедрения.
1. Введение 2. Привилегия Debug в токенах пользователей 3. Варианты инъекций DLL 4. Заключение 1. Введение DLL инъекция - это вполне легальный метод внедрения своего кода в сторонние приложения. Она широко используется в разработке инструментов безопасности, а её тайный замысел зависит исключительно от совести разработчика. Вот возможные сценарии применения этой техники: 1. Мод для расширения функционала ПО. Горячие "Hot-Patch" фиксы позволяют исправлять ошибки в приложениях. Или-же кастомизация интерфейса, как это делает например программа "MacType". Она внедряет свою DLL в процессы Win, чтобы улучшить стандартный механизм сглаживания шрифтов. Аналогичным образом поступает и "PuntoSwitcher", для автоматической смены раскладки клавиатуры Ru/Eng. 2. Антивирусы EDR/XDR - вот кто легальные пользователи этой технологии. В офисах аверов кипит работа по внедрению своих либ, чтобы проверять подозрительные файлы в песочнице "Sandbox" и отслеживать их поведение. Это позволяет шпионить за выделением памяти, вызовами API, и другими действиями малвари в реальном времени. Продукты класса EDR (CrowdStrike, Kaspersky)используют API-Hook внутри системных процессов, для блокировки атак на-лету. 3. В игровой индустрии фишка применяется для внедрения оверлеев в код, чтобы рисовать поверх интерфейса FPS-счётчики и отправлять юзеру всякие уведомления, без модификации файлов самой игры. Это касается и загрузки всевозможных модов, для изменения логики игры. Да, на лицо вмешательство в работу других приложений, но майки официально предоставляют API Код:
SetWindowsHookEx()Код:
CreateRemoteThread()2. ПривилегииDebug и Backupв токенах пользователей Понятно, что подсистема безопасности Win не позволит кому-попало резвиться в системе на своё усмотрение - для этого как минимум потребуются правами админа, а в большинстве случаях и привилегия отладки SeDebugPrivilege. Но проблема в том, что функция Код:
AdjustTokenPrivileges()Ознакомиться со списком своих привилегий можно командой Код:
whoami /privКод:
AdjustTokenPrivileges()А вот лист дефолтных прав админа, и мы можем активировать любую из них, в том числе дарующие нам полную свободу Debug и Backup: При таких раскладах, если обычному юзеру потребуется привилегия SeDubug (а для Dll-Inject она необходима), он может через Код:
DuplicateTokenEx()Код:
secpol.mscКод:
Локальные политики --> Назначения прав пользователям --> Отладка программ --> Добавить пользователя..3. Варианты реализацииDLL-Inject Классический метод инъекций заключается в цепочке вызовов: Код:
OpenProcess() --> VirtualAllocEx() --> WriteProcessMemory() --> CreateRemoteThread()Как одноразовый шприц такой приём может и подойдёт, но на долгосрочную перспективу его уже не натянешь. Это наследие прошлого, и начиная с Win7 если и работает, то с большим ограничением. После того как племя служб и сервисов перекочевало в закрытую сессию(0), перечисленная выше триада уже не может до них дотянуться, и нужно искать альтернативные подходы. Мир открывает столько возможностей, что зацикливаться на одних концепциях просто глупо. Идеи витают в воздухе, пока кто-нибудь не ухватит их, после чего все остальные дружной гурьбой копи-пастят. Но это как грабить уже ограбленный банк, который оцепила кругом полиция. Забавно, что каждое такое ограбление ослабляет охрану остальных объектов, а потому нужно найти наименее охраняемый периметр. Поскольку к каждому сарайчику часового не приставишь, значит простор для творческих манёвров у нас всё-таки есть. Во-первых, можно поместить свой код в асинхронную очередь потока APC (Asynchronous Procedure Call) - этим занимается функция Код:
QueueUserAPC()Код:
CreateFile()Код:
Read/WriteFile()C-подобный: Код:
QueueUserAPCКод:
SleepEx()Код:
WaitForSingleObjectEx()Код:
bAlertable =1Код: Код:
0: kd> !process 0 3 akelpad.exe3.1. Обобщение методов DLL-инъекций CreateRemoteThread() - классический метод. Поддерживается всеми версиями Win, но легко обнаруживается античитами из-за характерного паттерна: новый поток создаётся в процессе, который его не создавал. Плюсы: простота реализации + высокая надёжность. Минусы: легко детектится, оставляя явные следы. QueueUserAPC() - асинхронный вызов. Метод использует существующие потоки целевого процесса. Он добавляет вызов в очередь APC потока, который выполняется, когда поток перейдёт в "Аlertable" состояние. Плюсы: не создаёт новых потоков (сложнее обнаружить). Минусы: требует, чтобы в процессе был поток в alertable состоянии (не все процессы подходят). NtCreateThreadEx() - метод Native API. Поскольку многие системы мониторинга проверяют только Win32-API, этот метод может остаться незамеченным. Плюсы: меньше отслеживается античитами, минусы: зависимость от недокументированных структур, а потому может сломаться с обновлениями Win. SetWindowsHookEx() - перехват сообщений. Данная техника использует легитимный механизм Win-хуков. При установке, ОС сама загружает DLL с обработчиком в процессы. Плюсы: использует легитимный механизм (не создаёт подозрительных потоков). Минусы: ограничен процессами только с графическим интерфейсом GUI. Thread Hijacking - перехват потока. Более сложный метод. Инжектор приостанавливает существующий поток в целевом процессе, сохраняет его контекст (регистры, стек), подменяет Код:
RIP/EIPReflective DLL Injection - ручной маппинг Этот метод не вызывает Код:
LoadLibrary()Код:
DllMain()4. Выводы Инжект - мощный инструмент в арсенале разработчика. На fasm эта техника реализуется достаточно прямолинейно, сохраняя всю гибкость и контроль, которые даёт ассемблер. Понимание механизмов инъекции критически важно и для защитников: антивирусы и системы обнаружения вторжений активно мониторят характерные паттерны этих методов. Изучая инъекцию мы не только расширяем свои возможности как разработчика, но и глубже понимаем принципы безопасности Win в целом. Важно помнить, что это палка с двумя концами - при работе всегда нужно соблюдать законодательство и лицензионные соглашения. Разрешено: Отладка собственных программ, разработка модов к играм с разрешения разработчика, создание инструментов мониторинга для корпоративного использования. Запрещено: Взлом чужого ПО, создание читов для онлайн-игр (нарушает пользовательское соглашение), разработка вредоносного ПО. По понятным причинам код готового инжектора не выкладываю, тем более что информации и так достаточно получилось. В сл.части рассмотрим, как можно найти и удалить с любых процессов внедрённые в них описанными выше способами сторонние либы - там и будет полный код анти-инжекта. Всем удачи, пока! |
Изучая dll инъекции обнаружил интересную штуку: если изначально прямо вписать функции OpenProcess, VirtualAlloc, WriteProcessMemory, CreateRemoteThread, встроенный антивирусник windows ругается (на какие именно комбинации этих функций уже не помню). Но если их вызывать с помощью GetProcAddress т.е. узнаем адресс нужной функции и вызываем ее простым call, то уже все окей)
|
| Время: 20:25 |