o
    j"~                     @   s  d dl Z d dlZd dlZd dl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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mZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) d dl*m+Z+m,Z, d d	l-m.Z.m/Z/m0Z0m1Z1 d d
l2m3Z3m4Z4m5Z5m6Z6 d dl7m8Z8 d dl9m:Z:m;Z;m<Z<m=Z=m>Z> d dl?m@Z@ d dlAmBZB d dlCmDZD d dlEmFZF d dlGmHZH d dlGmIZI G dd dZJdS )    N)ListDict)hashlib)logger)CCACHE)KerberosClientSocket)METHOD_DATA
ETYPE_INFOETYPE_INFO2PADATA_TYPEPA_PAC_REQUESTPA_ENC_TS_ENCEncryptedData	krb5_pvnoKDC_REQ_BODYAS_REQTGS_REP
KDCOptionsPrincipalNameEncASRepPartEncTGSRepPartr   RealmChecksum	APOptionsAuthenticatorTicketAP_REQTGS_REQ	CKSUMTYPEPA_FOR_USER_ENCPA_PAC_OPTIONSPA_PAC_OPTIONSTypesEncTicketPart)KerberosErrorCodeKerberosError)Key_enctype_table_HMACMD5Enctype)
PaDataTypeEncryptionType	NAME_TYPEMESSAGE_TYPE)AuthenticatorChecksum)PKAuthenticatorAuthPackPA_PK_AS_REPKDCDHKeyInfoPA_PK_AS_REQ)KerberosCredential)KerberosTarget)KerberosSPN)construct_apreq_from_tgs_tgt)cms)corec                   @   sP  e Zd ZdedefddZg ddddddfd	ee d
ede	fddZ
g ddfd
ede	fddZg ddfd
efddZdd Zdd Zddg dddfded
efddZdefddZd.ddZg dejejejejejejejgfd d!Zdg d"ejejejgfd#d$Zejejejgfd%d&Zdd'g dfd(d)Zd*d+ Zd,d- Z dS )/KerbrosClientccredtargetc                 C   sj   || _ || _t| j| _|jd u rt n|j| _d | _d | _d | _d | _	d | _
d | _d | _d | _d | _d S )N)
credentialr;   r   ksocccacher   kerberos_session_keykerberos_TGTkerberos_TGT_encpartkerberos_TGSkerberos_cipherkerberos_cipher_typekerberos_keyserver_saltpkinit_tkey)selfr:   r;    rI   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/minikerberos/client.py__init__   s   
zKerbrosClient.__init__)forwardable	renewable	proxiableNFTkdcoptswith_pacreturnc                 C   s$  t d g }|du r$i }	ttd|	d< tddi |	d< ||	 t d|j  tj	tj
j}
|du r|d u rnt|
jd	d
|
jd }t|j | _|j| _t| jj| jj|| jd| _| j| jd|d }n|}
|}i }ttd|d< t|j|d |d< || i }tt||d< ttjj| jj !dd|d< | jj"# |d< ttjjd| jj"# gd|d< |
tj$dd jd	d
|d< |
tj$dd jd	d
|d< t%&d|d< |jg|d< |d ur|D ]}|| ||< qi }t'|d< t(j)j|d< ||d< t*||d < t+|S )!Nz'Constructing TGT request with auth dataTPA-PAC-REQUESTpadata-typeinclude-pacpadata-valuez$Selecting common encryption type: %sFr   microsecond)patimestamppausec)salt   zENC-TIMESTAMPetypecipherkdc-options/z	name-typezname-stringcnamerealmkrbtgtsnamedaystillrtime   noncer]   pvnomsg-typepadatareq-body),r   debugintr   r   dumpappendnamedatetimenowtimezoneutcr   replacerW   r&   valuerC   rD   r%   enctyper<   get_key_for_enctyperF   rE   encryptr   r   setr   r+   	PRINCIPALusernamesplitdomainupper	timedeltasecretsrandbitsr   r,   
KRB_AS_REQr   r   )rH   supported_encryption_methodrO   enctimestampnewnow
no_preauthkdc_req_body_extrarP   padatas	pa_data_1rv   	timestampenc_timestamp	pa_data_2kdc_req_bodykeykdc_reqrI   rI   rJ   build_asreq_lts.   sP   


 "zKerbrosClient.build_asreq_lts)rL   rM   zrenewable-okc                 C   s  ddl m} |jdkrtdtjtjj}i }tt	||d< t
