@@ -978,6 +978,32 @@ def enumerate_sessions_info(self, sessions):
978978 except SessionError :
979979 self .logger .fail ("RDP is probably not enabled, cannot list remote IPv4 addresses." )
980980
981+ @requires_admin
982+ def taskkill (self ):
983+ with TSTS .LegacyAPI (self .conn , self .host , self .kerberos ) as legacy :
984+ handle = legacy .hRpcWinStationOpenServer ()
985+ if self .args .taskkill .isdigit ():
986+ pidList = [int (self .args .taskkill )]
987+ else :
988+ res = legacy .hRpcWinStationGetAllProcesses (handle )
989+ if not res :
990+ self .logger .error ("Could not get process list" )
991+ return
992+
993+ pidList = [i ["UniqueProcessId" ] for i in res if i ["ImageName" ].lower () == self .args .taskkill .lower ()]
994+ if not pidList :
995+ self .logger .fail (f"Could not find process named { self .args .taskkill } " )
996+ return
997+
998+ for pid in pidList :
999+ try :
1000+ if legacy .hRpcWinStationTerminateProcess (handle , pid )["ErrorCode" ]:
1001+ self .logger .highlight (f"Terminated PID { pid } ({ self .args .taskkill } )" )
1002+ else :
1003+ self .logger .fail (f"Failed terminating PID { pid } " )
1004+ except Exception as e :
1005+ self .logger .exception (f"Error terminating PID { pid } : { e } " )
1006+
9811007 @requires_admin
9821008 def qwinsta (self ):
9831009 desktop_states = {
@@ -1077,6 +1103,16 @@ def qwinsta(self):
10771103
10781104 @requires_admin
10791105 def tasklist (self ):
1106+ # Formats a row to be printed on screen
1107+ def format_row (procInfo ):
1108+ return template .format (
1109+ procInfo ["ImageName" ],
1110+ procInfo ["UniqueProcessId" ],
1111+ procInfo ["SessionId" ],
1112+ procInfo ["pSid" ],
1113+ f"{ procInfo ['WorkingSetSize' ] // 1000 :,} K" ,
1114+ )
1115+
10801116 try :
10811117 with TSTS .LegacyAPI (self .conn , self .host , self .kerberos ) as legacy :
10821118 try :
@@ -1091,18 +1127,27 @@ def tasklist(self):
10911127 self .logger .success ("Enumerated processes" )
10921128 maxImageNameLen = max (len (i ["ImageName" ]) for i in res )
10931129 maxSidLen = max (len (i ["pSid" ]) for i in res )
1094- template = "{ : <%d} { : <8} { : <11} { : <%d} { : >12}" % ( maxImageNameLen , maxSidLen ) # noqa: UP031
1130+ template = f"{{ : <{ maxImageNameLen } }} {{ : <8}} {{ : <11}} {{ : <{ maxSidLen } }} {{ : >12}}"
10951131 self .logger .highlight (template .format ("Image Name" , "PID" , "Session#" , "SID" , "Mem Usage" ))
10961132 self .logger .highlight (template .replace (": " , ":=" ).format ("" , "" , "" , "" , "" ))
1133+ found_task = False
1134+
1135+ # For each process on the remote host
10971136 for procInfo in res :
1098- row = template .format (
1099- procInfo ["ImageName" ],
1100- procInfo ["UniqueProcessId" ],
1101- procInfo ["SessionId" ],
1102- procInfo ["pSid" ],
1103- "{:,} K" .format (procInfo ["WorkingSetSize" ] // 1000 ),
1104- )
1105- self .logger .highlight (row )
1137+ # If args.tasklist is not True then a process name was supplied
1138+ if self .args .tasklist is not True :
1139+ # So we look for it and print its information if found
1140+ if self .args .tasklist .lower () in procInfo ["ImageName" ].lower ():
1141+ found_task = True
1142+ self .logger .highlight (format_row (procInfo ))
1143+ # Else, no process was supplied, we print the entire list of remote processes
1144+ else :
1145+ self .logger .highlight (format_row (procInfo ))
1146+
1147+ # If a process was suppliad to args.tasklist and it was not found, we print a fail message
1148+ if self .args .tasklist is not True and not found_task :
1149+ self .logger .fail (f"Didn't find process { self .args .tasklist } " )
1150+
11061151 except SessionError :
11071152 self .logger .fail ("Cannot list remote tasks, RDP is probably disabled." )
11081153
@@ -1214,16 +1259,20 @@ def shares(self):
12141259 error = get_error_string (e )
12151260 self .logger .debug (f"Error adding share: { error } " )
12161261
1262+ if self .args .filter_shares :
1263+ self .logger .display ("[REMOVED] Use the --shares read,write options instead." )
1264+
12171265 self .logger .display ("Enumerated shares" )
12181266 self .logger .highlight (f"{ 'Share' :<15} { 'Permissions' :<15} { 'Remark' } " )
12191267 self .logger .highlight (f"{ '-----' :<15} { '-----------' :<15} { '------' } " )
1268+
12201269 for share in permissions :
12211270 name = share ["name" ]
12221271 remark = share ["remark" ]
1223- perms = share ["access" ]
1224- if self .args .filter_shares and not any ( x in perms for x in self . args . filter_shares ):
1272+ perms = "," . join ( share ["access" ])
1273+ if self .args .shares and self . args . shares . lower () not in perms . lower ( ):
12251274 continue
1226- self .logger .highlight (f"{ name :<15} { ',' . join ( perms ) :<15} { remark } " )
1275+ self .logger .highlight (f"{ name :<15} { perms :<15} { remark } " )
12271276 return permissions
12281277
12291278 def dir (self ):
@@ -1503,16 +1552,16 @@ def rid_brute(self, max_rid=None):
15031552 max_rid = int (self .args .rid_brute )
15041553
15051554 KNOWN_PROTOCOLS = {
1506- 135 : {"bindstr" : rf"ncacn_ip_tcp:{ self .host } " },
1507- 139 : {"bindstr" : rf"ncacn_np:{ self .host } [\pipe\lsarpc]" },
1508- 445 : {"bindstr" : rf"ncacn_np:{ self .host } [\pipe\lsarpc]" },
1555+ 135 : {"bindstr" : rf"ncacn_ip_tcp:{ self .remoteName } " },
1556+ 139 : {"bindstr" : rf"ncacn_np:{ self .remoteName } [\pipe\lsarpc]" },
1557+ 445 : {"bindstr" : rf"ncacn_np:{ self .remoteName } [\pipe\lsarpc]" },
15091558 }
15101559
15111560 try :
15121561 string_binding = KNOWN_PROTOCOLS [self .port ]["bindstr" ]
15131562 self .logger .debug (f"StringBinding { string_binding } " )
15141563 rpc_transport = transport .DCERPCTransportFactory (string_binding )
1515- rpc_transport .setRemoteHost (self .host )
1564+ rpc_transport .setRemoteHost (self .remoteName )
15161565
15171566 if hasattr (rpc_transport , "set_credentials" ):
15181567 # This method exists only for selected protocol sequences.
0 commit comments