o
    àý°jö<  ã                
   @   s¬  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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 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 dd	lmZ dd
l m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+ dZ,dZ-dZ.G dd„ deƒZ/ddddddddddœ	Z0G dd„ dej1ƒZ2G dd„ deƒZ3d d!„ Z4G d"d#„ d#e5ƒZ6		$d.d%d&„Z7d'd(„ Z8d)d)d)d)ddde,df	d*d+„Z9d)d)d)d)ddde,df	d,d-„Z:dS )/é    N)Ú	namedtypeÚuniv)ÚdecoderÚencoder)ÚLOG)ÚEnumé   )ÚgetKerberosTGTÚsendReceive)Ú_sequence_componentÚ_sequence_optional_componentÚseq_setÚRealmÚPrincipalNameÚAuthenticatorÚAS_REPÚAP_REQÚAP_REPÚKRB_PRIVÚEncKrbPrivPart)ÚCCache)ÚPrincipalNameTypeÚApplicationTagNumbersÚAddressTypeÚencodeFlags)ÚKeyÚget_random_bytes)Ú	PrincipalÚKerberosTimeÚTicketiÐ  i€ÿ  zkadmin/changepwc                   @   s0   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )ÚKPasswdResultCodesr   r   é   é   é   é   é   é   éÿÿ  N)Ú__name__Ú
__module__Ú__qualname__ÚSUCCESSÚ	MALFORMEDÚ	HARDERRORÚ	AUTHERRORÚ	SOFTERRORÚACCESSDENIEDÚBAD_VERSIONÚINITIAL_FLAG_NEEDEDÚUNKNOWN© r4   r4   úˆ/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/impacket/krb5/kpasswd.pyr    4   s    r    zpassword changed successfullyz!protocol error: malformed requestz%server error (KRB5_KPASSWD_HARDERROR)zLauthentication failed (may also indicate that the target user was not found)z1password change rejected (KRB5_KPASSWD_SOFTERROR)zaccess deniedzprotocol error: bad versionz#protocol error: initial flag neededzunknown error)	r   r   r!   r"   r#   r$   r%   r&   r'   c                   @   s:   e Zd Ze edde ¡ ƒedde	ƒ ƒedde
ƒ ƒ¡ZdS )ÚChangePasswdDataÚ	newpasswdr   Útargnamer   Ú	targrealmr!   N)r(   r)   r*   r   Ú
NamedTypesr   r   ÚOctetStringr   r   r   ÚcomponentTyper4   r4   r4   r5   r6   M   s    ýr6   c                   @   s$   e Zd ZdZdZdZdZdZdZdS )ÚPasswordPolicyFlagsr   r!   r#   é   é   é    N)	r(   r)   r*   ÚComplexÚNoAnonChangeÚNoClearChangeÚLockoutAdminsÚStoreCleartextÚRefusePasswordChanger4   r4   r4   r5   r=   Y   s    r=   c                    st   d}d}t | ƒt |¡ks| dd… dkrt‚t || ¡‰ ˆ d ˆ d ˆ d | ˆ d | ‡ fd	d
„tD ƒdœ}|S )Nz!HIIIQQl    @ÓT$r   r!   s     r   r#   r$   c                    s    g | ]}|j ˆ d  @ r|j‘qS )r"   )ÚvalueÚname)Ú.0Úflag©Ú
propertiesr4   r5   Ú
<listcomp>o   s     z)_decodePasswordPolicy.<locals>.<listcomp>)Ú	minLengthÚhistoryÚmaxAgeÚminAgeÚflags)ÚlenÚstructÚcalcsizeÚ
ValueErrorÚunpackr=   )ÚppolicyStringÚppolicyStructÚticksInADayÚpasswordPolicyr4   rK   r5   Ú_decodePasswordPolicyb   s   "

