o
    j                  
   @   s  d dl m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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 d d
lmZmZ d dlmZmZmZmZ d dl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ej'dkZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2G dd dZ3G dd de3Z4G dd dZ5e6dkriej7j8du re9dej7e_7e:ej; G d d! d!ej<Z=d"d# Z>ej?d$d%d&Z@e@jAd'd(d)d* e@jAd+d,d-d* e@jAd.d,d/d* e@jAd0d(d1d* e@Bd2ZCeCjAd3d(d4d5d6 e(re@jDd7d8d$d9ZEne@jDd7d8d:ZEeEjFd;d<d=ZGe(r eGjDd>d?d$d9ZHneGjDd>d?d:ZHeHjFd@dAd=ZIeIjAdBd,dCd* e@jAdDd,dEd* eHjFdFe=dGdHZJeJjAdIg dJdKdLdMdN eJjAdOd(eKdPdQdRdS e	rieJjAdTd(dUd* n	eJjAdTd(dUe>dV eJjAdWd(dXd* eJjAdYdZd[gdKdZd\dN eJjAd]d(d^d* eHjFd_e=d`dHZLeLjAdWd(dad* eLjAdbd(dcd* eLjAdIg dddKdLdedN eLjAdOd(eKdPdQdRdS eLjAdYdZd[gdKdZd\dN eLjAd]d(d^d* eHjFdfe=dgdHZMeMjAdIg dhdKdidjdN eMjAdOd(eKdkdldRdS eMjAdmd(eKdndodpdS eMjAdqd(eKdrd dsdS eMjAdYdZd[gdKdZd\dN eMjAd]d(d^d* eNejOdtkr+e@P  eQdt e@R ZSeTeSjUeSjV eeSjW\ZXZYZZZ[eXdu rGduZXeZdukraeYdukraeSj\du rad dvl]m]Z] e]dwZZeSj^dukrqe_dx eQdt eSj^du rzdueS_^ze5eXeYeZe[Z`e`aeS W dS  eby   e_dy Y dS  ecyh Zd zdzed Zeefee d{eev reSjgh dfkrefd| d}eev re`jijjjkd$kreSjgh dfkrefd| e#eev refd~ efd eSj^dukrefd nefd e%eev s e$eev reSj^dukrefd nefd e!eev refd e"eev s%e&eev r*efd e"eev s4e&eev rGe`jijjl ekrGeXdukrGefd e&eev sQe$eev r]emd W Y dZd[ddS W Y dZd[ddS dZd[dww dS )    )print_functionN)PY3)uuidversion)
AUTH_BASIC)logger)parse_target)parse_bitmask)	transportnspi)PR_CONTAINER_FLAGS_VALUESMAPI_PROPERTIES)
CP_TELETEXExchBinaryObjectget_guid_from_dnget_dn_from_guid) RPC_PROXY_REMOTE_NAME_NEEDED_ERRRPC_PROXY_HTTP_IN_DATA_401_ERRRPC_PROXY_CONN_A1_0X6BA_ERRRPC_PROXY_CONN_A1_404_ERRRPC_PROXY_RPC_OUT_DATA_404_ERRRPC_PROXY_CONN_A1_401_ERR)      i  6i 0l     l     l     0    z=======================c                   @   sf   e Zd Zdd Zdd Zdd Zd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
S )	Exchangerc                 C   sF   d| _ d| _d| _d| _d| _d| _d| _d | _d | _d | _	d | _
d S )N Fhex)	_username	_password_domain_lmhash_nthash_extended_output_output_type_stringbinding_rpctransport_Exchanger__outputFileName_Exchanger__outputFdself r.   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/../../../bin/exchanger.py__init__A   s   
zExchanger.__init__c                 C      t dNz,Virtual method. Not implemented in subclass!NotImplementedErrorr,   r.   r.   r/   conenct_mapiQ      zExchanger.conenct_mapic                 C   r1   r2   r3   r,   r.   r.   r/   connect_rpcT   r6   zExchanger.connect_rpcc                 C   r1   )NzNot Implemented!r3   r,   r.   r.   r/   load_autodiscoverW   s   zExchanger.load_autodiscoverr   Nc                 C   s@   || _ || _|| _d| _d| _|d ur|d\| _| _d S d S )Nr   :)r!   r"   r#   r$   r%   split)r-   usernamepassworddomainhashesr.   r.   r/   set_credentials]   s   zExchanger.set_credentialsc                 C   
   || _ d S N)r&   )r-   output_moder.   r.   r/   set_extended_outputg      
