@@ -76,32 +76,58 @@ def execute_WithOutput(self, command):
7676 self .__registry_Path = f"Software\\ Classes\\ { gen_random_string (6 )} "
7777
7878 commands = [
79- f"{ self .__shell } { command } 1> { result_output } 2>&1" ,
79+ # 1. Run the command and write output to file
80+ f'{ self .__shell } { command } 1> "{ result_output } " 2>&1' ,
81+
82+ # 2. Base64 encode the file using PowerShell
8083 f'{ self .__shell } powershell -Command "[Convert]::ToBase64String([IO.File]::ReadAllBytes(\' { result_output } \' )) | Out-File -Encoding ASCII \' { result_output_b64 } \' "' ,
81- f'{ self .__shell } for /F "usebackq" %G in ("{ result_output_b64 } ") do reg add HKLM\\ { self .__registry_Path } /v { keyName } /t REG_SZ /d "%G" /f' ,
82- f"{ self .__shell } del /q /f /s { result_output } { result_output_b64 } " ,
84+
85+ # 3. Use PowerShell to split base64 content into 16KB chunks and store in registry
86+ f'{ self .__shell } powershell -Command "$b64 = Get-Content -Raw \' { result_output_b64 } \' ; '
87+ f'$chunksize = 16000; '
88+ f'$count = [math]::Ceiling($b64.Length / $chunksize); '
89+ f'for ($i = 0; $i -lt $count; $i++) {{ '
90+ f' $chunk = $b64.Substring($i * $chunksize, [math]::Min($chunksize, $b64.Length - ($i * $chunksize))); '
91+ f' $name = \\ "{ keyName } _chunk_$i\\ "; '
92+ f' reg add \\ "HKLM\\ { self .__registry_Path } \\ " /v $name /t REG_SZ /d $chunk /f }}; '
93+ f'reg add \\ "HKLM\\ { self .__registry_Path } \\ " /v \\ "{ keyName } \\ " /t REG_DWORD /d $count /f"' ,
94+
95+ # 4. Delete temporary files
96+ f'{ self .__shell } del /q /f "{ result_output } " "{ result_output_b64 } "'
8397 ]
8498
8599 for cmd in commands :
86100 self .execute_remote (cmd )
87101 time .sleep (0.5 )
88- self .logger .info (f"Waiting { self .__exec_timeout } s for command completely executed." )
102+
103+ self .logger .info (f"Waiting { self .__exec_timeout } s for command to complete." )
89104 time .sleep (self .__exec_timeout )
90105
91106 self .queryRegistry (keyName )
92107
93108 def queryRegistry (self , keyName ):
94109 try :
95- self .logger .debug (f"Querying registry key: HKLM\\ { self .__registry_Path } " )
110+ # Spawn an instance of StdRegProv to access the registry
111+ self .logger .debug (f"Retrieving output from: HKLM\\ { self .__registry_Path } " )
96112 descriptor , _ = self .__iWbemServices .GetObject ("StdRegProv" )
97113 descriptor = descriptor .SpawnInstance ()
98- retVal = descriptor .GetStringValue (0x80000002 , self .__registry_Path , keyName )
99- self .__outputBuffer = base64 .b64decode (retVal .sValue ).decode (self .__codec , errors = "replace" ).rstrip ("\r \n " )
114+
115+ # Get the number of chunks stored in the registry
116+ num_chunks = descriptor .GetDWORDValue (0x80000002 , self .__registry_Path , keyName ).uValue
117+ self .logger .debug (f"Number of chunks: { num_chunks } " )
118+
119+ # Retrieve each chunk and decode the base64 content
120+ outputBuffer_b64 = ""
121+ for i in range (num_chunks ):
122+ chunk_name = f"{ keyName } _chunk_{ i } "
123+ self .logger .debug (f"Retrieving chunk: { chunk_name } " )
124+ outputBuffer_b64 += descriptor .GetStringValue (0x80000002 , self .__registry_Path , chunk_name ).sValue
125+ self .__outputBuffer = base64 .b64decode (outputBuffer_b64 ).decode (self .__codec , errors = "replace" ).rstrip ("\r \n " )
100126 except Exception :
101127 self .logger .fail ("WMIEXEC: Could not retrieve output file, it may have been detected by AV. Please try increasing the timeout with the '--exec-timeout' option. If it is still failing, try the 'smb' protocol or another exec method" )
102128
103129 try :
104130 self .logger .debug (f"Removing temporary registry path: HKLM\\ { self .__registry_Path } " )
105- retVal = descriptor .DeleteKey (0x80000002 , self .__registry_Path )
131+ descriptor .DeleteKey (0x80000002 , self .__registry_Path )
106132 except Exception as e :
107133 self .logger .debug (f"Target: { self .__target } removing temporary registry path error: { e !s} " )
0 commit comments