o
    �õ±j¸y  ã                   @   sH  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Zd dlZd dlZd dl	Z	d dl
Z
d dlmZ d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< d dl=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZI d dlJmKZKmLZLmMZMmNZNmOZO d dlPmQZQmRZRmSZSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZambZb d dlcmdZdmeZe d dlfmgZg d dlhmiZi G dd„ dƒZjdd„ Zkeldk�r"e
 mekƒ ¡ dS dS )é    )Údivision)Úprint_functionN)Útimegm)Ústrptime)Ú	unhexlify)ÚListÚOptionalÚDictÚAny)Úlogger)ÚCCACHE)ÚKerberosSPN)ÚKerberosCredential)ÚKerberosTarget)ÚAS_REPÚTGS_REPÚETYPE_INFO2ÚAuthorizationDataÚEncTicketPartÚEncASRepPartÚEncTGSRepPartÚAD_IF_RELEVANTÚKDC_REQ_BODYÚAS_REQÚTGS_REQÚPrincipalNameÚRealmÚTicketÚAP_REQÚAuthenticatorÚEncryptedDataÚPA_FOR_USER_ENCÚ	krb5_pvnoÚ
KDCOptionsÚ	APOptionsÚMETHOD_DATAÚ
ETYPE_INFOÚPADATA_TYPEÚPA_PAC_REQUESTÚPA_ENC_TS_ENCÚChecksumÚ	CKSUMTYPE)ÚApplicationTagNumbersÚPreAuthenticationDataTypesÚEncryptionTypeÚPrincipalNameTypeÚProtocolVersionNumberÚTicketFlagsÚChecksumTypesÚAuthorizationDataTypeÚKERB_NON_KERB_CKSUM_SALTÚ	NAME_TYPEÚMESSAGE_TYPEÚ
PaDataType)ÚKeyÚ_enctype_tableÚ_checksum_tableÚEnctypeÚ_HMACMD5)ÚKERB_SID_AND_ATTRIBUTESÚPAC_SIGNATURE_DATAÚPAC_INFO_BUFFERÚPAC_LOGON_INFOÚPAC_CLIENT_INFO_TYPEÚPAC_SERVER_CHECKSUMÚPAC_PRIVSVR_CHECKSUMÚPACTYPEÚPKERB_SID_AND_ATTRIBUTES_ARRAYÚVALIDATION_INFOÚPAC_CLIENT_INFOÚKERB_VALIDATION_INFOÚUPN_DNS_INFO_FULLÚPAC_REQUESTOR_INFOÚPAC_UPN_DNS_INFOÚPAC_ATTRIBUTES_INFOÚPAC_REQUESTORÚPAC_ATTRIBUTE_INFO)ÚKerberosTimeÚ	Principal)ÚAIOKerberosClientSocket)ÚAIOKerberosClientc                   @   sª   e Zd Zdededefdd„Zedd„ ƒZedd	„ ƒZed
d„ ƒZdd„ Z	dd„ Z
dd„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$S )%ÚTICKETERÚtargetÚpasswordÚdomainc                 C   sŽ   || _ || _|| _|| _d | _d | _|jr>|j d¡}|d | _t	|ƒdkr*|d n|d | _
|jd ur<|  |j¡ d S d S d| _| j| _
d S )Nú/r   é   Úkrbtgt)Ú_TICKETER__passwordÚ_TICKETER__targetÚ_TICKETER__domainÚ_TICKETER__optionsÚ_TICKETER__tgtÚ_TICKETER__tgt_session_keyÚspnÚsplitÚ_TICKETER__serviceÚlenÚ_TICKETER__serverÚkeytabÚloadKeysFromKeytab)ÚselfrT   rU   rV   ÚoptionsÚ	spn_parts© rj   úŠ/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/minikerberos/tickettest.pyÚ__init__`   s   

ÿzTICKETER.__init__c                 C   s   | d9 } | d7 } | S )Ni€–˜ l     }*{Gírj   )Útrj   rj   rk   ÚgetFileTimes   s   zTICKETER.getFileTimec                 C   s   | d d d |  S ©Né   é   rj   ©Údata_lengthrj   rj   rk   ÚgetPadLengthy   s   zTICKETER.getPadLengthc                 C   s   | d d d S ro   rj   rr   rj   rj   rk   ÚgetBlockLength}   s   zTICKETER.getBlockLengthc                 C   s   t  d¡ d S )Nz3Keytab loading not yet implemented for minikerberos)ÚloggingÚwarning)rg   Úfilenamerj   rj   rk   rf   �   s   
zTICKETER.loadKeysFromKeytabc                 C   sô  t ƒ }ttj tjj¡ ¡ ƒ}|  |¡}|d@ |d d< |d? |d d< d|d d< d|d d< d|d d< d|d d< |d@ |d	 d< |d? |d	 d< d
|d d< d
|d d< d|d d< d|d d< | j|d< d|d< d|d< d|d< d|d< d|d< d|d< d
|d< t	| j
jƒ|d< | j
j d¡}t|ƒd
krŸd|d< nt	|d
 ƒ|d< t|ƒ|d< |D ]}q¯d
|d< d|d< d|d< | j ¡ |d < d!|d"< d
|d#< d
|d$ d< d
|d$ d< d
|d% d< d
|d% d< d
|d&< d
|d'< d
|d(< tƒ }||d)< |S )*Nl   ÿÿ Ú	LogonTimeÚdwLowDateTimeé    ÚdwHighDateTimeÚ
LogoffTimeiÿÿÿÚKickOffTimeÚPasswordLastSetr   ÚPasswordCanChangeÚPasswordMustChangeÚEffectiveNameÚ ÚFullNameÚLogonScriptÚProfilePathÚHomeDirectoryÚHomeDirectoryDriveiô  Ú
LogonCountÚBadPasswordCountÚUserIdú,i  ÚPrimaryGroupIdÚ
GroupCountÚ	UserFlagsó                   ÚUserSessionKeyÚLogonServerÚLogonDomainNames           ÚLMKeyÚSubAuthStatusÚLastSuccessfulILogonÚLastFailedILogonÚFailedILogonCountÚ	Reserved3ÚResourceGroupCountÚData)rH   r   ÚdatetimeÚnowÚtimezoneÚutcÚ	timetuplern   r[   Úintr]   Úuser_idÚgroupsra   rc   r\   ÚupperrF   )rg   ÚkerbdataÚaTimeÚunixTimer£   ÚgroupÚvalidationInforj   rj   rk   ÚcreateBasicValidationInfo‡   s^   


z"TICKETER.createBasicValidationInfoc                 C   s@  |   ¡ }i }| ¡ | ¡  |t< tƒ }tƒ }|d d d tjjkr7tj	j|d< tj	j|d< d|d< d|d< n)d|d< d|d< t
| jjƒdkrTtjj|d< tjj|d< ntjj|d< tjj|d< | ¡ |t< | ¡ |t< tƒ }| j d	¡|d
< t
|d
 ƒ|d< | ¡ |t< | jjrŽ|  |¡ | jjdu rž|  |¡ |  |¡ |S )NÚticketúenc-partÚetypeÚSignatureTyper�   Ú	Signatures               é@   zutf-16leÚNameÚ
NameLengthF)rª   ÚgetDataÚgetDataReferentsr@   r>   r.   ÚRC4_HMACÚvaluer2   ÚHMAC_MD5rc   r]   ÚaesKeyÚHMAC_SHA1_96_AES256ÚHMAC_SHA1_96_AES128rB   rC   rG   r[   ÚencoderA   Ú	extra_pacÚcreateUpnDnsPacÚold_pacÚcreateAttributesInfoPacÚcreateRequestorInfoPac)rg   ÚkdcRepr©   ÚpacInfosÚsrvCheckSumÚprivCheckSumÚ
clientInforj   rj   rk   ÚcreateBasicPacá   s:   



zTICKETER.createBasicPacc                 C   sˆ  t ƒ }d|  t|ƒ¡ }| j ¡ › d| j ¡ › � d¡}t|ƒ|d< t|ƒt|ƒ |d< |d |d  }|  |¡}|d| 7 }| j ¡  d¡}t|ƒ|d< || |d< |d |d  }|  |¡}|d| 7 }d|d	< | j d¡}t|ƒ|d
< || |d< |d |d
  }|  |¡}|d| 7 }d}	t|	ƒ|d< || |d< |d |d  }|  |¡}|	d|  }
|| | |
 }| ¡ | | |t	< d S )Nó    ú@z	utf-16-leÚ	UpnLengthÚ	UpnOffsetÚDnsDomainNameLengthÚDnsDomainNameOffseté   ÚFlagsÚSamNameLengthÚSamNameOffsets                                    Ú	SidLengthÚ	SidOffset)
rI   rt   rc   r[   Úlowerr\   r»   r¤   r³   rK   )rg   rÂ   Ú
upnDnsInfoÚPAC_padÚupn_dataÚ	total_lenÚpadÚdns_nameÚsamNameÚuser_sid_dataÚ	user_dataÚpost_pac_datarj   rj   rk   r½   	  s:    



zTICKETER.createUpnDnsPacc                 C   s&   t ƒ }d|d< d|d< | ¡ | t< d S )NrÍ   ÚFlagsLengthrX   rÎ   )rN   r³   rL   )rÂ   ÚpacAttributesrj   rj   rk   r¿   2  s   z TICKETER.createAttributesInfoPacc                 C   s   t ƒ }| ¡ |t< d S ©N)rM   r³   rJ   )rg   rÂ   ÚpacRequestorrj   rj   rk   rÀ   :  s   zTICKETER.createRequestorInfoPacc                 C   s   | j jdu r| j| jkrt d¡ nt d¡ t d¡ dS t d¡ | j| jkr3tƒ }tjj	|d< n	t
ƒ }tj
j	|d< d|d	< | j jd u rG	 | j ¡ |d
< ttjj	| jgdœƒ|d< tƒ |d< tjj	|d d< | j ¡ |d d< t| j| jkr|tjj	ntjj	| j| j| jkrŒ| j ¡ n| jgdœƒ|d d< tƒ |d d< d|d d d< tƒ |d< | j jd u rßt| j jƒdkrÌtjj	|d d d< tjj	|d d< n%tjj	|d d d< tjj	|d d< ntjj	|d d d< tjj	|d d< d|d d< |  |¡}||fS )NTz/Requesting TGT to target domain to use as basisz3Requesting TGT/TGS to target domain to use as basisz:Request functionality not yet implemented for minikerberos)NNz,Creating basic skeleton ticket and PAC Infoszmsg-typeé   ÚpvnoÚcrealm©z	name-typezname-stringÚcnamer«   ztkt-vnoÚrealmÚsnamer¬   rÍ   Úkvnor°   r­   )r]   Úrequestr\   rd   rv   ÚinfoÚerrorr   r,   r¶   r   Únthashr¤   r   r5   Ú	PRINCIPALr[   r   r0   rã   ÚSRV_INSTrb   r    rc   r¸   r.   ÚAES256_CTS_HMAC_SHA1_96ÚAES128_CTS_HMAC_SHA1_96rµ   rÆ   )rg   rÁ   rÂ   rj   rj   rk   ÚcreateBasicTicketB  sR   


þ
 þ

zTICKETER.createBasicTicketc                 Ã   s   �t  d¡ dS )Nz?S4U2Self+U2U functionality not yet implemented for minikerberos)NNNN)rv   rì   )rg   rj   rj   rk   ÚgetKerberosS4U2SelfU2U}  s   €
zTICKETER.getKerberosS4U2SelfU2Uc                 C   s¢  t  d| j| jf ¡ tj tjj¡tjt	| j
jƒd� }| j
jr(t  d¡ dS tƒ }g }|d d d dd	œ|d
< |d
 d tjjkrUd dd„ tdƒD ƒ¡|d
 d< n+|d
 d tjjkrpd dd„ tdƒD ƒ¡|d
 d< nd dd„ tdƒD ƒ¡|d
 d< | j ¡ |d< ttjj| jgdœƒ|d< dddœ|d< tj tjj¡}|jdd�|d< |jdd�|d< ||d< ||d< g |d< t  d ¡ t  d!¡ t  d"¡ | j| jkrØtƒ }ntƒ }|d
 |d
< g |d#< d$|d%< ||d&< t|d ƒ|d< t|d ƒ|d< t|d ƒ|d< t|d ƒ|d< | j ¡ |d'< t| j| jk�r tjjntjj| j| j| jk�r1| j ¡ n| jgdœƒ|d(< | j| jk�rGt  d)¡ nt  d*¡ |||fS )+NzCustomizing ticket for %s/%s)ÚhourszRSapphire ticket (impersonation) functionality not yet implemented for minikerberos)NNNr«   r¬   r­   ó    )ÚkeytypeÚkeyvalueÚkeyrö   rƒ   c                 S   ó   g | ]}t  tj¡‘qS rj   ©ÚrandomÚchoiceÚstringÚascii_letters©Ú.0Ú_rj   rj   rk   Ú
<listcomp>ž  ó    z,TICKETER.customizeTicket.<locals>.<listcomp>é   r÷   c                 S   rù   rj   rú   rÿ   rj   rj   rk   r     r  r{   c                 S   rù   rj   rú   rÿ   rj   rj   rk   r  ¢  r  rä   rå   ræ   r   )ztr-typeÚcontentsÚ	transited)ÚmicrosecondÚauthtimeÚ	starttimeÚendtimez
renew-tillzauthorization-dataz	PAC_LOGON_INFOz	PAC_CLIENT_INFO_TYPEz	EncTicketPartzlast-reqiÍ[Únoncezkey-expirationÚsrealmrè   z	EncAsRepPartz	EncTGSRepPart) rv   rë   r\   r[   rœ   r�   rž   rŸ   Ú	timedeltar¡   r]   ÚdurationÚimpersonaterì   r   r.   rñ   r¶   ÚjoinÚrangerð   r¤   r   r5   rî   Úreplacerd   r   r   Ústrrï   rb   )rg   rÁ   rÂ   ÚticketDurationÚencTicketPartÚflagsr�   Ú
encRepPartrj   rj   rk   ÚcustomizeTicket‚  sh   $


þ"" þ
þ


"þ

zTICKETER.customizeTicketc                 C   s   t  d¡ t  d¡ dS )NzSigning/Encrypting final ticketzLPAC signing and ticket encryption not yet fully implemented for minikerberos)rõ   NN)rv   rë   rì   )rg   rÁ   ÚencASorTGSRepPartr  rÂ   rj   rj   rk   ÚsignEncryptTicketØ  s   

	zTICKETER.signEncryptTicketc                 C   s0   t  d| j dd¡d  ¡ tƒ }t  d¡ d S )NzSaving ticket in %srW   Ú.z.ccachez8CCACHE saving not yet fully implemented for minikerberos)rv   rë   r[   r  r   )rg   r«   Ú
sessionKeyÚccacherj   rj   rk   Ú
saveTicketç  s   zTICKETER.saveTicketc                 Ã   sf   �|   ¡ \}}|d ur-|  ||¡\}}}|d ur/|  ||||¡\}}}|r1|  ||¡ d S d S d S d S rà   )rò   r  r  r  )rg   r«   ÚadIfRelevantr  r  rÂ   Úcipherr  rj   rj   rk   Úrunõ  s   €ûzTICKETER.runN)Ú__name__Ú
__module__Ú__qualname__r  rl   Ústaticmethodrn   rt   ru   rf   rª   rÆ   r½   r¿   rÀ   rò   ró   r  r  r  r!  rj   rj   rj   rk   rS   _   s*    


Z()
;VrS   c               
   Ã   sî  �t dƒ tjddd�} | jdddd� | jd	dd
d� | jddddd� | jddddd� | jddddd� | jddddd� | jdddd� | jdddd� | jddddd� | jd dd!d"d� | jd#dd$d� | jd%dd&d� | jd'dd(d� | jd)dd*d+d� | jd,dd-d� | jd.dd/d� |  d0¡}|jd1dd2d� |jd3dd4d� |jd5dd6d7d� |jd8dd9d:d� | jd;dd<d� ttjƒd=krþ|  ¡  t d>ƒ t d?ƒ t d@ƒ t dAƒ t dBƒ t dCƒ t dDƒ t dEƒ t dFƒ t dGƒ t dHƒ t 	d=¡ |  
¡ }|j�rtjtjdI� ntjtjdI� |jd u �r%t dJ¡ t 	d=¡ |jd u �rA|jd u �rA|jd u �rAt dK¡ t 	d=¡ |jd u�r]|jd u�r]|jdu �r]t dL¡ t 	d=¡ |jdu �rs|jd u �rst dM¡ t 	d=¡ |jdu �r�|jd u �r�|jd u �r�dNdOlm} |dPƒ}n|j}|j�r8g }|jdf|j�p£|jdQf|jdf|jd1f|d3f|jdf|jd fg}|D ]\}}|�sÈ| |¡ �q¼|�rÝt dRdS |¡› �¡ t 	d=¡ |j �sï|j�sït dT¡ t 	d=¡ g }	|j!�rú|	 d%¡ |j"d u�r|	 d#¡ |j#d u�r|	 d¡ |j$d u�r|	 d)¡ |	�r)t dUdS |	¡› �¡ |j �r8|jd u�r8t dV¡ zt%|j&||j|ƒ}
|
 '¡ I d H  W d S  t(�yv } zt )¡ j*tjk�redNd l+}| ,¡  t t-|ƒƒ W Y d }~d S d }~ww )WNzMinikerberos Ticket GeneratorTz>Creates a Kerberos golden/silver tickets based on user options)Úadd_helpÚdescriptionrT   Ústorez%username for the newly created ticket)ÚactionÚhelpz-spnz}SPN (service/server) of the target service the silver ticket will be generated for. if omitted, golden ticket will be createdz-requestÚ
store_trueFzlRequests ticket to domain and clones it changing only the supplied information. It requires specifying -user)r)  Údefaultr*  z-domainz2the fully qualified domain name (e.g. contoso.com))r)  Úrequiredr*  z-domain-sidz@Domain SID of the target domain the ticker will be generated forz-aesKeyzhex keyz5AES key used for signing the ticket (128 or 256 bits))r)  Úmetavarr*  z-nthashz#NT hash used for signing the ticketz-keytabz7Read keys for SPN from keytab file (silver ticket only)z-groupsz513, 512, 520, 518, 519zVcomma separated list of groups user will belong to (default = 513, 512, 520, 518, 519)z-user-idÚ500zCuser id for the user the ticket will be created for (default = 500)z
-extra-sidzHComma separated list of ExtraSids to be included inside the ticket's PACz
-extra-pacz-Populate your ticket with extra PAC (UPN_DNS)z-old-pacz^Use the old PAC structure to create your ticket (exclude PAC_ATTRIBUTES_INFO and PAC_REQUESTORz	-durationÚ87600z=Amount of hours till the ticket expires (default = 24*365*10)z-tsz&Adds timestamp to every logging outputz-debugzTurn DEBUG output ONÚauthenticationz-userzZdomain/username to be used if -request is chosen (it can be different from domain/usernamez	-passwordzpassword for domain/usernamez-hasheszLMHASH:NTHASHz$NTLM hashes, format is LMHASH:NTHASHz-dc-ipz
ip addresszoIP Address of the domain controller. If ommited it use the domain part (FQDN) specified in the target parameterz-impersonatez¦Sapphire ticket. target username that will be impersonated (through S4U2Self+U2U) for querying the ST and extracting the PAC, which will be included in the new ticketrX   z
Examples: zp	./ticketer.py -nthash <krbtgt/service nthash> -domain-sid <your domain SID> -domain <your domain FQDN> baduser
zd	will create and save a golden ticket for user 'baduser' that will be all encrypted/signed used RC4.z^	If you specify -aesKey instead of -ntHash everything will be encrypted using AES128 or AES256zc	(depending on the key specified). No traffic is generated against the KDC. Ticket will be saved asz	baduser.ccache.
zÛ	./ticketer.py -nthash <krbtgt/service nthash> -aesKey <krbtgt/service AES> -domain-sid <your domain SID> -domain <your domain FQDN> -request -user <a valid domain user> -password <valid domain user's password> baduser
z`	will first authenticate against the KDC (using -user/-password) and get a TGT that will be usedzc	as template for customization. Whatever encryption algorithms used on that ticket will be honored,zf	hence you might need to specify both -nthash and -aesKey data. Ticket will be generated for 'baduser'z	and saved as baduser.ccache)ÚlevelzDomain should be specified!z7You have to specify either aesKey, or nthash, or keytabzMYou cannot specify both -aesKey and -nthash w/o using -request. Pick only onez.-request parameter needs -user to be specifiedr   )Úgetpassz	Password:z-aesKey or -nthashz+missing parameters to do sapphire ticket : z, z=missing parameter -user-id. Must be set if not doing -old-pacz7doing sapphire ticket, ignoring following parameters : zWparameter -user-id will be ignored when specifying -old-pac in a sapphire ticket attack).ÚprintÚargparseÚArgumentParserÚadd_argumentÚadd_argument_grouprc   ÚsysÚargvÚ
print_helpÚexitÚ
parse_argsÚdebugrv   ÚbasicConfigÚDEBUGÚINFOrV   Úcriticalr¸   rí   re   rì   rê   ÚuserÚhashesrU   r3  r  Ú
domain_sidr¢   Úappendr  r¾   r¼   Ú	extra_sidr£   r  rS   rT   r!  Ú	ExceptionÚ	getLoggerr2  Ú	tracebackÚ	print_excr  )Úparserr¨   rh   r3  rU   Úmissing_paramsÚrequired_paramsÚparamÚ
param_nameÚignored_paramsÚexecuterÚerJ  rj   rj   rk   Úmainÿ  sÌ   €



$

$



$
ù

€







€ürT  Ú__main__)nÚ
__future__r   r   r5  rœ   rv   rû   rý   Ústructr9  ÚasyncioÚcalendarr   Útimer   Úbinasciir   Útypingr   r   r	   r
   Úminikerberosr   Úminikerberos.common.ccacher   Úminikerberos.common.spnr   Úminikerberos.common.credsr   Úminikerberos.common.targetr   Ú"minikerberos.protocol.asn1_structsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   Úminikerberos.protocol.constantsr,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   Ú minikerberos.protocol.encryptionr8   r9   r:   r;   r<   Úminikerberos.protocol.pacr=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   Ú minikerberos.protocol.structuresrO   rP   Ú$minikerberos.network.aioclientsocketrQ   Úminikerberos.aioclientrR   rS   rT  r"  r!  rj   rj   rj   rk   Ú<module>   sF   0x8P   # 
ÿ