zExchanger.set_extended_outputc                 C   r@   rA   )r'   )r-   output_typer.   r.   r/   set_output_typej   rD   zExchanger.set_output_typec                 C   s   || _ t| j d| _d S )Nzw+)r*   openr+   )r-   filenamer.   r.   r/   set_output_filem   s   zExchanger.set_output_filec                 C   sB   | j d krtr| j |d  n| j |d d t| d S )N
zutf-8)r+   r   writeencodeprint)r-   textr.   r.   r/   rM   q   s
   
zExchanger.printc                 C   sX   t r| jdkrdtt|d S | jdkrdt| S t r'tt|dS t|S )Nr    z0x%sascii)r   r'   strbinasciihexlifybase64	b64encode)r-   bytestrr.   r.   r/   _encode_binaryy   s   

zExchanger._encode_binaryc                 C   s   | j d kr
| j   d | _ d S rA   )r+   closer,   r.   r.   r/   __del__   s   


zExchanger.__del__)r   r   r   N)__name__
__module____qualname__r0   r5   r7   r8   r?   rC   rF   rI   rM   rV   rX   r.   r.   r.   r/   r   @   s    


r   c                   @   s   e Zd ZegZg dZeg d ZdZdd Zd(ddZ	d	d
 Z
dd Zdd Zdd Zdd Zedd Zd)ddZdd Zd)ddZdd Zdg dddfd d!Zdg ddfd"d#Zd)d$d%Zg ddfd&d'ZdS )*NSPIAttacks)i  :i 9l   N  i@ 0i@ 0r   ):i :l     r   r   i  :i 9l     l     l    l      l     i 0l      i &:i *:i (:i ):i 	:i :i:i :i :i :i :i 
:i :i i  9l    z l    Z  l    \  l    ^  l    `  l    b  l    d  l    f  l    h  l    j  l    l  l     l     l     l     l     l   l l    > l    l   , l    l    j l    f l     l   v l    l    "  l    l    r   z#ncacn_http:%s[6004,RpcProxy=%s:443]c                 C   s>   t |  d | _i | _d| _t | _t | _	tj
| j	d< d S )NCodePage)r   r0   _NSPIAttacks__handlerhtableanyExistingContainerIDlistpropsr   STATstatr   r,   r.   r.   r/   r0      s   

zNSPIAttacks.__init__r   c                 C   s   | j ||f | _td| j  t| j| _| j| j| j	| j
| j| j | j | _| j| j| j	| j
| j| j tjrD| jt | jd | j  | jtj t| j| j}|d | _d S )NzStringBinding %s   contextHandle)DEFAULT_STRING_BINDINGr(   loggingdebugr
   DCERPCTransportFactoryr)   r?   r!   r"   r#   r$   r%   get_dce_rpc_NSPIAttacks__dceoptionsbasicset_auth_typer   set_auth_levelconnectbindr   MSRPC_UUID_NSPI	hNspiBindre   r_   )r-   
remoteNamerpcHostnamerespr.   r.   r/   r7      s"   
zNSPIAttacks.connect_rpcc                 C   s>   t  }t|d< t||d< t | j| j|}|d | _d S )Nr^   ContainerIDpStat)	r   rd   r   r\   _int_to_dwordhNspiUpdateStatrm   r_   re   )r-   	table_MIdre   rx   r.   r.   r/   update_stat  s
   zNSPIAttacks.update_statc                 C   s,   t | j| j}t |d }| | d S )NppRows)r   hNspiGetSpecialTablerm   r_   simplifyPropertyRowSet_parse_and_set_htable)r-   rx   
resp_simplr.   r.   r/   load_htable  s   zNSPIAttacks.load_htablec                 C   sB   | j D ]}| | | jd | j | d< | jd | j | d< qd S )N	TotalRecscount
CurrentRec	start_mid)r`   r~   re   r-   MIdr.   r.   r/   load_htable_stat  s
   