tjj| jjdd|d< | jj |d	< t
tjjd
| jj gd|d< |tjdd jdd|d< |tjdd jdd|d< td|d< |jg|d< t|}t|  }i }	|j|	d< |jdd|	d< td|	d< ||	d< i }
| jjj|
d< | jjj|
d< d|
d< i }d|d< | |
|d< i }|!||d< | jj" |d< i }t#|	|d< |$||d< | jjj%|d < t&|}| jj'| d!d"}t( }||d#< g }|d!u ri }t)t*d$|d%< t+d&d!i |d'< |,| i }t-j.j|d%< | |d'< |,| i }d(|d)< d*|d+< ||d,< ||d-< t/|S ).Nr   )keys   z5RC4 encryption is not supported for certificate auth!r_   r`   ra   rb   rc   rd   re   r[   rf   rV   rh   ri   rj   rk   r]   cusecctime
paChecksumpgqz1.2.840.10046.2.1	algorithm
parameters
public_keypkAuthenticatorclientPublicValueclientDHNonceT)wrap_signedsignedAuthPackrR   rS   rT   rU      rl   
   rm   rn   ro   )0
asn1cryptor   rz   	Exceptionru   rv   rw   rx   r   r~   r   r+   r   r<   r   r   r   r   SRV_INSTr   ry   r   r   r   r   sha1rr   digestrW   dhparamsr   r   DomainParametersPublicKeyAlgorithmget_public_keyr.   PublicKeyInfodh_noncer/   sign_authpackr2   rq   r   r   rs   r)   	PK_AS_REQr   )rH   r   rO   rP   r   rv   kdc_req_body_datar   checksumauthenticatordppkaspkiauthpacksigned_authpackpayloadr   	pa_data_0r   asreqrI   rI   rJ   build_asreq_pkinitb   sl   
 "



z KerbrosClient.build_asreq_pkinitc                 C   s`   | j jd ur| j|||d}n| j|||d}td | j| }|j	dkr.t
|d|S )N)rP   zSending TGT request to server	KRB_ERRORzPreauth failed!)r<   certificater   r   r   rp   r=   sendrecvrr   rt   r$   )rH   r   rO   rP   reqreprI   rI   rJ   
do_preauth   s   


zKerbrosClient.do_preauthc              
   C   s   zA| j d u r
td| j | jj| jj| jj\}}}|d ur!||| _|d | _t	|d |d | _
t|d  | _|d | _W dS  tyW } z
d |fW  Y d }~S d }~ww )NNo CCACHE file foundenc-partkeytypekeyvalue)TN)r>   r   get_tgtr<   r   r   ccache_spn_strict_checkr@   rA   r%   r?   r&   rC   rD   )rH   tgt	keystructerrerI   rI   rJ   tgt_from_ccache   s    
"

zKerbrosClient.tgt_from_ccachec           	      C   s   t  }t|d jD ]K}t|d }|tjks|tjkrW|tjkr+t|d }n|tjkr7t|d }|jD ]}|d |t|d < t	
dt|d j|d f  q:q| j|}||vrftd|| }|d urr| }|| _|S )Nze-datarS   rU   rZ   r]   z/Server supports encryption type %s with salt %sz,Preferred enc type not in supported enctypes)collectionsOrderedDictr   loadnativer)   r	   r
   r*   r   rp   rt   r<   get_preferred_enctyper   encoderF   )	rH   r   supp_enc_methods
enc_method	data_typeenc_info_listenc_infopreferred_enc_typerZ   rI   rI   rJ   "select_preferred_encryption_method   s(   


"z0KerbrosClient.select_preferred_encryption_methodoverride_snamec                 C   s  |   \}}|du rdS td tjtjj}i }	tt||	d< t	t
jj| jjdd|	d< | jj |	d< |du rQt	t
jjd| jj gd|	d	< nt	t
jj| d|	d	< |tjd
d jdd|	d< |tjd
d jdd|	d< td|	d< |du r| j |	d< n||	d< i }
|du rttd|
d< tddi |
d< i }t|d< tjj|d< t |
dkr|
g|d< t!|	|d< t"|}td| j#$   | j#j%| dd}|j&dkr|j'}|| _(|dks| jj)du r|S t*|d  d  | _+|d  d | _,t-| j+j.| j/t0|d  d | _1n+|j'd! t2j3jkr't4||j'}td" | 5|}| 6|}td# |j'}|| _(| jj7durl| 8|\| _9| _:| _+|j| _,| j;j<| j(| j9dd$ td% dS |d  d& }| j+=| j1d'|}z	t>?|j'| _9W n6 t@y } z)td( z	tA?|j'| _9W n t@y } ztBd) |d}~ww W Y d}~nd}~ww t-| j+j.| j9d* d+ | _:| j;j<| j(| j9dd$ td% dS ),aJ  
		decrypt_tgt: used for asreproast attacks
		Steps performed:
			1. Send and empty (no encrypted timestamp) AS_REQ with all the encryption types we support
			2. Depending on the response (either error or AS_REP with TGT) we either send another AS_REQ with the encrypted data or return the TGT (or fail miserably)
			3. PROFIT
		Nz2Generating initial TGT without authentication datar_   r`   ra   rb   rc   rd   re   r[   rf   r   rV   rh   ri   rj   rk   r]   TrR   rS   rT   rU   rl   rm   rn   ro   zSending initial TGT to %sF)throwr   r   
