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�rüe+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�rže IdS¡ e 7dP¡ e9jJ�r¦e9jJZKneEZKe9jLdu �s´e9jMdu�r·de9_Ne9jOdu�rÀde9_Pze)eFeGeEeKe9ƒZQeQ R¡  W dS  eS�yû ZT ze U¡ jVejWk�réd dlXZXeX Y¡  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r•t& '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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 ¡ 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 �rÇt 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$%siôÿÿÿz,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 rŒt 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rÈt d¡ |	 ¡ }n‚ W Y d }	~	nd }	~	ww g }
t dt|ƒ ¡ |D �](}t |tj!ƒduríqád}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�r«t"|d d ƒd"k�r—d#}�qt"t& '|  (t#t"|d d ƒƒ¡¡ƒ}�qt"|d ƒd%k�rÆ|d D ]}| )| *¡  +d&¡¡ �q¸�q|du �rít#|ƒt,@ �rÜt d'| ¡ n|D ]}|
 )||||||g¡ �qÞW qá t-�y
 }	 zt .d(t"|	ƒ ¡ W Y d }	~	qád }	~	ww t|
ƒdk�rÈ| j/|
g d)¢d*� t0d+ƒ | j1du �s1| jd u�s1| jd u�rÄt2d,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_truez�Removes the (servicePrincipalName=*) filter from the LDAP query for added stealth. May cause huge memory consumption / errors on large domains.z-machine-onlyFzÏQueries 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-kzÁUse 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 addressz—IP 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‰   zˆYou 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ª       


ÿÿ
ÿ



(


€ü¦