Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

В компьютерном программировании , DLL инъекция является методом , используемым для запуска кода в пределах адресного пространства другого процесса , заставляя его загрузить динамическую библиотеку . [1] Внедрение DLL часто используется внешними программами, чтобы повлиять на поведение другой программы так, как ее авторы не ожидали или не планировали. [1] [2] [3] Например, внедренный код может перехватить системные вызовы функций, [4] [5] или прочитать содержимое текстовых полей пароля , что невозможно сделать обычным способом. [6]Программа, используемая для внедрения произвольного кода в произвольные процессы, называется инжектором DLL .

Подходы в Microsoft Windows [ править ]

В Microsoft Windows есть несколько способов заставить процесс загружать и выполнять код в DLL, которые авторы не планировали:

  • DLL, перечисленные в записи реестраHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs , загружаются в каждый процесс, который загружает User32.dll во время первоначального вызова этой DLL. [7] [8] [9] Начиная с Windows Vista , AppInit_DLL по умолчанию отключены. [10] Начиная с Windows 7, инфраструктура AppInit_DLL поддерживает подписывание кода . Начиная с Windows 8 , вся функциональность AppInit_DLL отключается, когда включена безопасная загрузка , независимо от подписи кода или настроек реестра. [11]
  • DLL, перечисленные в разделе реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDLLs, загружаются в каждый процесс, который вызывает функции Win32 API CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW и WinExec. Это правильный способ использовать легальную инъекцию DLL в текущей версии Windows - Windows 10. DLL должна быть подписана действующим сертификатом.
  • Функции управления процессами, такие как CreateRemoteThread, или методы внедрения кода, такие как AtomBombing [12], могут использоваться для внедрения библиотеки DLL в программу после ее запуска. [5] [6] [13] [14] [15] [16]
    1. Откройте дескриптор целевого процесса. Это можно сделать, запустив процесс [17] [18] или отключив что-то, созданное этим процессом, о существовании которого известно, - например, окно с предсказуемым заголовком, [19] или получив список запущенных процессов. [20] и поиск имени файла целевого исполняемого файла. [21]
    2. Выделите часть памяти в целевом процессе [22], и в него будет записано имя внедряемой DLL. [13] [23]
      Этот шаг можно пропустить, если подходящее имя DLL уже доступно в целевом процессе. Например, если процесс ссылается на ' User32.dll ', ' GDI32.dll ', ' Kernel32.dll ' или любую другую библиотеку, имя которой заканчивается на '32 .dll ', можно будет загрузить библиотеку с именем '32. .dll '. Ранее было продемонстрировано, что этот метод эффективен против метода защиты процессов от внедрения DLL. [24]
    3. Создайте новый поток в целевом процессе [25] с начальным адресом потока, установленным как адрес LoadLibrary, и аргументом, установленным на адрес строки, только что загруженной в целевой объект. [13] [26]
      Вместо того, чтобы записывать имя загружаемой библиотеки DLL в целевой объект и запускать новый поток в LoadLibrary, можно записать код, который необходимо выполнить, в целевой объект и запустить поток с этого кода. [6]
    4. Затем операционная система вызывает процедуру инициализации внедренной DLL. [13] [27]
    Обратите внимание, что без мер предосторожности этот подход может быть обнаружен целевым процессом из-за уведомлений DLL_THREAD_ATTACH, отправляемых каждому загруженному модулю при запуске потока. [27]
  • Windows , закрепляя вызовы , такие , как SetWindowsHookEx. [2] [5] [6] [28] [29] [30]
  • Используйте функцию SuspendThread или NtSuspendThread, чтобы приостановить все потоки, а затем используйте функцию SetThreadContext или NtSetContextThread, чтобы изменить контекст существующего потока в приложении для выполнения внедренного кода, который, в свою очередь, может загрузить DLL. [4] [31] [32]
  • Используйте ограничения дизайна в Windows и приложениях, которые вызывают функцию LoadLibrary или LoadLibraryEx без указания полного пути к загружаемой DLL. [33] [34] [35]
  • Операционная система на уровне прокладки .
  • Замена библиотеки DLL для конкретного приложения мошеннической заменой, которая реализует тот же экспорт функций, что и оригинал. [36]

Подходы к Unix-подобным системам [ править ]

В Unix-подобных операционных системах с динамическим компоновщиком на основе ld.so (в BSD ) и ld-linux.so (в Linux ) произвольные библиотеки могут быть связаны с новым процессом, указав путь к библиотеке в переменной среды LD PRELOAD. , который можно настроить глобально или индивидуально для одного процесса. [37]

Например, в системе Linux эта команда запускает команду «prog» с разделяемой библиотекой из файла «test.so», связанного с ней во время запуска:

LD_PRELOAD = "./test.so" прога