error-codez1Got reply from server, asikg to provide auth dataz"Got valid TGT response from server)override_ppzGot valid TGTr^      z(EncAsRepPart load failed, is this linux?z+Failed to load decrypted part of the reply!r   r   )Cr   r   rp   ru   rv   rw   rx   r   r~   r   r+   r   rz   r<   r   r   r   r   r   get_principalnamer   ry   r   r   get_supported_enctypesrq   r   r   rr   r   r,   r   lenr   r   r=   get_addr_strr   rt   r   r@   	nopreauthr&   rC   rD   r%   r{   r|   r*   rE   r#   KDC_ERR_PREAUTH_REQUIREDr$   r   r   r   decrypt_asrep_certrA   r?   r>   add_tgtdecryptr   r   r   r   error)rH   override_etypedecrypt_tgtrO   r   rP   _r   rv   r   r   r   r   r   r   
cipherTexttempr   rI   rI   rJ   get_TGT   s   

 $
&







zKerbrosClient.get_TGTspn_userc              
   C   s   z/| j d u r
td| j |\}}}|d ur|t|d |d }t|j}||d |d fW S  tyG } zd d d |fW  Y d }~S d }~ww )Nr   r   r   r   )r>   r   get_tgsr%   r   r   )rH   r   tgsr   r   r   r   rI   rI   rJ   tgs_from_ccacheM  s   

zKerbrosClient.tgs_from_ccachec                 C   s  |  |\}}}}|du r|||fS | jdu r%|  \}}|dur%tdtd|   tjtj	j
}	i }
ttg d|
d< |j |
d< ttjj| d|
d< |	tjd	d
 jdd|
