o
    àý°j�:  ã                
   @   s  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 d dl	m
Z
 d dlmZmZmZ d d	lmZmZ d d
lmZmZmZmZmZmZ d dlm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%Z%d dl&Z&d dl'Z'd dl(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d� e.j/dd d!d� e.j/d"d d#d� e.j/d$d%dd&d� e. 0d'¡Z1e1j/d(dd)d*d� e1j/d+d d,d� e1j/d-d d.d� e1j/d/dd0d1d� e. 0d2¡Z1e1j/d3dd4d5d� e1j/d6dd7d8d� e1j/d9d:d d;d<� e2e(j3ƒd=k�re. 4¡  e( 5d=¡ e. 6¡ Z7e 8e7j9e7j:¡ ee7j;e7j<e7j=e7j>e7j?ƒ\Z@ZAZBZCZCe7_?e@d>k�rGe' Dd?¡ e( 5d=¡ ze)eAeBe@e7ƒZEeE F¡  W dS  eG�y� ZH ze' I¡ jJe'jKk�rod dlLZLeL M¡  e' NeOeHƒ¡ W Y dZH[HdS dZH[Hww dS )@é    )Údivision)Úprint_function)Úunicode_literals)Údatetime)Úversion)Ú	transport)Úhept_map)ÚMSRPC_UUID_GKDIÚ
GkdiGetKeyÚGroupKeyEnvelope)ÚRPC_C_AUTHN_LEVEL_PKT_INTEGRITYÚRPC_C_AUTHN_LEVEL_PKT_PRIVACY)ÚEncryptedPasswordBlobÚKeyIdentifierÚcompute_kekÚ	create_sdÚdecrypt_plaintextÚ
unwrap_cek)Úlogger)Úparse_identityÚ
ldap_login)ÚldapÚldapasn1)Údecoder)Úrfc5652Nc                   @   s<   e Zd Zedd„ ƒZdd„ Zdd„ Zedd„ ƒZd	d
„ ZdS )ÚGetLAPSPasswordc           
         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|Ž ƒ qA|rŒt|dƒ�0}d d	d„ t |ƒD ƒ¡}	| |	j|Ž d
 ¡ | D ]}| |	j|Ž  	¡ d
 ¡ qkW d   ƒ d S 1 s…w   Y  d S d 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/GetLAPSPassword.pyÚ
<listcomp>1   s    z.GetLAPSPassword.printTable.<locals>.<listcomp>ú c                 S   ó   g | ]
\}}d ||f ‘qS )z	{%d:%ds} r   ©r   ÚnumÚwidthr   r   r"   r#   4   ó    z  c                 S   s   g | ]}d | ‘qS )ú-r   )r   ÚitemLenr   r   r"   r#   8   s    Úwú	c                 S   r%   )z{%d:%ds}r   r&   r   r   r"   r#   >   r)   Ú
)
Ú	enumerateÚmaxÚappendr   ÚjoinÚprintÚformatÚopenÚwriteÚstrip)
ÚitemsÚheaderÚ
outputfileÚcolLenÚcolÚ	rowMaxLenÚoutputFormatr   ÚfileÚoutputFormat_filer   r    r"   Ú
printTable-   s$   ÿ"ýÿzGetLAPSPassword.printTablec                 C   sÈ   || _ || _|| _|| _d | _d| _d| _|j| _|j	| _
|j| _|j| _|j| _|j| _|j| _i | _|jd urC|j d¡\| _| _| j d¡}d| _|D ]}|  jd| 7  _qN| jd d… | _d S )NÚ ú:Ú.zdc=%s,éÿÿÿÿ)ÚoptionsÚ_GetLAPSPassword__usernameÚ_GetLAPSPassword__passwordÚ_GetLAPSPassword__domainÚ_GetLAPSPassword__targetÚ_GetLAPSPassword__lmhashÚ_GetLAPSPassword__nthashÚaesKeyÚ_GetLAPSPassword__aesKeyÚkÚ_GetLAPSPassword__doKerberosÚdc_ipÚ_GetLAPSPassword__kdcIPÚdc_hostÚ_GetLAPSPassword__kdcHostÚcomputerÚ _GetLAPSPassword__targetComputerr:   Ú_GetLAPSPassword__outputFileÚ
ldaps_flagÚ_GetLAPSPassword__ldaps_flagÚ_GetLAPSPassword__KDSCacheÚhashesÚsplitÚbaseDN)ÚselfÚusernameÚpasswordÚdomainÚcmdLineOptionsÚdomainPartsr!   r   r   r"   Ú__init__C   s,   
zGetLAPSPassword.__init__c              
   C   sø  zXt |ƒ}tj|d t ¡ d�\}}|d }tj|t ¡ d�\}}|d }|d d }	|	d }
