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 behaviors 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.
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
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)
beacon> inlineExecute-Assembly –dotnetassembly /root/Desktop/simpleMain.exe –main
Use Case
Go HAM
beacon> inlineExecute-Assembly –dotnetassembly /root/Desktop/Seatbelt.exe –assemblyargs AntiVirus AppLocker –amsi –etw –appdomain forRealLegit –mailslot forRealLegit
Caveats
Some detection and mitigation strategies that could be used:
The rmmod command in Linux removes a loaded module from the running kernel. Because the kernel has…
The free command in Linux gives you a quick summary of RAM and swap usage. It reads…
The diff command in Linux compares two text files line by line and shows the lines that…
DNS cache is a temporary database your OS and browser build as you browse. Each time you visit a website, the domain-to-IP mapping is saved locally, cutting out the round trip to a remote DNS server on repeat visits. Stale entries are the most common reason to flush the DNS cache: a server moves to a new IP, but your OS or browser still routes to the old address. This guide covers how to clear the DNS cache on Windows, Linux, and macOS, and how to flush the separate cache stored inside Chrome and Firefox. Flush DNS Cache on Windows The command is the same on Windows 10, Windows 11, and earlier supported releases. Open Command Prompt with administrator privileges. Type cmd in the Windows search bar, right-click Command Prompt, and select Run as…
Using a strong, unique password for every account is one of the most effective security…
Ubuntu locks the root account by default. New users often wonder what the root password…