d< td|
d< |rr||
d< n| jdkr}dg|
d< n| jg|
d< i }t|d< t| jd |d< | jd |d< |	j|d< |	jdd|d< |rt }d|_d|_i }d|d< | |d< t ||d< d|d< | j!"| j#dt$|% d}i }t|d< t&j'j|d < t(t |d!< t)| jd" |d"< t*| j|d#|d$< i }t+j,j|d%< t-|% |d&< i }t|d< t&j.j|d < |g|d'< t/|
|d(< t,|}td) | j01|% }|j2d*kr>t3|d+td, |j4}t56| j!7| j#d-|d. d/ j4}t8|d0 d1 |d0 d2 }| j9:|| td3 || _;|||fS )4a  
		Requests a TGS ticket for the specified user.
		Retruns the TGS ticket, end the decrpyted encTGSRepPart.

		spn_user: KerberosTarget: the service user you want to get TGS for.
		override_etype: None or list of etype values (int) Used mostly for kerberoasting, will override the AP_REQ supported etype values (which is derived from the TGT) to be able to recieve whatever tgs tiecket 
		NzNo TGT found in CCACHE!z$Constructing TGS request for user %s)rL   rM   renewable_okcanonicalizer_   rc   ra   re   r[   rf   r   rV   rh   rj   rk   r]   ir   authenticator-vnocrealmrb   r   r   s                   i  	cksumtyper   cksumz
seq-number   rl   rm   
ap-optionsticketr\   r   rS   rU   rn   ro   z"Constructing TGS request to serverr   zget_TGS failed!zGot TGS reply, decrypting...   r   r^   r   r   r   zGot valid TGS reply)<r   r@   r   r   r   rp   get_formatted_pnameru   rv   rw   rx   r   r~   r   r   r   r+   r   rz   r   r   ry   r   r   rD   r   r   rW   r-   flagschannel_bindingto_bytesr   rC   r}   r?   r   rr   r,   
KRB_AP_REQr   r   r   r)   r   r   KRB_TGS_REQr   r=   r   rt   r$   r   r   r   r   r%   r>   add_tgsrB   )rH   r   r   is_linuxr   encTGSRepPartr   r   r   rv   r   authenticator_dataacchksumauthenticator_data_encap_reqr   r   r   r   rI   rI   rJ   get_TGS\  s~   









"

zKerbrosClient.get_TGS)rL   rM   r   zenc-tkt-in-skeyc                 C   s  | j std |   | j|}tjtjj	}i }t
|d< t| j d |d< | j d |d< |j|d< |jdd|d< | j| jd	t| d }i }t
|d
< tjj|d< tt |d< t| j d |d< t| j|d|d< i }tjj|d< t| |d< i }	tt||	d< tt j!j| jj"#dd|	d< | jj$% |	d< |tj&dd jdd|	d< t'(d|	d< dg|	d< t| j d g|	d< i }
t
|
d
< tj)j|
d< |g|
d< t*|	|
d < t|
}td! | j+,| }|j-d"krd#}|j.d$ d%krd&}t/||td' |j.}t0t1|d d( d  }|d d( d) }|2| jd*|}t34|j.}t54| j2| jd+|d( d) j.}t6|d, d- |d, d. }| j78|| td/ ||||fS )0Nz+[U2U] TGT is not available! Fetching TGT...r   r   rb   r   r   rV   r   r   rl   rm   r   r   r\   r   rS   rU   r_   r`   ra   re   rc   r[   rf   rh   rj   rk   r   r]   additional-ticketsrn   ro   z[U2U] Sending request to serverr   z[U2U] failed!r      zc[U2U] Failed to get U2U! Error code (16) indicates that delegation is not enabled for this account!z[U2U] Got reply, decrypting...r   r^      r  r   r   r   z[U2U] Got valid TGS reply)9r@   r   rp   r   r<   r   ru   rv   rw   rx   r   r   rW   ry   rC   r}   r?   r   rr   r,   r  rz   r   r~   r   r   rD   r)   r   r   r   r   r+   r   r   r   r   r   r   r   r   r  r   r=   r   rt   r   r$   r&   rq   r   r"   r   r   r%   r>   r  )rH   rO   r   supp_encrv   r  r  r  pa_data_authkrb_tgs_bodykrb_tgs_reqr   replyemsgr   r^   	encticketdecdata	decticketr
  r   rI   rI   rJ   U2U  sj   

 