zNSPIAttacks.load_htable_statc                 C   sZ   | j dkrd S | ji kr|   | jD ]}| | | jd dkr*t|| _  d S qd S )Nr]   r   r   )ra   r`   r   r~   re   r\   r{   r   r.   r.   r/   load_htable_containerid%  s   



z#NSPIAttacks.load_htable_containeridc                 C   s   i | _ |D ]m}|t }i | j |< |t | j | d< |dkr%d| j d d< n|t | j | d< t|t | j | d< t|v rHt|t | j | d< t|v rV|t | j | d< nd| j | d< t|v rk|t | j | d< qd| j | d< qd S )	Nflagsr   zDefault Global Address Listnameguidparent_guiddepth	is_master)	r`   PR_EMS_AB_CONTAINERIDPR_CONTAINER_FLAGSPR_DISPLAY_NAMEr   
PR_ENTRYIDPR_EMS_AB_PARENT_ENTRYIDPR_DEPTHPR_EMS_AB_IS_MASTER)r-   r`   abr   r.   r.   r/   r   3  s$   
z!NSPIAttacks._parse_and_set_htablec                 C   s   | dkr| S | d d S )Nr   l        r.   )numberr.   r.   r/   r{   O  s   zNSPIAttacks._int_to_dwordNc           	      C   s  g }| j D ],}|d krd| j | vr|| q|d kr1d| j | v r1| j | d |kr1|| q|D ]}| j | }d|d< d|d  }td||d f  d|v r]td	||d f  |d
krst|d  }td||f  ntd|  |d d
krtd|  | jrt|}td|||f  d|v rt|d }|dkrtd|  ntd|||d f  t	t
|d }td||f  t  |d
kr| j|d d q4|d krQ| j D ]t}| j | d dkrPtd td| j | d   tdt| j | d    tdt| j | d    |d
k r#t|n|}td||f  t	t
| j | d }td|  | j | d d
krMtd|  t  qd S d S )Nr   Tprintedz    r   z%s%sr   r   z%sTotalRecs: %dr   r   z
%sGuid: %sz%sGuid: Noner   z'%sPR_EMS_AB_IS_MASTER attribute is set!z%sAssigned MId: 0x%.08X (%d)r      z:%sAssigned first record MId: 0x00000002 (MID_END_OF_TABLE)z)%sAssigned first record MId: 0x%.08X (%d)r   z%sFlags: %s)r   FzFound parentless object!zName: %szGuid: %szParent guid: %szAssigned MId: 0x%.08X (%d)z	Flags: %s)r`   appendrM   r   bin_to_stringlowerr&   r\   r{   r	   r   print_htable)	r-   r   
MIds_printr   r   indentr   dwordr   r.   r.   r/   r   V  sf   
(




  zNSPIAttacks.print_htablec                 C   s   t | j| j | j  d S rA   )r   hNspiUnbindrm   r_   
disconnectr,   r.   r.   r/   r     s   zNSPIAttacks.disconnectc              	   C   s   d}|D ]c}|d? }|d@ }|dkrq|dkrqd}|t v r9t | d }|d u r.t | d }|d u r8t | d	 }nd
| }| jrFd||f }t|| tr\| d|| || f  q| d||| f  q|dkrw|d kry| | d S d S d S )NT     
      F      rf   z0x%.8xz
%s, 0x%.8xz%s: %s)r   r&   
isinstancer   rM   rV   )r-   	row_simpl	delimiterempty
aulPropTag
PropertyIdPropertyTypeproperty_namer.   r.   r/   	print_row  s2   zNSPIAttacks.print_rowc                 C   s^   t | jdkr	d S t| j| j}|d d D ]}|d }|d@ }|dkr&q| j| qd S )Nr   	ppColumnsr   Datar   r   )lenrc   r   hNspiQueryColumnsrm   r_   r   )r-   rx   propPropertyTagr   r.   r.   r/   
load_props  s   zNSPIAttacks.load_props2   Fc              
   C   s  d}d}| j dkr|   |d kr|d krtd|d kr%|d kr%td|d kr9| | | jd tjkr8dS nd}|| jkrF| j}d}n$|| jkrO| j}n|g kre| j	g kr\| 
  | j	}tg}d}ntg}d}|rt| j}| j}d}	 |d krtj| j| j| j||d}	|	d | _z	t|	d }
