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re+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ZEeEF  W dS  eGy ZH ze'I jJe'jKkrod dlLZLeLM  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|rt|d0}dd	d t |D }	||	j| d
  | D ]}||	j| 	 d
  qkW d    d S 1 sw   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  }nt| 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rtd| j  d S td d S |D ]}t|tjdurqzd }d }	d }
d }d}|d D ]}t|d dkrt|d d
 }t|d dkrd}| t|d d
 }t !|d d "d}|d }
|d }qt|d dkst|d dkrt|d d
 dkrt#$| %t&t|d d
 'd}	qt|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 }~qd }~ww t|d
kr| jd urt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   iz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-kzUse 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



(