tt|
d ƒƒ}t |
d	 d
 ¡\}}|d d d d  ¡  d¡}t	|ƒ}d}W n t
ys } zt dt|ƒ ¡ W Y d }~nd }~ww |d | jv rƒ| j|d  }nÇt| jtdd�}t |¡}t|dƒr¤|j| j| j| j| j| jd� | jr°|j| j| jd� | jd urÁ| | j¡ | | j¡ |  ¡ }| !t"¡ | !t#¡ t $d| ¡ z| %¡  W n t
yù } zt dt|ƒ ¡ |W  Y d }~S d }~ww t $d¡ z| &t¡ W n t
�y$ } zt dt|ƒ ¡ |W  Y d }~S d }~ww t $d¡ t $d¡ t'|||d |d |d |d d�}t(d )|d  ¡ƒ}|| j|d < t*||ƒ}t|d! d" d# ƒ}t |¡\}}t|d ƒ}t+|t|	d$ ƒƒ}t,|||ƒS )%NÚBlob)Úasn1SpecÚcontentÚrecipientInfosr   ÚkekriÚkekidÚkeyIdentifierÚotherÚkeyAttrzfield-1é   úutf-8Tz;Cannot unpack msLAPS-EncryptedPassword blob due to error %sÚ	RootKeyIdÚncacn_ip_tcp)ÚdestHostÚremoteIfÚprotocolÚset_credentials)r_   r`   ra   ÚlmhashÚnthash)ÚkdcHostzConnecting to %sz.Something went wrong, check error status => %sÚ	ConnectedzSuccessfully boundzCalling MS-GKDI GetKeyÚL0IndexÚL1IndexÚL2Index)Ú	target_sdÚl0Úl1Úl2Úroot_key_idó    ÚpbbOutÚencryptedContentInfoÚcontentEncryptionAlgorithmÚ
parametersÚencryptedKey)-r   r   Údecoder   ÚContentInfoÚEnvelopedDatar   ÚbytesÚasOctetsr   Ú	ExceptionÚloggingÚerrorÚstrrZ   r   rJ   r	   r   ÚDCERPCTransportFactoryÚhasattrru   rG   rH   rI   rK   rL   rP   Úset_kerberosrR   ÚsetRemoteHostÚsetRemoteNameÚget_dce_rpcÚset_auth_levelr   r   ÚdebugÚconnectÚbindr
   r   r2   r   r   r   )r^   ÚrawEncryptedLAPSBlobÚencryptedLAPSBlobÚparsed_cms_dataÚ	remainingÚenveloped_data_blobÚparsed_enveloped_dataÚ_Úrecipient_infosÚkek_recipient_infoÚkek_identifierÚkey_idÚtmpÚsidr}   Úlaps_enabledÚeÚgkeÚstringBindingÚrpctransportÚdceÚrespÚkekÚenc_content_parameterÚivÚcekr   r   r"   ÚgetLAPSv2Decrypt_   st   €ÿ




€þ
€þ

$
z GetLAPSPassword.getLAPSv2Decryptc                 C   s   | d8 } | d } | S )Nl     }*{Gíi€–˜ r   )Útr   r   r"   ÚgetUnixTimež   s   zGetLAPSPassword.getUnixTimec                 C   s4  t | j| j| j| j| j| j| j| j| j	| j
| j| jƒ}|j| _d}| jd ur/|d| j d 7 }|d7 }ztjddd�}|j|g d¢|gd�}W n' tjyn } z| ¡  d	¡d
krct d¡ | ¡ }n‚ W Y d }~nd }~ww g }t dt|ƒ ¡ t|ƒd
kr–| jd ur�t d| j ¡ d S t d¡ d S |D ]×}t|tjƒdur£q˜z°d }d }	d }
d }d}|d D ]€}t|d ƒdkrÄt|d d
 ƒ}t|d ƒdkrîd}|  t|d d
 ƒ¡}t  !|d d…  "d¡¡}|d }