W n ty } z|	  tt| td	d }~ww |rt|
d
krdS |
D ]	}d|vr dS qdS |r0|d krg }|
D ]	}||t  qn|}tj| j| j| j |||d}	z	t|	d }
W n ty } z|	  tt| tdd }~ww |r0t|
d
kr dS |
D ]}d|vr, dS q"dS |rK|
D ]}t|v rG|t }| | q5	 q5n|
D ]	}| |t qM|d kr^d S | jd tjkrid S t|
d
krrd S qu)NFr]   Wrong arguments!r   T)rz   Count	pPropTagsrz   r   #NspiQueryRows returned wrong resultr   l   
  )ry   r   r   lpETablezCNspiQueryRows returned wrong result while processing explicit table)ra   r   	Exceptionr~   re   r   MID_END_OF_TABLE
PROPS_GUIDPROPS_MINUMALrc   r   PR_INSTANCE_KEYhNspiQueryRowsrm   r_   r   dumpRawri   errorrP   r   r   PR_EMS_AB_OBJECT_GUIDrM   r   	DELIMITER)r-   r}   attrsr   eTable	onlyCheckprintOnlyGUIDsuseAsExplicitTablefirstReqPropsrx   	resp_rowserow	eTableInt
objectGuidr.   r.   r/   req_print_table_rows  s   









z NSPIAttacks.req_print_table_rowsc           
      C   s   |d kr|d krt d|d kr|d krt d|g kr(| jg kr%|   | j}|r;| |g|}|dkr9t dd S t|d}| }	 g }|dkrLn.t|D ]}	| }| }|dksd|d dkreqP|| qPt	|dkrrqD| ||t
 qE|  d S )Nr   r   z%Object with specified GUID not found!rTr   #)r   rc   r   _req_print_guidrG   readlinerangestripr   r   r   rW   )
r-   r   r   r   guidFileprintedLinesfdlineguidListir.   r.   r/   req_print_guid`  s<   

zNSPIAttacks.req_print_guidc           
   
   C   s   g }|D ]}| t|dd qtj| j| j||d}z|d d dkr'W dS t|d }W n tyJ } z|  t	
t| tdd }~ww |D ]}	| |	| qM|d d S )NT)minimize)r   paStrr   cRowsr   z'NspiResolveNamesW returned wrong result)r   r   r   hNspiResolveNamesWrm   r_   r   r   r   ri   r   rP   r   )
r-   r   r   r   legacyDNListr   rx   r   r   r   r.   r.   r/   r     s"   zNSPIAttacks._req_print_guidc                 C   s  |dks|dk s|dk s|dks|dkrt d||kr!|}d}n| }d}||7 }|}|| }		 |dkr<|	|kr<|}	n
|dk rF|	|k rF|}	| d||	| f  |rm| j|t||	|dd}
|
rl| j|t||	|d	 n| j|t||	|d	 |	|kr~d S ||7 }|	|7 }	q1)
Nr   l    r   r   r]   Tz# MIds %d-%d:)r   r   r   )r   r   )r   rM   r   r   )r-   	start_dntstop_dntr   r   checkIfEmptysteprstepdnt1dnt2existsr.   r.   r/   req_print_dnt  s6   (zNSPIAttacks.req_print_dnt)r   rA   )rY   rZ   r[   r   r   r   PROPS_EXTENDEDrh   r0   r7   r~   r   r   r   r   staticmethodr{   r   r   r   r   r   r   r   r   r.   r.   r.   r/   r\      s.    	R


A
% 
.r\   c                   @   sL   e 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S )ExchangerHelperc                 C   s"   || _ || _|| _|| _d | _d S rA   )_ExchangerHelper__domain_ExchangerHelper__username_ExchangerHelper__password_ExchangerHelper__remoteNameexch)r-   r=   r;   r<   rv   r.   r.   r/   r0     s
   
zExchangerHelper.__init__c                 C   sD   |j  }|j }|dkr| || | || d S td| )Nr   z%s module not found)moduler   	submodule
nspi_checknspi_runr   )r-   rn   r   r   r.   r.   r/   run  s   

zExchangerHelper.runc                 C   s   t  | _| j| j| j| j|j | j|j |dv r(|j	d kr(| j
|j	 | j| j|j |dkr;| | n|dkrE| | n|dkrO| | n	|dkrX| | | j  d S )N)dump-tables
guid-known
dnt-lookuplist-tablesr  r  r  )r\   r   r?   r   r   r   r>   rC   rj   output_filerI   r7   r   rpc_hostnamenspi_list_tablesnspi_dump_tablesnspi_guid_knownnspi_dnt_lookupr   r-   r   rn   r.   r.   r/   r     s   
zExchangerHelper.nspi_runc                 C   s   |dkr|j d kr|jd krt  td |dkr/|j d kr/|jd kr/td td |dkrF|jd krF|jd krFt	  td |dkr`|jd krb|jd krdtd td d S d S d S d S )Nr  r   z"Specify only one of -name or -guidr  z'Specify only one of -guid or -guid-file)
r   r   dump_tables
print_helpsysexitri   r   	guid_file
guid_knownr  r.   r.   r/   r     s   




