InlineExecute-Assembly is a proof of concept Beacon Object File (BOF) that allows security professionals to perform in process .NET assembly execution as an alternative to Cobalt Strikes traditional fork and run execute-assembly module

Overview

InlineExecute-Assembly

InlineExecute-Assembly is a proof of concept Beacon Object File (BOF) that allows security professionals to perform in process .NET assembly execution as an alternative to Cobalt Strikes traditional fork and run execute-assembly module. InlineExecute-Assembly will execute any assembly with the entry point of Main(string[] args) or Main(). This should allow you to run most released tooling without any prior modification needed.

The BOF will automatically determine which Common Language Runtime (CLR) is needed to be loaded into the process for your assembly (v2.0.50727 or v4.0.30319) prior to execution and in most cases, should exist gracefully if any issues arise. The BOF also supports several flags which allow the operator to dictate several behaivors prior to .NET execution which include, disabling AMSI via in memory patching, disabling and restoring ETW via in memory patching, customization of the CLR App Domain name to be created, whether to create and direct console output of your assembly to a named pipe or mailslot, and allows the operator to switch the default entry point of Main(string[] args) to Main(). More details on usage, use cases, and possible detections can be found below and https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/.

Lastly the advantage of executing our .NET assemblies in the same process as our beacon implant is that we avoid the default behavior of Cobalt Strike's execute-assembly module which creates a new process to then load/inject the CLR/.NET assembly. However, other opsec considerations still exist, for example, does the process we are executing within normally load the CLR or does the .NET assembly we are executing have any known signatures? Therefore, the disadvantage is that if something does get detected and killed, for example by AMSI, your beacon is also killed.

Subject References

This tool wouldn't exist without being able to piggyback off some really great research, tools, and code already published by members of the security community. So thank you. Lastly, if you feel anyone has been left out below, please let me know and I will be sure to get them added.

  • HostingCLR - here - CLR/Executing assembly logic
  • Dotnet-Loader-Shellcode - (by @modexpblog) - here - All around great research including on COM Interfaces for executing .NET in C -> Real MVP
  • Donut - (by @TheRealWover and @modexpblog) - here - COM Interfaces Header
  • Memory Patching AMSI Bypass - (by @_RastaMouse) - here - AMSI memory patching research
  • Metasploit-Execute-Assembly - (by @b4rtik) - here - Modified AMSI patching and used find .NET version function
  • ExecuteAssembly - (by @med0x2e)- here - Modified aggressor script
  • Hiding Your .NET ETW - (by @xpn) - here - Great ETW research
  • ETW BOF - (by @ajpc500)- here - Modified ETW patching
  • ExecuteAssembly_Mailslot - (by @N4k3dTurtl3)- here - Modified using mailslots for console redirection
  • @freefirex2 - Was kind enough to share some good BOF inner workings and gotcha's.

Getting Started

  1. Copy the inlineExecute-Assembly folder with all of its contents to a system you plan to connect with via the Cobalt Strike GUI application.
  2. Load in the inlineExecute-Assembly.cna Aggressor script
  3. Run inlineExecute-Assembly --dotnetassembly /path/to/assembly.exe for most basic execution (see use cases below for specific flag examples)

Build Your Own

Run the below command inside the src directory via x64 Native Tools Command Prompt for VS 2019

cl.exe /c inlineExecute-Assembly.c /GS- /FoinlineExecute-Assemblyx64.o

Run the below command inside the src directory via x86 Native Tools Command Prompt for VS 2019

cl.exe /c inlineExecute-Assembly.c /GS- /FoinlineExecute-Assemblyx86.o

Flags

--dotnetassembly        Directory path to your assembly **required**
--assemblyargs          Assembly arguments to pass
--appdomain             Change default name of AppDomain sent (default value is totesLegit and is set via the included aggressor script) *Domain always unloaded*
--amsi                  Attempts to disable AMSI via in memory patching (If successful AMSI will be disabled for the entire life of process)
--etw                   Attempts to disable ETW via in memory patching (If successful ETW will be disabled for the entire life of process unless reverted)
--revertetw             Attempts to disable ETW via in memory patching and then repatches it back to original state
--pipe                  Change default name of named pipe (default value is totesLegit and is set via the included aggressor script)
--mailslot              Switches to using mailslots to redirect console output. Changes default name of mailslot (If left blank, default value is totesLegit and is set via the included aggressor script)
--main                  Changes entry point to Main() (default value is Main(string[] args))

Use Case

Execute .NET assembly

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe

Use Case

Execute .NET assembly with arguments

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker

Use Case

Execute .NET assembly with arguments and disable AMSI

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --amsi

Use Case

Execute .NET assembly with arguments and disable ETW

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --etw

Use Case

Execute .NET assembly with arguments and redirect output via mailslots instead of the default named pipe

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --mailslot

Use Case

Execute .NET assembly with arguments and change the default named pipe name set in the aggressor script

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --pipe forRealLegit