ûr\   c                   @   s   e Zd ZdS )ÚKPasswdErrorN)r(   r)   r*   r4   r4   r4   r5   r]   w   s    r]   ó	   localhostc                 C   s¬  |	d u rt  tdƒd¡}	|
d u rtj tjj¡}
t|tƒs"| 	d¡}t
ƒ }d|d< ||d< t|d| jƒ |
j|d< t |
¡|d	< |	|d
< tj|d< |j|d d< |j|d d< t 	|¡}| |d|d ¡}t d t |¡¡¡ tƒ }d|d< t tjjƒ|d< ttƒ ƒ|d< t|d|jƒ tj|d< |j|d d< ||d d< t 	|¡}t ƒ }||d< |rÉ|rÉ| !¡ |d< tj|d< t"j#j|d d< ||d d d< t 	|¡}t d t |¡¡¡ t$ƒ }t 	|¡|d< |	|d
< tj|d< t%j&j|d d < ||d d!< t 	|¡}| |d"|d ¡}t d# t |¡¡¡ t'ƒ }d|d< t tj'jƒ|d< tj|d$< |j|d$ d< ||d$ d< t 	|¡}t(|ƒ}t(|ƒ}d%| | }t) *d&|t+|¡}|| | }|S )'Nr#   Úbigúutf-8r$   zauthenticator-vnoÚcrealmÚcnameÚcusecÚctimez
seq-numberÚsubkeyÚkeytypeÚkeyvalueé   zb64(authenticator): {}Úpvnozmsg-typez
ap-optionsÚticketÚauthenticatorÚetypeÚcipherr7   r9   r8   z	name-typezname-stringr   zb64(changePasswdData): {}ú	user-dataz	s-addressz	addr-typeÚaddressé   úb64(encKrbPrivPart): {}úenc-partr%   ú!HHH),ÚintÚ
from_bytesr   ÚdatetimeÚnowÚtimezoneÚutcÚ
isinstanceÚbytesÚencoder   r   Úcomponents_to_asn1Úmicrosecondr   Úto_asn1r   ÚnoValueÚenctypeÚcontentsr   Úencryptr   ÚdebugÚformatÚbase64Ú	b64encoder   r   rG   r   Úlistr6   Úupperr   ÚNT_PRINCIPALr   r   ÚIPv4r   rS   rT   ÚpackÚKRB5_KPASSWD_PROTOCOL_VERSION)Ú	principalÚdomainÚ	newPasswdÚtgsrm   Ú
sessionKeyÚsubKeyÚtargetPrincipalÚtargetDomainÚsequenceNumberrw   Úhostnamerk   ÚencodedAuthenticatorÚencryptedEncodedAuthenticatorÚapReqÚapReqEncodedÚchangePasswdDataÚencodedChangePasswdDataÚencKrbPrivPartÚencodedEncKrbPrivPartÚencryptedEncKrbPrivPartÚkrbPrivÚkrbPrivEncodedÚapReqLenÚ
krbPrivLenÚ
messageLenÚencodedr4   r4   r5   ÚcreateKPasswdRequest{   sv   












r§   c                 C   sð  d}t  |¡}z!| d |… }t  ||¡\}}}| ||| … }| || d … }	W n   tdƒ‚ztj|tƒ d�d }
tj|	tƒ d�d }W n   tdƒ‚|d d }z	| |d|¡}W n   td	ƒ‚t	 
d
 t |¡¡¡ z#tj|tƒ d�d }|d  ¡ }t |d d… d¡|dd … }}W n   tdƒ‚t	 