Такую библиотеку можно создать так же, как и другие общие объекты . В GCC это включает в себя компиляцию исходного файла, содержащего новые глобальные объекты, которые необходимо связать, с параметром -fpic или -fPIC , [38] и связывание с параметром -shared . [39] Библиотека имеет доступ к внешним символам, объявленным в программе, как и любая другая библиотека.

В macOS следующая команда запускает команду «prog» с разделяемой библиотекой из файла «test.dylib», связанной с ней во время запуска: [40]

DYLD_INSERT_LIBRARIES = "./test.dylib"  DYLD_FORCE_FLAT_NAMESPACE = 1 прога

Также возможно использовать методы на основе отладчика в Unix-подобных системах. [41]

Образец кода [ править ]

Использование функции API LoadLibrary [ править ]

В приведенном ниже примере функции используется метод внедрения DLL, который использует тот факт, что kernel32.dll отображается на один и тот же адрес почти во всех процессах. Поэтому LoadLibrary (которая является функцией kernel32.dll) также отображается на тот же адрес. LoadLibrary также подходит для процедуры запуска потока, требуемой CreateRemoteThread.

#include  <windows.h>РУЧКА  inject_DLL ( Const  символ *  имя_файла ,  INT  ПИД ) {  HANDLE  h_process  =  OpenProcess ( PROCESS_ALL_ACCESS ,  FALSE ,  ПИД );  // получение дескриптора целевого процесса char  fullDLLPath [ _MAX_PATH ];  // получение полного пути к файлу dll  GetFullPathName ( имя_файла ,  _MAX_PATH ,  fullDLLPath ,  NULL ); LPVOID  DLLPath_addr  =  VirtualAllocEx ( h_process ,  NULL ,  _MAX_PATH ,  MEM_COMMIT  |  MEM_RESERVE ,  PAGE_READWRITE );  // выделение памяти в целевом процессе  WriteProcessMemory ( h_process ,  DLLPath_addr ,  fullDLLPath ,  strlen ( fullDLLPath ),  NULL );  // записываем путь к dll в эту память LPVOID  LoadLib_addr  =  GetProcAddress ( GetModuleHandle ( "Kernel32" ),  // получение адреса LoadLibraryA (то же самое для  "LoadLibraryA" );  // все процессы), чтобы начать выполнение на нем HANDLE  h_rThread  =  CreateRemoteThread ( h_process ,  NULL ,  0 ,  // запуск потока удаленного выполнения в LoadLibraryA  ( LPTHREAD_START_ROUTINE ) LoadLib_addr ,  DLLPath_addr ,  0 ,  NULL );  // и передавая путь к dll в качестве аргумента WaitForSingleObject ( h_rThread ,  БЕСКОНЕЧНЫЙ );  // ждем завершения DWORD  exit_code ;  GetExitCodeThread ( h_rThread ,  & exit_code );  // получение возвращаемого значения, т. е.  дескриптора модуля, // возвращаемого LoadLibraryA CloseHandle ( h_rThread );  // освобождение дескриптора  внедренного потока VirtualFreeEx ( h_process ,  DLLPath_addr ,  0 ,  MEM_RELEASE );  // ... и память, выделенная для пути к DLL,  CloseHandle ( h_process );  // ... и дескриптор целевого процесса return  ( HANDLE ) код_выхода ; }