Use Case

Execute .NET assembly and change the default app domain set in the aggressor script

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --appdomain forRealLegit

Use Case

Execute .NET assembly with Main() entry point instead of the default Main(string[] args)

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/simpleMain.exe --main

Use Case

Go HAM

Syntax

beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --amsi --etw --appdomain forRealLegit --mailslot forRealLegit

Caveats

  1. While I have tried to make this as stable as possible, there are no guarantees things will never crash and beacons won’t die. We don’t have the added luxury of fork and run where if something goes wrong our beacon lives. This is the tradeoff with BOFs. With that said, I can’t stress how important it is that you test your assemblies beforehand to make sure they will work properly with the tool.
  2. Since the BOF is executed in process and takes over the beacon while running, this should be taken into account before being used for long running assemblies. If you choose to run something that will take a long time to get back results, your beacon will not be active to run more commands till the results come back and your assembly finishes running. This also doesn’t adhere to sleep set. For example, if your sleep is set at 10 minutes and you run the BOF, you will get results back as soon as the BOF finishes executing.
  3. Unless modification is done to tools that load PE’s in memory (e.g., SafetyKatz), these will most likely kill your beacon. Many of these tools work fine with execute assembly because they are able to send their console output from the sacrificial process before exiting. When they exit via our in process BOF, they kill our process, which kills our beacon. These can be modified to work but I would advise running these types of assemblies via execute assembly since other non-OPSEC friendly things could be loaded into your process that don’t get removed.
  4. If your assembly uses Environment.Exit this will need to be removed as it will kill the process and beacon.
  5. Named pipes and mail slots need to be unique. If you don’t receive data back and your beacon is still alive, the issue is most likely you need to select a different named pipe or mail slot name.

Detection

Some detection and mitigation strategies that could be used:

  1. Uses PAGE_EXECUTE_READWRITE when performing AMSI and ETW memory patching. This was done on purpose and should be a red flag as very few programs have memory ranges with the memory protection of PAGE_EXECUTE_READWRITE.
  2. Default name of named pipe created is totesLegit. This was done on purpose and signature detections could be used to flag this.
  3. Default name of mailslot created is totesLegit. This was done on purpose and signature detections could be used to flag this.
  4. Default name of AppDomain loaded is totesLegit. This was done on purpose and signature detections could be used to flag this.
  5. Good tips on detecting malicious use of .NET (by @bohops) here, (by F-Secure) here, and here
  6. Looking for .NET CLR loading into suspicious processes, such as unmanaged processes which should never have the CLR loaded.
  7. Event Tracing here
  8. Looking for other known Cobalt Strike Beacon IOC's or C2 egress/communication IOC's.
You might also like...
An implementation and proof-of-concept of Process Forking.

ForkPlayground A library to implement the Process Forking attack described in this blog post. ForkLib - C++ library that implements the Process Forkin

Cobalt Strike BOF - Bypass AMSI in a remote process with code injection.
Cobalt Strike BOF - Bypass AMSI in a remote process with code injection.

Cobalt Strike BOF - Inject AMSI Bypass Cobalt Strike Beacon Object File (BOF) that bypasses AMSI in a remote process with code injection. Running inje

King Hamlet is a simple tool, which allows you to perform a Process Ghosting Attack

KingHamlet Process Ghosting Tool - 64 bits Only! King Hamlet is a simple tool, which allows you to perform a Process Ghosting Attack

Proof of concept userspace filesystem that executes filenames as shell commands and makes the result accessible though reading the file.

ExecFS Proof of concept userspace filesystem that executes filenames as shell commands and makes the result accessible though reading the file. $ ./ex

Beacon Object File allowing creation of Beacons in different sessions.
Beacon Object File allowing creation of Beacons in different sessions.

JumpSession_BOF This is a Beacon Object File allowing creation of Beacons in different sessions. Must be Elevated. This BOF was created on the heels o

Load and execute COFF files and Cobalt Strike BOFs in-memory

COFFLoader2 This repo contains the source code of a Common Object File Format (COFF) loader, which is a rewrite of the research and implementation don

 	Cobalt Strike is a commercial, full-featured, remote access tool that bills itself as
Cobalt Strike is a commercial, full-featured, remote access tool that bills itself as "adversary simulation software designed to execute targeted attacks and emulate the post-exploitation actions of advanced threat actors".

COBALT STRIKE 4.4 Cobalt Strike is a commercial, full-featured, remote access tool that bills itself as "adversary simulation software designed to exe

Resources for DFIR Professionals Responding to the REvil Ransomware Kaseya Supply Chain Attack

Resources for DFIR Professionals Responding to the REvil Ransomware Kaseya Supply Chain Attack Yesterday Sophos and Huntress Labs identified that Kase

Process Ghosting - a PE injection technique, similar to Process Doppelgänging, but using a delete-pending file instead of a transacted file
Process Ghosting - a PE injection technique, similar to Process Doppelgänging, but using a delete-pending file instead of a transacted file