|d }q²t|d ƒdksÿt|d ƒdk�rt|d d
 ƒdk�rt# $|  %t&t|d d
 ƒƒ¡¡ 'd¡}	q²t|d ƒdk�r2|d d
  (¡  "d¡}q²|d u�rR|d u�rR||
||	t|ƒg}dd „ |D ƒ}| )|¡ W q˜ t*�yo } zt d!t|ƒ ¡ W Y d }~q˜d }~ww t|ƒd
k�rŽ| jd u�r‡t d"| j ¡ d S t d#¡ d S |  +|g d$¢| j,¡ d S )%Nz^(&(objectCategory=computer)(|(msLAPS-EncryptedPassword=*)(ms-MCS-AdmPwd=*)(msLAPS-Password=*))z(name=ú)Tiè  )ÚcriticalityÚsize)úmsLAPS-EncryptedPasswordúmsLAPS-PasswordExpirationTimezmsLAPS-PasswordÚsAMAccountNameúms-Mcs-AdmPwdExpirationTimezms-MCS-AdmPwd)ÚsearchFilterÚ
attributesÚsearchControlsÚsizeLimitExceededr   zNsizeLimitExceeded exception caught, giving up and processing the data receivedzTotal of records returned %dz%s$ not found in LDAP.zNo valid entry in LDAPFr¾   Útyper»   Úvalsr¹   iîÿÿÿzutf-16leÚnÚpr¼   rº   Ú0z%Y-%m-%d %H:%M:%Szms-Mcs-AdmPwdro   c                 S   s   g | ]
}|d ur
|nd‘qS )NzN/Ar   )r   Úelementr   r   r"   r#   æ   r)   z'GetLAPSPassword.run.<locals>.<listcomp>z-Skipping item, cannot process due to error %szNo LAPS data returned for %szNo LAPS data returned)ÚHostzLAPS UsernamezLAPS PasswordzLAPS Password ExpirationÚLAPSv2)-r   rJ   r]   rR   rT   rP   rG   rH   rI   rK   rL   rN   rY   Ú_dstHostrV   r   ÚSimplePagedResultsControlÚsearchr   ÚLDAPSearchErrorÚgetErrorStringÚfindrŽ   r˜   Ú
getAnswersr   r�   Ú
isinstanceÚSearchResultEntryr�   r³   r‹   ÚjsonÚloadsrˆ   r   Úfromtimestamprµ   ÚintÚstrftimerŒ   r1   r�   rA   rW   )r^   ÚldapConnectionr½   Úpaged_search_controlr®   r©   ÚentriesÚitemr»   ÚlapsPasswordExpirationÚlapsUsernameÚlapsPasswordÚlapsv2Ú	attributeÚ	plaintextÚrÚentryr   r   r"   Úrun¤   sŽ   6

ý
þ€û	

ÿ
"&€€
€€þ
ÿzGetLAPSPassword.runN)	Ú__name__Ú
__module__Ú__qualname__ÚstaticmethodrA   rd   r³   rµ   rã   r   r   r   r"   r   ,   s    
?
r   Ú__main__Tz Extract LAPS passwords from LDAP)Úadd_helpÚdescriptionÚtargetÚstorezdomain[/username[:password]])ÚactionÚhelpz	-computerÚcomputernamez&Target a specific computer by its name)rí   Úmetavarrî   z-tsÚ
store_truez&Adds timestamp to every logging outputz-debugzTurn DEBUG output ONz-outputfilez-ozOutputs to a file.Ú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 addresszoIP Address of the domain controller. If ommited it use the domain part (FQDN) specified in the target parameterz-dc-hostÚhostnamez|Hostname of the domain controller to use. If ommited, the domain part (FQDN) specified in the account parameter will be usedz-ldapsrX   zpEnable LDAPS (LDAP over SSL). Required when querying a Windows Server 2025domain controller with LDAPS enforced.)Údestrí   rî   rn   rB   zDomain should be specified!)PÚ
__future__r   r   r   r   Úimpacketr   Úimpacket.dcerpc.v5r   Úimpacket.dcerpc.v5.epmr   Úimpacket.dcerpc.v5.gkdir	   r
   r   Úimpacket.dcerpc.v5.rpcrtr   r   Úimpacket.dpapi_ngr   r   r   r   r   r   Úimpacket.examplesr   Úimpacket.examples.utilsr   r   Úimpacket.ldapr   r   Úpyasn1.codec.derr   Úpyasn1_modulesr   ÚargparserÒ   rŽ   Úsysr   rä   r3   ÚBANNERÚArgumentParserÚparserÚadd_argumentÚadd_argument_groupÚgroupr   ÚargvÚ
print_helpÚexitÚ
parse_argsrF   ÚinitÚtsr˜   rë   r[   Úno_passrM   rO   ra   r_   r`   r¡   ÚcriticalÚexecuterrã   r�   r©   Ú	getLoggerÚlevelÚDEBUGÚ	tracebackÚ	print_excr�   r�   r   r   r   r"   Ú<module>   st     
K



(


€üÌ