d ||¡¡ zt| }W n ty·   td }Y nw zt|ƒ}djdi |¤Ž}W n% tt jfyë   z| d¡}W n tyè   t |¡ d¡}Y nw Y nw |tjjk}||||fS )Nrs   z(kpasswd: malformed reply from the server©Úasn1Specr   zBkpasswd: malformed AP_REP or KRB_PRIV in the reply from the serverrr   rm   rp   z=kpasswd: cannot decrypt KRB_PRIV in the reply from the serverrq   rn   r!   r_   zNkpasswd: malformed EncKrbPrivPart in the KRB_PRIV in the reply from the serverzresultCode: {}, message: {}r'   z¤Password policy:
	Minimum length: {minLength}
	Password history: {history}
	Flags: {flags}
	Maximum password age: {maxAge} days
	Minimum password age: {minAge} daysr`   zlatin-1r4   )rT   rU   rW   r]   r   Údecoder   r   Údecryptr   r„   r…   r†   r‡   r   ÚasOctetsrt   ru   ÚRESULT_MESSAGESÚKeyErrorr\   rV   ÚerrorÚUnicodeDecodeErrorÚbinasciiÚhexlifyr    r+   rG   )r¦   rm   r“   ÚheaderStructÚ	headerLenÚheadersÚ_ÚapRepLenÚapRepEncodedr¢   ÚapRepr¡   r    rŸ   rž   ÚresultÚ
resultCodeÚmessageÚresultCodeMessageÚppolicyÚsuccessr4   r4   r5   ÚdecodeKPasswdReply×   sb   
&ÿù
ùÿ€ýrÀ   Ú c                 C   s&   t | |dd||||||||	|
|ƒ dS )ad  
    Change the password of the requesting user with RFC 3244 Kerberos Change-Password protocol.

    At least one of oldPasswd, (oldLmhash, oldNthash) or (TGT, aesKey) should be defined.

    :param string clientName:   username of the account changing their password
    :param string domain:       domain of the account changing their password
    :param string newPasswd:    new password for the account
    :param string oldPasswd:    current password of the account
    :param string oldLmhash:    current LM hash of the account
    :param string oldNthash:    current NT hash of the account
    :param string aesKey:       current AES key of the account
    :param string TGT:          TGT of the account. It must be a TGT with a SPN of kadmin/changepw
    :param string kdcHost:      KDC address/hostname, used for Kerberos authentication
    :param string kpasswdHost:  KDC exposing the kpasswd service (TCP/464, UDP/464),
                                used when sending the password change requests
                                (Default: same as kdcHost)
    :param int kpasswdPort:     TCP port where kpasswd is exposed (Default: 464)
    :param string subKey:       Subkey to use to encrypt the password change request
                                (Default: generate a random one)

    :return void:               Raise an KPasswdError exception on error.
    N)ÚsetPassword)Ú
clientNamer�   r�   Ú	oldPasswdÚ	oldLmhashÚ	oldNthashÚaesKeyÚTGTÚkdcHostÚkpasswdHostÚkpasswdPortr“   r4   r4   r5   ÚchangePassword  s
   

ýrÌ   c               
   C   sŽ  |du r|
}t | tjjd�}|	du rTt d¡rTt d¡}zt |¡}W n   Y n+t 	d 
|¡¡ t}| |d¡}|durK| ¡ }	t d 
||¡¡ n	t d 
||¡¡ |	du rit|||||||
td�\}}}}n|	d	 }|	d
 }|	d }tj|tƒ d�d }tƒ }| |d ¡ |du r˜t|jƒ}t|j|ƒ}t|||||||||ƒ	}t||||ƒ}t|||ƒ\}}}}|r¹dS |}|rÃ|d| 7 }t|ƒ‚)aê  
    Set the password of a target account with RFC 3244 Kerberos Set-Password protocol.
    Requires "Reset password" permission on the target, for the user.

    At least one of oldPasswd, (oldLmhash, oldNthash) or (TGT, aesKey) should be defined.

    :param string clientName:   username of the account performing the reset
    :param string domain:       domain of the account performing the reset
    :param string targetName:   username of the account whose password will be changed
    :param string targetDomain: domain of the account whose password will be changed
    :param string newPasswd:    new password for the target account
    :param string oldPasswd:    current password of the account performing the reset
    :param string oldLmhash:    current LM hash of the account performing the reset
    :param string oldNthash:    current NT hash of the account performing the reset
    :param string aesKey:       current AES key of the account performing the reset
    :param string TGT:          TGT of the account performing the reset
                                It must be a TGT with a SPN of kadmin/changepw
    :param string kdcHost:      KDC address/hostname, used for Kerberos authentication
    :param string kpasswdHost:  KDC exposing the kpasswd service (TCP/464, UDP/464),
                                used when sending the password change requests
                                (Default: same as kdcHost)
    :param int kpasswdPort:     TCP port where kpasswd is exposed (Default: 464)
    :param string subKey:       Subkey to use to encrypt the password change request
                                (Default: generate a random one)

    :return bool:               True if successful, raise an KPasswdError exception on error.
    N)ÚtypeÚ
KRB5CCNAMEzUsing Kerberos cache: {}FzUsing TGT for {} from cache {}z%No valid TGT for {} found in cache {})Ú
serverNameÚKDC_REPrm   r’   r¨   r   rj   z: )r   r   rŠ   rG   ÚosÚgetenvr   ÚloadFiler   r„   r…   ÚKRB5_KPASSWD_TGT_SPNÚgetCredentialÚtoTGTÚinfor	   r   rª   r   r   Ú	from_asn1r   Úkeysizer   r�   r§   r
   rÀ   r]   ) rÃ   r�   Ú
targetNamer•   r�   rÄ   rÅ   rÆ   rÇ   rÈ   rÉ   rÊ   rË   r“   ÚuserNamerÎ   ÚccacherŽ   ÚcredsÚtgtrm   ÚoldSessionKeyr’   rj   ÚsubKeyBytesÚkpasswordReqÚkpasswordRepr¿   r»   r½   r¼   ÚerrorMessager4   r4   r5   rÂ   =  sP   
ÿ
ÿrÂ   )NNNNr^   );r†   r±   rv   rÑ   rT   Úpyasn1.typer   r   Úpyasn1.codec.derr   r   Úimpacketr   Úimpacket.dcerpc.v5.enumr   Ú
kerberosv5r	   r
   Úasn1r   r   r   r   r   r   r   r   r   r   r   rÜ   r   Ú	constantsr   r   r   r   Úcryptor   r   Útypesr   r   r   ÚKRB5_KPASSWD_PORTr�   rÔ   r    r­   ÚSequencer6   r=   r\   Ú	Exceptionr]   r§   rÀ   rÌ   rÂ   r4   r4   r4   r5   Ú<module>   sV   4÷	
þ\
F
þ
"þ