Ссылки [ править ]

  1. ^ a b Джеймс Шумейкер (2006). «Анализ внедрения DLL» (PDF) . Презентация GSM . Голубое небо. Архивировано из оригинального (PDF) 3 декабря 2008 года . Проверено 31 августа 2008 года .
  2. ^ a b Iczelion (август 2002 г.). «Учебник 24: ловушки Windows» . Домашняя страница сборки Win32 Iczelion . Архивировано из оригинала на 1 августа 2008 года . Проверено 31 августа 2008 года .
  3. Rocky Pulley (19 мая 2005 г.). «Расширение диспетчера задач с помощью внедрения DLL» . CodeProject . CodeProject. Архивировано из оригинала на 6 февраля 2009 года . Проверено 1 сентября 2008 года .
  4. ^ a b Насер Р. Роухани (23 октября 2003 г.). "Учебник по внедрению DLL и перехвату функций" . CodeProject . CodeProject . Проверено 31 августа 2008 года .
  5. ^ a b c Иво Иванов (2 декабря 2002 г.). «Обнаружен перехват API» . CodeProject . CodeProject . Проверено 31 августа 2008 года .
  6. ^ a b c d Роберт Кустер (20 августа 2003 г.). «Три способа внедрения вашего кода в другой процесс» . CodeProject . CodeProject . Проверено 31 августа 2008 года .
  7. ^ «Работа со значением реестра AppInit_DLLs» . Справка и поддержка Microsoft . Microsoft. 21 ноября 2006 . Проверено 31 августа 2008 года .
  8. Раймонд Чен (13 декабря 2007 г.). «AppInit_DLLs следует переименовать в Deadlock_Or_Crash_Randomly_DLLs» . Старая новая вещь . Microsoft . Проверено 31 августа 2008 года . CS1 maint: обескураженный параметр ( ссылка )
  9. ^ "dllmain.c" . ReactOS . Фонд ReactOS. 8 июля 2008 . Проверено 31 августа 2008 года .[ постоянная мертвая ссылка ]
  10. ^ AppInit_DLL в Windows 7 и Windows Server 2008 R2
  11. ^ «AppInit DLL и безопасная загрузка» . MSDN . Проверено 29 марта 2016 года .
  12. ^ " ' AtomBombing' Microsoft Windows через внедрение кода" . Темное чтение . Проверено 20 апреля 2017 года .
  13. ^ a b c d Трент Уоддингтон. "InjectDLL" . Проверено 31 августа 2008 года .
  14. ^ "Dll Injection" . DreamInCode.net . MediaGroup1. 4 мая 2006 года архивации с оригинала на 2 сентября 2008 года . Проверено 31 августа 2008 года .
  15. Грег Дженкинс (ноябрь 2007 г.). «Фреймворк для внедрения DLL» . Ring3 Circus . WordPress . Проверено 31 августа 2008 года .
  16. Дрю Бентон (17 августа 2007 г.). «Более полное решение для внедрения DLL с использованием CreateRemoteThread» . CodeProject . CodeProject . Проверено 1 сентября 2008 года .
  17. ^ "CreateProcess" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  18. ^ "ПРОЦЕСС_ИНФОРМАЦИЯ" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  19. ^ "Функция GetWindowThreadProcessId" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  20. ^ "EnumProcesses" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  21. ^ "GetModuleBaseName" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  22. ^ "VirtualAllocEx" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  23. ^ "WriteProcessMemory" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  24. ^ "Аванпост обхода самозащиты через усовершенствованную инъекцию DLL с уязвимостью кражи дескрипторов" . Matousec . 1 декабря 2006 . Проверено 31 августа 2008 года .
  25. ^ "CreateRemoteThread" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  26. ^ "LoadLibrary" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  27. ^ a b "DllMain" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  28. ^ "Функция SetWindowsHookEx" . Платформа SDK для Windows XP SP2 . Microsoft . Проверено 31 августа 2008 года .
  29. ^ «Значение реестра AppInit_DLL и Windows 95» . Справка и поддержка Microsoft . Microsoft. 1 марта 2005 . Проверено 31 августа 2008 года .
  30. ^ «Внедрение DLL с использованием метода SetWindowsHookEx ()» . Смена игры . 3 апреля 2008 . Проверено 1 сентября 2008 года .
  31. ^ "SetThreadContext DLL Injection" . 16 января 2007 . Проверено 1 сентября 2008 года .
  32. Бен Ботто (6 сентября 2008 г.). «Инжектор DLL» . Архивировано из оригинала на 7 февраля 2009 года . Проверено 1 сентября 2008 года .
  33. ^ «Небезопасная загрузка библиотеки может позволить удаленное выполнение кода» . Microsoft . 10 июня 2011 . Проверено 20 апреля 2016 года .
  34. ^ "Безопасная загрузка библиотек для предотвращения атак предварительной загрузки DLL" . Microsoft . 10 июня 2011 . Проверено 8 августа 2012 года .
  35. ^ «Microsoft Security Advisory: небезопасная загрузка библиотеки может позволить удаленное выполнение кода» . Microsoft . 10 июня 2011 . Проверено 20 апреля 2016 года .
  36. ^ Николас Falliere (26 сентября 2010). «Заражение Stuxnet проектов Step 7» . Symantec.
  37. ^ Линус Торвальдс ; Дэвид Энгель; Эрик Янгдейл; Питер Макдональд; Хунцзю Лу; Ларс Вирзениус; Митч Д'Суза (14 марта 1998 г.). «ld.so/ld-linux.so - динамический компоновщик / загрузчик» . Справочные страницы UNIX . Архивировано из оригинала на 6 февраля 2009 года . Проверено 31 августа 2008 года . CS1 maint: обескураженный параметр ( ссылка )
  38. ^ «Параметры генерации кода» . Использование коллекции компиляторов GNU (GCC) . Фонд свободного программного обеспечения . Проверено 31 августа 2008 года . Сгенерируйте позиционно-независимый код (PIC), подходящий для использования в разделяемой библиотеке, если поддерживается для целевой машины. sqq.-fpic
  39. ^ "Параметры ссылки" . Использование коллекции компиляторов GNU (GCC) . Фонд свободного программного обеспечения . Проверено 31 августа 2008 года . Создайте общий объект, который затем можно связать с другими объектами, чтобы сформировать исполняемый файл. sqq.-shared
  40. ^ "Уловка LD_PRELOAD" . Питер Голдсборо . Проверено 17 мая 2017 года .
  41. Григорий Шпитальник (12 февраля 2009 г.). «Внедрение кода в работающее приложение Linux» . Код проекта . Проверено 18 ноября 2010 года .