"
zKerbrosClient.U2U)rL   rM   r   c                 C   s  | j std |   | j|}d}tjtjj	}i }t
|d< t| j d |d< | j d |d< |j|d< |jdd|d	< | j| jd
t| d}	i }
t
|
d< tjj|
d< tt |
d< t| j d |
d< t| j|	d|
d< i }tjj|d< t|
 |d< tjjj dddd}||j!" 7 }||j#" 7 }||" 7 }td|$   td|  t%&| jd|}td|$   i }t't(d|d< ||d< i }t)tjj|* d|d< |j#|d < t+||d!< ||d"< i }t't,d#|d< t-| |d< |durt.|t/r|g}nt.|t0r|}n|* }n| jj!1d$}i }t2t||d%< t)tj3j|d|d&< | jj#4 |d'< |tj5d(d) jdd|d*< t67d+|d,< | jj8g|d-< i }t
|d< tj9j|d< ||g|d.< t:||d/< t|}td0 | j;<| }|j=d1krd2}|j>d3 d4krd5}t?||td6 |j>}t@A| jB| jd7|d8 d9 j>}tC|d: d; |d: d< }| jDE|| td= || _F|||fS )>z0
		user_to_impersonate : KerberosTarget class
		z0[S4U2self] TGT is not available! Fetching TGT...Kerberosr   r   rb   r   r   rV   r   r   Nrl   rm   r   r   r\   r   rS   rU      littleFsignedz[S4U2self] S4UByteArray: %s   z[S4U2self] chksum_data: %sHMAC_MD5r   r   ra   userName	userRealmr   zauth-packagezPA-FOR-USERr`   r_   re   rc   r[   rf   rh   rj   rk   r]   rn   ro   z$[S4U2self] Sending request to serverr   zS4U2self failed!r   r  zlS4U2self: Failed to get S4U2self! Error code (16) indicates that delegation is not enabled for this account!z#[S4U2self] Got reply, decrypting...r  r   r^   r   r   r   z[S4U2self] Got valid TGS reply)Gr@   r   rp   r   r<   r   ru   rv   rw   rx   r   r   rW   ry   rC   r}   r?   r   rr   r,   r  rz   r   r~   r   r   rD   r)   r   r   r+   r   r  r   r   r   hexr'   r   rq   r   r   r   r   r   r   
isinstancestrlistr   r   UNKNOWNr   r   r   r   r{   r  r   r=   r   rt   r   r$   r   r   r   r%   r>   r  rB   )rH   user_to_impersonater   rO   r   r  auth_package_namerv   r  r  r  r  S4UByteArraychksum_datar  pa_for_user_encpa_for_userr  r  r   r  r  r   r
  r   rI   rI   rJ   S4U2self  s   







"

zKerbrosClient.S4U2selfc                 C   s  t dd|   tjtjj}| j	|}i }t
td|d< tdttdgi |d< i }t|d< t| jd	 |d	< | jd
 |d
< |j|d< |jdd|d< | j| jdt| d }i }	t|	d< tjj|	d< tt |	d< t| jd |	d< t| j|d|	d< i }
t j!j|
d< t"|	 |
d< i }t#tg d|d< t$t%j&j| d|d< | jj'( |d< |tj)dd jdd|d< t*+d|d< | jj,g|d < |g|d!< i }t|d< tj-j|d< |
|g|d"< t.||d#< t!|}| j/0| }|j1d$krd%}|j2d& d'krd(}t3||t d) |j2}t45| j6| jd*|d+ d, j2}t7|d- d. |d- d/ }| j89|| t d0 |||fS )1Nz[S4U2proxy] Impersonating %sr`   zPA-PAC-OPTIONSrS   rz   z%resource-based constrained delegationrU   r   r   rb   r   r   rV   r   r   rl   rm   r   r   r\   r   )rL   rM   zconstrained-delegationr   r_   ra   re   rc   r[   rf   rh   rj   rk   r]   r  rn   ro   r   zS4U2proxy failed!r   r  znS4U2proxy: Failed to get S4U2proxy! Error code (16) indicates that delegation is not enabled for this account!z+[S4U2proxy] Got server reply, decrypting...r  r   r^   r   r   r   z[S4U2proxy] Got valid TGS reply):r   rp   joinr   ru   rv   rw   rx   r<   r   rq   r   r    r!   r~   rr   r   r   r@   rW   ry   rC   r}   r?   r   r,   r  rz   r   r   r   rD   r)   r   r   r   r   r+   r   r   r   r   r   r   r{   r  r   r=   r   rt   r   r$   r   r   r   r%   r>   r  )rH   s4uself_ticketr   r   rv   r  pa_pac_optsr  r  r  
pa_tgs_reqr  r  r   r  r  r   r
  r   rI   rI   rJ   	S4U2proxyx  sb   



