@@ -161,6 +161,7 @@ def process_target(
161161 username = auth .username
162162 password = auth .password
163163 hashes = auth .hashes
164+ aes_key = auth .aes_key
164165 kerberos = auth .kerberos
165166 dc_ip = auth .dc_ip
166167 timeout = auth .timeout
@@ -267,7 +268,7 @@ def process_target(
267268 else :
268269 # Standard mode: Direct SMB connection
269270 smb = smb_connect (
270- target , domain , username , hashes or password , kerberos = kerberos , dc_ip = dc_ip , timeout = timeout
271+ target , domain , username , hashes or password , kerberos = kerberos , dc_ip = dc_ip , timeout = timeout , aes_key = aes_key
271272 )
272273
273274 good (f"{ target } : Connected via SMB" )
@@ -421,48 +422,55 @@ def process_target(
421422
422423 # Credential validation via Task Scheduler RPC (if requested and not in OPSEC mode)
423424 if validate_creds and not opsec and password_task_paths :
424- info (f"{ target } : Querying Task Scheduler RPC for credential validation..." )
425- try :
426- # Parse hashes for RPC auth
427- lm_hash = ""
428- nt_hash = ""
429- if hashes :
430- hash_parts = hashes .split (":" )
431- if len (hash_parts ) == 2 :
432- lm_hash , nt_hash = hash_parts
433- elif len (hash_parts ) == 1 and len (hash_parts [0 ]) == 32 :
434- nt_hash = hash_parts [0 ]
435-
436- rpc_client = TaskSchedulerRPC (
437- target = target ,
438- domain = domain ,
439- username = username ,
440- password = password or "" ,
441- lm_hash = lm_hash ,
442- nt_hash = nt_hash ,
443- )
425+ # Skip if using ccache-only Kerberos (no credentials to use for RPC)
426+ if kerberos and not password and not hashes and not aes_key :
427+ warn (f"{ target } : Credential validation not supported with ccache-only Kerberos (use password, --hashes, or --aes-key)" )
428+ else :
429+ info (f"{ target } : Querying Task Scheduler RPC for credential validation..." )
430+ try :
431+ # Parse hashes for RPC auth
432+ lm_hash = ""
433+ nt_hash = ""
434+ if hashes :
435+ hash_parts = hashes .split (":" )
436+ if len (hash_parts ) == 2 :
437+ lm_hash , nt_hash = hash_parts
438+ elif len (hash_parts ) == 1 and len (hash_parts [0 ]) == 32 :
439+ nt_hash = hash_parts [0 ]
440+
441+ rpc_client = TaskSchedulerRPC (
442+ target = target ,
443+ domain = domain ,
444+ username = username ,
445+ password = password or "" ,
446+ lm_hash = lm_hash ,
447+ nt_hash = nt_hash ,
448+ aes_key = aes_key or "" ,
449+ kerberos = kerberos ,
450+ dc_ip = dc_ip or "" ,
451+ )
444452
445- if rpc_client .connect ():
446- # Validate only the tasks we know have Password logon type
447- cred_validation_results = rpc_client .validate_specific_tasks (password_task_paths )
448- rpc_client .disconnect ()
449-
450- if cred_validation_results :
451- valid_count = sum (1 for r in cred_validation_results .values () if r .password_valid )
452- invalid_count = sum (1 for r in cred_validation_results .values ()
453- if r .credential_status == CredentialStatus .INVALID )
454- unknown_count = sum (1 for r in cred_validation_results .values ()
455- if r .credential_status == CredentialStatus .UNKNOWN )
456- good (f"{ target } : Validated { len (cred_validation_results )} password tasks "
457- f"({ valid_count } valid, { invalid_count } invalid, { unknown_count } unknown)" )
453+ if rpc_client .connect ():
454+ # Validate only the tasks we know have Password logon type
455+ cred_validation_results = rpc_client .validate_specific_tasks (password_task_paths )
456+ rpc_client .disconnect ()
457+
458+ if cred_validation_results :
459+ valid_count = sum (1 for r in cred_validation_results .values () if r .password_valid )
460+ invalid_count = sum (1 for r in cred_validation_results .values ()
461+ if r .credential_status == CredentialStatus .INVALID )
462+ unknown_count = sum (1 for r in cred_validation_results .values ()
463+ if r .credential_status == CredentialStatus .UNKNOWN )
464+ good (f"{ target } : Validated { len (cred_validation_results )} password tasks "
465+ f"({ valid_count } valid, { invalid_count } invalid, { unknown_count } unknown)" )
466+ else :
467+ info (f"{ target } : No run info available for password tasks" )
458468 else :
459- info (f"{ target } : No run info available for password tasks" )
460- else :
461- warn (f"{ target } : Failed to connect to Task Scheduler RPC" )
462- except Exception as e :
463- warn (f"{ target } : Credential validation failed: { e } " )
464- if debug :
465- traceback .print_exc ()
469+ warn (f"{ target } : Failed to connect to Task Scheduler RPC" )
470+ except Exception as e :
471+ warn (f"{ target } : Credential validation failed: { e } " )
472+ if debug :
473+ traceback .print_exc ()
466474 elif validate_creds and not password_task_paths :
467475 info (f"{ target } : No password-authenticated tasks found - skipping credential validation" )
468476 elif validate_creds and opsec :
@@ -594,6 +602,7 @@ def process_target(
594602 password = ldap_auth_pass ,
595603 hashes = ldap_auth_hashes ,
596604 kerberos = kerberos ,
605+ aes_key = aes_key ,
597606 attributes = ["pwdLastSet" , "sAMAccountName" ],
598607 )
599608
@@ -634,6 +643,7 @@ def process_target(
634643 auth_password = ldap_auth_pass ,
635644 hashes = ldap_auth_hashes ,
636645 kerberos = kerberos ,
646+ aes_key = aes_key ,
637647 )
638648
639649 if tier0_cache :
0 commit comments