zExchangerHelper.nspi_checkc                 C   s(   | j   |jr| j   | j   d S rA   )r   r   r   r   r   )r-   rn   r.   r.   r/   r    s   

z ExchangerHelper.nspi_list_tablesc                 C   s  | j |j |jd ks|jdkrtj}n|jdkrtj}n|jdkr'tj}ng }|jd kr=|j	 dv r=t
d d}n| j   |jd krXt
d|j  t|j}d }nd }|j}d}| j jD ]Z}|dkrjqc|d ur| j j| d |krt
d	||jf  t
d
| j j| d   |} n+qc| j j| d |krt| j j| d }t
d	||f  t
d|  |} nqc|dkrt
d td | j |||j d S )NMINIMALEXTENDEDGUIDS)galzdefault global address listzglobal address listzLookuping Global Address Listr   z/Search for an address book with objectGUID = %sr   z MId %d is assigned for %s objectzLookuping %sr   z+Lookuping address book with objectGUID = %sz!Specified address book not found!r   )r   rF   rE   lookup_typer\   r   r   r   r   r   ri   infor   r   r   string_to_binr`   rj   r   r   r  r  r   rows_per_request)r-   rn   propTagsr}   r   r   r   r.   r.   r/   r    sP   






z ExchangerHelper.nspi_dump_tablesc                 C   sx   | j |j |jd ks|jdkrtj}n|jdkrtj}ng }|jd kr/| j |j| d S | j j||j	|j
d d S )Nr  r  )r   r   r   )r   rF   rE   r  r\   r   r   r   r   r  r  r-   rn   r  r.   r.   r/   r	  R  s   

zExchangerHelper.nspi_guid_knownc                 C   sR   |j d ks
|j dkrtj}n|j dkrtj}ng }| jj|j|j||jdd d S )Nr  r  T)r   r   r   )	r  r\   r   r   r   r   r   r   r  r  r.   r.   r/   r
  b  s   

zExchangerHelper.nspi_dnt_lookupN)rY   rZ   r[   r0   r   r   r   r  r  r	  r
  r.   r.   r.   r/   r     s    >r   __main__utf8c                   @   s   e Zd Zdd ZdS )SmartFormatterc                 C   s*   | dr|dd   S tj| ||S )NzR|r   )
startswith
splitlinesargparseHelpFormatter_split_lines)r-   rN   widthr.   r.   r/   r#  x  s   
zSmartFormatter._split_linesN)rY   rZ   r[   r#  r.   r.   r.   r/   r  w  s    r  c                 C   s   |  t }|S rA   )decoder  getfilesystemencoding)
bytestringunicode_stringr.   r.   r/   localized_arg~  s   r)  Tz!A tool to abuse Exchange services)add_helpdescriptiontargetstorez6[[domain/]username[:password]@]<targetName or address>)actionhelpz-debug
store_truez!Turn DEBUG and EXTENDED output ONz-tsz&Adds timestamp to every logging outputz-rpc-hostnamezoA name of the server in GUID (preferred) or NetBIOS name format (see description in the beggining of this file)authenticationz-hasheszLMHASH:NTHASHz$NTLM hashes, format is LMHASH:NTHASH)r.  metavarr/  zA module namer   )r/  destrequired)r/  r3  r   zAttack NSPI interface)r/  zA submodule namer   r  zList Address Booksz-countz-Request total number of records in each tablez-basicz,Authenticate with Basic Auth instead of NTLMr  zDump Address Books)formatter_classr/  z-lookup-type)r  r  FULLr  ?r  zR|Lookup type:
  MINIMAL  - Request limited set of fields (default)
  EXTENDED - Request extended set of fields
  FULL     - Request all fields for each row
  GUIDS    - Request only GUIDs)choicesnargsdefaultr/  z-rows-per-request50r   z$Limit the number of rows per request)r.  typer2  r:  r/  z-namez-Dump table with the specified name (inc. GAL))r.  r/  r<  z-guidz"Dump table with the specified GUIDz-output-typer    rS   z Output format for binary objectsz-output-filezOutput filenamer  z1Retrieve Active Directory objects by GUID / GUIDsz#Dump object with the specified GUIDz
-guid-filez"Dump objects using GUIDs from file)r  r  r6  zR|Lookup type:
  MINIMAL  - Request limited set of fields (default)
  EXTENDED - Request extended set of fields
  FULL     - Request all fields for each rowr  zLookup Distinguished Name Tags)r  r6  r  r  zR|Lookup type:
  EXTENDED - Request extended set of fields (default)
  FULL     - Request all fields for each row
  GUIDS    - Request only GUIDs350i^  z
-start-dnt500000i  zA DNT to start fromz	-stop-dnt0zA DNT to lookup tor   r   )getpassz	Password:z-rpc-hostname cannot be emptyKeyboardInterruptzProtocol failed: %sr   a  Most likely ntdsai.dll in lsass.exe has crashed on a Domain Controller while processing a DNT which does not support to be requested via MS-NSPI. The DC is probably rebooting. This can happend in Multi-Tenant Environment. You can try to request different DNT rangezConnection reset by peerzTThis usually means the target has no ACL to connect to this endpoint using RPC ProxyzIs the server a MS Exchange?zLTry to specify -rpc-hostname (see description in the beggining of this file)zYTry to specify different -rpc-hostname, or enumerate endpoints via rpcmap.py / rpcdump.pyzqCannot determine the right RPC Server name. Specify -rpc-hostname (see description in the beggining of this file)zMThe specified RPC Server is incorrect. Try to specify different -rpc-hostnamezESpecify -rpc-hostname (see description in the beggining of this file)zWrong credentials!zlThe server requested Basic authentication which may require you to specify the domain. Your domain is empty!zBA proxy in front of the target server detected (may be WAF / SIEM))n
__future__r   rS   codecsri   r!  rQ   r  sixr   impacketr   r   impacket.httpr   impacket.examplesr   impacket.examples.utilsr   impacket.structurer	   impacket.dcerpc.v5r
   r   impacket.mapi_constantsr   r   impacket.dcerpc.v5.nspir   r   r   r   impacket.dcerpc.v5.rpchr   r   r   r   r   r   version_infoPY37ORHIGHERr   r   r   r   r   r   r   r   r   r   r   r\   r   rY   stdoutencoding	getwriterrM   BANNERr"  r  r)  ArgumentParserparseradd_argumentadd_argument_groupgroupadd_subparsers
subparsers
add_parsernspi_parsernspi_attackslist_tablesr  intr  
dnt_lookupr   argvr  r  
parse_argsrn   inittsrj   r,  r=   r;   r<   rv   r>   r@  r  r   
exchHelperr   rA  r   r   
error_textcriticalr   r   r   r)   rts_ping_receivedget_auth_typer  r.   r.   r.   r/   <module>   sJ   
H    N 





 







	











 