"

zKerbrosClient.S4U2proxyr   c              	   C   s   t ||| j||||dS )N)r  
seq_numberap_optscb_data)r6   r@   )rH   r   r
  
sessionkeyr  r8  r9  r:  rI   rI   rJ   construct_apreq  s   zKerbrosClient.construct_apreqc                 C   s    |  |\}}}| |d |S )Nr   )r2  r7  )rH   target_userservice_spnr   r
  r   rI   rI   rJ   getST  s   zKerbrosClient.getSTc                 C   s  dd }|d D ]}|d dkrt |d j} nqtdztj|d j}W n   tj|d d	d  j}Y |d
 }|d dkrJtdt|d j}tddgdd |d D  d}tj	t
|d  dd  ddd}| jj|}	|d }
|	| jjj |
 }|d d }t| }|tjkr||d| _n|tjkr||d| _n	|tjkrtdt|j| j}|d d }||d |}t|j}tt|d! d"  }t|j|d! d# }|||fS )$Nc                 S   s~   d}d}t ||k r=tt|g|   }t |t | |kr/||d |t |  7 }	 |S ||7 }|d7 }t ||k s
|S )N    r   r[   )r   r   r   bytesr   )rz   keysizeoutput
currentNumcurrentDigestrI   rI   rJ   truncate_key  s   z6KerbrosClient.decrypt_asrep_cert.<locals>.truncate_keyrn   rS   r#  rU   zPA_PK_AS_REP not found!dhSignedData   encap_content_infocontent_typez1.3.6.1.5.2.3.2z%Keyinfo content type unexpected valuecontent 1c                 S   s   g | ]}t |qS rI   )r)  ).0xrI   rI   rJ   
<listcomp>  s    z4KerbrosClient.decrypt_asrep_cert.<locals>.<listcomp>subjectPublicKeyr  r   bigFr!  serverDHNoncer   r]       r  zBRC4 key truncation documentation missing. it is different from AESr^   r   r   r   r   )r0   r   r   r   r7   
SignedDatar1   rq   r3  
from_bytesr8   	BitStringrr   r<   r   exchanger   r&   r(   AES256rG   AES128RC4NotImplementedErrorr%   r{   r   r   )rH   as_reprF  papkasrepsdkeyinfoauthdatapubkey
shared_keyserver_noncefullKeyr]   r^   r   enc_datadec_dataencasrepsession_keyrI   rI   rJ   r     sF   $&



z KerbrosClient.decrypt_asrep_cert)NF)!__name__
__module____qualname__r3   r4   rK   r   r)  boolr   r   r   r   r   r   r5   r   r   r  r*   DES_CBC_CRCDES_CBC_MD4DES_CBC_MD5DES3_CBC_SHA1ARCFOUR_HMAC_MD5AES256_CTS_HMAC_SHA1_96AES128_CTS_HMAC_SHA1_96r  r2  r7  r<  r?  r   rI   rI   rI   rJ   r9      s     ,4K"g
.` JrFr9   )Kr   ru   r   typingr   r   	unicryptor   minikerberosr   minikerberos.common.ccacher   !minikerberos.network.clientsocketr   "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"   minikerberos.protocol.errorsr#   r$    minikerberos.protocol.encryptionr%   r&   r'   r(   minikerberos.protocol.constantsr)   r*   r+   r,    minikerberos.protocol.structuresr-   minikerberos.protocol.rfc4556r.   r/   r0   r1   r2   minikerberos.common.credsr3   minikerberos.common.targetr4   minikerberos.common.spnr5   !minikerberos.protocol.ticketutilsr6   r   r7   r8   r9   rI   rI   rI   rJ   <module>   s*    x