Process Ghosting This is my implementation of the technique presented by Gabriel Landau: https://www.elastic.co/blog/process-ghosting-a-new-executable

Comments
  • Remove the explicit size argument

    Remove the explicit size argument

    BeaconDataExtract provides the size of the extracted data through the optional size parameter. Using that allows the parameter to be removed and also eliminates the possibility of a descrepancy where size != len(data).

    This doesn't make much of a difference for Cobalt Strike users because the aggressor script handled the value automatically. For Metasploit users however, it removes the necessity to know the size in bytes of the .NET executable file. This makes it easier to use since the BOF arguments have to be explicitly packed.

    See: https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/beacon-object-files_main.htm#BeaconDataExtract

    Metasploit examples (because I don't have Cobalt Strike) Before Note the 10th parameter 4608 which is the size in bytes of HelloWorld1.exe.

    meterpreter > execute_bof /home/smcintyre/Repositories/InlineExecute-Assembly/inlineExecuteAssembly/inlineExecute-Assemblyx64.o --format-string ziiiiizzzib "totesLegit" 0 0 0 0 1 "totesLegit" "totesLegit" "" 4608 file:/home/smcintyre/HelloWorld1.exe
    
    
    Hello, World
    
    [+] inlineExecute-Assembly Finished
    
    meterpreter >
    

    After Now there are only 10 parameters because the size doesn't need to be specified.

    meterpreter > execute_bof /home/smcintyre/Repositories/InlineExecute-Assembly/src/inlineExecute-Assemblyx64.o --format-string ziiiiizzzb "totesLegit" 0 0 0 0 1 "totesLegit" "totesLegit" "" file:/home/smcintyre/HelloWorld1.exe
    
    
    Hello, World
    
    [+] inlineExecute-Assembly Finished
    
    meterpreter > 
    
    opened by zeroSteiner 0
Owner
anthemtotheego
anthemtotheego
Cobalt Strike Beacon Object File (BOF) that takes the name of of a PE file as an argument and spawns the process in a suspended state

Beacon Object File (BOF) that spawns an arbitrary process from beacons memory. Supports Parent Process ID (PPID) spoofing & blocking non-MS signed DLLs from loading into the processes memory (some EDR DLLs).

boku 349 Dec 1, 2022
Proof of concept Beacon Object File (BOF) that attempts to detect userland hooks in place by AV/EDR

Detect-Hooks Detect-Hooks is a proof of concept Beacon Object File (BOF) that attempts to detect userland API hooks in place by AV/EDR. The BOF will r

anthemtotheego 121 Dec 25, 2022
Cobalt Strike Beacon Object File (BOF) that uses handwritten shellcode to return the process Environment strings without touching any DLL's.

Cobalt Strike "Where Am I?" Beacon Object File Cobalt Strike Beacon Object File (BOF) that uses handwritten shellcode to return the process Environmen

Bobby Cooke 92 Nov 30, 2022
EarlyBird process hollowing technique (BOF) - Spawns a process in a suspended state, inject shellcode, hijack main thread with APC, and execute shellcode

HOLLOW - Cobalt Strike BOF Authors: Bobby Cooke (@0xBoku) Justin Hamilton (@JTHam0) Octavio Paguaga (@OakTree__) Matt Kingstone (@n00bRage) Beacon Obj

Bobby Cooke 203 Dec 20, 2022
Cobalt Strike beacon object file implementation for trusted path UAC bypass. The target executable will be called without involving

Beacon object file implementation for trusted path UAC bypass. The target executable will be called without involving "cmd.exe" by using DCOM object.

Chris Au 91 Dec 28, 2022
This repository is meant to host the core files needed to create a Beacon Object File for use with Cobalt Strike

BOF Template This repository is meant to host the core files needed to create a Beacon Object File for use with Cobalt Strike. A Beacon Object File (B

Cobalt Strike 42 Nov 9, 2022
A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types and values using Ptrace during program execution.

print-function-args-debugger A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types an

*finixbit 15 Jun 17, 2022
Proof-of-concept implementation for the paper "Osiris: Automated Discovery of Microarchitectural Side Channels" (USENIX Security'21)

Osiris This repository contains the implementation of the Osiris framework discussed in the research paper "Osiris: Automated Discovery of Microarchit

CISPA 41 Nov 11, 2022
A Beacon Object File that creates a minidump of the LSASS process.

NanoDump A Beacon Object File that creates a minidump of the LSASS process. Features It uses syscalls (with SysWhispers2) for most operations You can

HelpSystems 1.1k Jan 5, 2023
A BOF for enumerating version information for DLLs associated for a Beacon process.

DLL Image Resource Version Enumeration BOF What is this? This is a Cobalt Strike BOF file (a mildly massaged port of @N4k3dTurtl3's existing PoC , mea

null 10 Nov 5, 2022