o
    j                     @   sN  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	T 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 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m Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(T d dl)T d dl*T d dl+T d dl,T d dl-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7T d dl8m9Z9 d dl8m:Z: d dl;m<Z<m=Z=m>Z> d dl?m@Z@ d dlAmBZB d dlCmDZE d dlCmFZG d dlHmIZI G dd de jJZKG dd dZLG dd  d ZMG d!d" d"ZNG d#d$ d$ZOd%d& ZPeQd'kr%d d(lRmSZS eTd) d*ZUeSVeUZWeXePeW dS dS )+    N)	Coroutine)logger)*)NetBIOSPacketizer)
SMBCommand)NTStatus)	SMBHeaderSMBHeaderFlags2Enum)
SMBMessage)SMBSecurityMode)SMB_COM_NEGOTIATE_REQ)SMB2MessageSMB2TransformSMB2Compression)
SMB2ContextType SMB2PreauthIntegrityCapabilitiesSMB2HashAlgorithm
SMB2CipherSMB2CompressionTypeSMB2CompressionFlagsSMB2EncryptionCapabilitiesSMB2CompressionCapabilitiesSMB2SigningAlgorithmSMB2SigningCapabilities)FileInfoClass) FileFullDirectoryInformationList)FileAttributes)SECURITY_DESCRIPTOR)SE_OBJECT_TYPE)hmac)hashlib)AESMODE_CCMMODE_GCM)AES_CMAC)KDF_CounterMode)compress)
decompress)	UniClientc                   @   s   e Zd ZdZdZdZdZdS )SMBConnectionStatusNEGOTIATINGSESSIONSETUPRUNNINGCLOSEDN)__name__
__module____qualname__r*   r+   r,   r-    r1   r1   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/aiosmb/connection.pyr)   -   s
    r)   c                   @       e Zd Zdd Zedd ZdS )	TreeEntryc                 C   s:   d | _ d | _d | _d | _d | _d | _d | _d | _d | _d S N)	
share_nametree_id
session_idnumber_of_usersis_DFSis_CAis_scaleoutencryptmaximal_accessselfr1   r1   r2   __init__4   s   
zTreeEntry.__init__c                 C   st   t  }||_| jj|_| jj|_d|_tj	| j
jv |_tj| j
jv |_tj| j
jv |_tj| j
jv |_| j
j|_|S N   )r4   r6   headerTreeIdr7   	SessionIdr8   r9   TreeCapabilitiesSMB2_SHARE_CAP_DFScommandCapabilitiesr:   &SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITYr;   SMB2_SHARE_CAP_SCALEOUTr<   
ShareFlagsSMB2_SHAREFLAG_ENCRYPT_DATAr=   MaximalAccessr>   )replyr6   ter1   r1   r2   from_tree_reply?   s   


zTreeEntry.from_tree_replyN)r.   r/   r0   rA   staticmethodrR   r1   r1   r1   r2   r4   3   s    r4   c                   @   r3   )
FileHandlec                 C   s:   d | _ d | _d | _d | _d | _d | _d | _td| _	d S rB   )
file_idr7   oplock_level
is_durableis_resilientlast_disconnect_time	file_nameasyncio	Semaphoreoplockr?   r1   r1   r2   rA   N   s   zFileHandle.__init__c                 C   s8   t  }| jj|_||_||_d|_d|_d|_||_	|S )NFr   )
rT   rI   FileIdrU   r7   rV   rW   rX   rY   rZ   )rP   r7   rZ   rV   fhr1   r1   r2   from_create_replyX   s   
zFileHandle.from_create_replyN)r.   r/   r0   rA   rS   r`   r1   r1   r1   r2   rT   M   s    
rT   c                   @   s>   e Zd ZdddZdd Zdd Zd	d
 Zdd Zdd ZdS )SMBPendingMsg  d   c                 C   s(   || _ || _|| _|| _|| _d | _d S r5   )
message_idmax_renewaltimeoutOutstandingResponsesOutstandingResponsesEventpending_task)r@   rd   rg   rh   rf   re   r1   r1   r2   rA   e   s   
zSMBPendingMsg.__init__c                    s(   t dI d H  | t I d H  d S )Nrb   )r[   sleep_SMBPendingMsg__destroy_messageSMBPendingTimeoutr?   r1   r1   r2   __pending_waiterm   s   zSMBPendingMsg.__pending_waiterc                    s2   d |f| j | j< | j| jv r| j| j   d S r5   )rg   rd   rh   set)r@   problemr1   r1   r2   __destroy_messageq   s
   zSMBPendingMsg.__destroy_messagec                    s^   | j d ur| j   | jd ur%|  jd8  _| jdkr%| t I d H  t|  | _ d S )NrC   r   )ri   cancelre   rk   SMBPendingMaxRenewalr[   create_task_SMBPendingMsg__pending_waiterr?   r1   r1   r2   updatew   s   



zSMBPendingMsg.updatec                    s   t |  | _d S r5   )r[   rs   rt   ri   r?   r1   r1   r2   run   s   zSMBPendingMsg.runc                    s   | j d ur| j   d S d S r5   )ri   rq   r?   r1   r1   r2   stop   s   
zSMBPendingMsg.stopN)rb   rc   )	r.   r/   r0   rA   rt   rk   ru   rv   rw   r1   r1   r1   r2   ra   d   s    
ra   c                   @   s  e Zd ZdZdXdededef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efd d!ZdYd"d#ZdYd$d%Zd&eeeef fd'd(Zd)efd*d+Zded&efd,d-Zd&efd.d/ZdZd)efd1d2Zd3e fd4d5Z!e"j#e$j%d0dfd6e&d7e"fd8d9Z'd[d;d<Z(d\d=d>Z)e*j+e,j-d:d:d?fd@dAZ.dBd:e,j/d0d:fdCdDZ0d0e1j2dEfdFdGZ3e4j5fdHdIZ6dJdK Z7dLdM Z8dNdO Z9dPdQ Z:dRdS Z;dTdU Z<dVdW Z=d0S )]SMBConnectionzr
	Connection class for network connectivity and SMB messages management (sending/recieveing/singing/encrypting).
	TFtargetpreserve_gssapinosignc                 C   s  || _ || _d | _|du rt|| _|| _| jj| _d | _d | _	d | _
d | _d | _d| _d | _d| _d| _d | _d | _d| _d| _tj| _i | _i | _i | _i | _i | _i | _i | _i | _d| _ | jj!d urk| jj!nd| _!| jj"d urx| jj"nd| _"| jj#d ur| jj#nd| _#d | _$d| _%d | _&t'( | _)d| _*d| _+d| _,d| _-d| _.d| _/d| _0d| _1t2j3| _4|du rt2j5t2j6B | _4d| _7d| _8d | _9d | _:d | _;d | _<d | _=d| _>t?j@| _Ad| _Bd | _Cd | _Dd | _E	 tFjGg| _Ed| _HtIjJg| _Kd | _LtMjN| _Od| _Pd S )NT   Fr   i   s@                                                                   )Qr{   gssapioriginal_gssapicopydeepcopyry   preferred_dialectssupported_dialectssettingsnetwork_connectionnetbios_transportincoming_taskkeepalive_taskkeepalive_timeoutconnection_closed_evtlogin_oksupress_keepaliveactivity_atselected_dialectsigning_requiredencryption_requiredr)   r*   statusrh   OutstandingRequestsrg   pending_tablemessageIdToOplockTreeConnectTable_idTreeConnectTable_shareFileHandleTableSequenceWindowMaxTransactSizeMaxReadSizeMaxWriteSize
ServerGuidRequireSigning
ServerNameGUIDrandom
ClientGUIDSupportsFileLeasingSupportsMultiCreditSupportsDirectoryLeasingSupportsMultiChannelSupportsPersistentHandlesSupportsEncryptionClientCapabilitiesServerCapabilitiesNegotiateSecurityModeNONEClientSecurityModeSMB2_NEGOTIATE_SIGNING_ENABLEDSMB2_NEGOTIATE_SIGNING_REQUIREDServerSecurityModerF   
SessionKey
SigningKeyApplicationKeyEncryptionKeyDecryptionKeyCompressAllRequestsr   SHA_512PreauthIntegrityHashIdPreauthIntegrityHashValueCompressionIdCipherIdCompressionIdsr   LZNT1SupportsChainedCompressionr   AES_128_CCMsupported_encryptionssupported_signaturesr    sha512preauth_ctxsession_closed)r@   r}   ry   rz   r{   r1   r1   r2   rA      s   




zSMBConnection.__init__c                    s   | S r5   r1   r?   r1   r1   r2   
__aenter__   s   zSMBConnection.__aenter__c                    s   t j|  ddI d H  d S )N   rf   )r[   wait_for	terminate)r@   exc_typeexc	tracebackr1   r1   r2   	__aexit__   s   zSMBConnection.__aexit__c                 C   s"   | j tjtjtjfv r| jS | jS r5   )r   NegotiateDialectsSMB300SMB302SMB311r   r   r?   r1   r1   r2   get_session_key   s   zSMBConnection.get_session_keyc                 C   s^   z| j  }|d ur| }W n
   t  d }Y | jd ur-|tj| jv tj| jv dS d S )N)	ntlm_datasigning_enabledr   )	r}   get_extra_infoto_dictr   	print_excr   r   r   r   )r@   r   r1   r1   r2   r     s   



zSMBConnection.get_extra_infoc                    s  z̐zd| j  2 zZ3 dH W }tj | _|du r*t| jdur'| j d|d dk r8td|d  |d dkrt	
|}|jjtjkrht| jt|jjdd dd	}||j|d
d |jj}n+|jjtjkrt| jt|jjdd }||j|d
d |jj}ntd|jj |d dkrt
|}|jjtjkr|jj| jkrtd |jjt j!kr|jd|jj" }|t#|j|jj"d 7 }|}ntd|jjj$ td|d dkrt%
|}|d dkrt&
|}|jj't(j)kr0|jj*| j+v r| j+|jj* ,  t-|jj*| j.| j/| jj0| jj1d| j2|jj*< | j2|jj* 3 I dH  q
|jj*| j2v rJ| j2|jj* 4 I dH  | j2|jj*= ||f| j.|jj*< |jj*| j/v re| j/|jj* 5  q
q
6 W n< t6j7y   Y W tdtd  | j/D ]}dtdf| j.|< | j/| 5  q| 8 I dH  dS    t9d Y W tdtd  | j/D ]}dtdf| j.|< | j/| 5  q| 8 I dH  dS tdtd  | j/D ]}dtdf| j.|< | j/| 5  q| 8 I dH  w )z
		Waits from SMB message bytes from the transport in_queue, and fills the connection table.
		This function started automatically when calling connect.
		Pls don't touch it.
		NzUnknown targetr      zUnknown SMB packet type %s         segment_size   4      z7Common encryption algo is %s but it is not implemented!zFServer is using a different compression algo than whats agreed upon...z5Server used %s compression, but it is not implementedz=Server sent chained compression, but its not implemented here      )rf   re   z1__handle_smb_in got error from transport layer %szConnection closed__handle_smb_in):r   readdatetimeutcnowr   SMBConnectionTerminatedry   get_hostname_or_ip	Exceptionr   
from_bytesrD   EncryptionAlgorithmr   r   r!   r   r"   Noncedecryptdata	SignatureAES_128_GCMr#   r   Flagsr   r   CompressionAlgorithmr   r   debugr   r   Offsetlznt1_decompressnamer   r
   Statusr   PENDING	MessageIdr   releasera   rg   rh   PendingTimeoutPendingMaxRenewalr   rv   rw   rn   r[   CancelledErrorr   	exception)r@   msg_datamsgctxuncompressed_datamidr1   r1   r2   r     s   




,H


zSMBConnection.__handle_smb_inc              
      s   z;|   I dH \}}|dur||  I dH \}}|dur ||  I dH \}}|dur/|t|  | _d| _W dS  tyY } z| 	 I dH  d|fW  Y d}~S d}~ww )a  
		This is the normal starting function.
		Performs establishment of the TCP connection, then the negotiation and finally the session setup.
		If this function returns without an exception, then I'm happy.
		Also it means that you have a working and active session to the server.
		NTTNF)
connect	negotiatesession_setupr[   rs   	keepaliver   r   r   
disconnectr@   _errer1   r1   r2   logint  s&   zSMBConnection.loginc              
      s   zhzId| j jvrtd|  I d H \}}|d ur||  I d H \}}|d ur+|| jddI d H \}}|d ur<|| j  d fW W |  I d H  S  tyi } zd |fW  Y d }~W |  I d H  S d }~ww |  I d H  w )Nz2NTLMSSP - Microsoft NTLM Security Support Providerz6Fake authentication is only supported via NTLM packageT)	fake_auth)r}   authentication_contextsr   r  r  r  r   r  r  r1   r1   r2   
fake_login  s*   zSMBConnection.fake_loginc           	   
      s  zz_|| _ |  I dH \}}|dur|d}d}| jddI dH \}}}t|tr9tj|jjv }tj	|jjv }nt|t
rLtj|jjv }tj|jjv }|durR|||||dfW W |  I dH  S  ty } zdddd|fW  Y d}~W |  I dH  S d}~ww |  I dH  w )z
		Checks if the remote end supports a given protocol.
		On success it returns True and the reply from the server (for checking SMB3 capabilities)
		NT)protocol_testF)r   r  r  
isinstancer   r   r   rI   SecurityModer   r
   r   %NEGOTIATE_SECURITY_SIGNATURES_ENABLED&NEGOTIATE_SECURITY_SIGNATURES_REQUIREDr  r   )	r@   protocolr	  r
  sign_ensign_reqresrplyr  r1   r1   r2   r    s2   

zSMBConnection.protocol_testc              
      s   z#t  | _t| j}t| j|}| I dH | _t 	| 
 | _W dS  tyA } z|  I dH  d|fW  Y d}~S d}~ww )zh
		Establishes socket connection to the remote endpoint. Also starts the internal reading procedures.
		Nr  F)r[   Eventr   r   r   r(   ry   r  r   rs   _SMBConnection__handle_smb_inr   r   r  )r@   
packetizerclientr  r1   r1   r2   r    s   

zSMBConnection.connectc                    st   | j tjkr	dS tj| _ | jdur| j  | jdur,| j I dH  tdI dH  | j	dur8| j	  dS dS )z
		Tears down the socket connecting as well as the reading cycle.
		Doesn't do any cleanup! 
		For proper cleanup call the terminate function.
		Nr   )
r   r)   r-   r   rq   r   closer[   rj   r   r?   r1   r1   r2   r    s   



zSMBConnection.disconnectc              
      s   zAd}| j jdk rW dS | j jdkrt| j jd |}	 t|I dH  tj | j j|krB| j	du rBtj
|  | jdI dH  q tjyM   Y dS  tyk } ztd |  I dH  W Y d}~dS d}~ww )	zR
		Sends an echo message every X seconds to the server to keep the channel open
		
   r   NrC   TFr   z/Keepalive failed! Server probably disconnected!)ry   rf   maxr[   rj   r   r   r   secondsr   r   echor   r   r   r   r   r  )r@   
sleep_timer  r1   r1   r2   r    s&    
zSMBConnection.keepaliver   c                 C   s&   t  }|| j|  | | _d S r5   )r    r   ru   r   digest)r@   r   r   r1   r1   r2   update_integrity  s   zSMBConnection.update_integrityc              
      sb  zd}t j| jv rt }tj|_tj|_	d|_
tj|_t }|du r)dg|_nddg|_t||}| |I dH \}}|durC|| |I dH \}}}|durT|t|trs|du ro|jjdkrid|dfW S d|dfW S td	|jj	tjkr~td
| jt j= t }| j|_d|_| j|_dd | jD |_tdd | jD rtj |_t j!| jv r|j"#t$%| j&g | j'dur| jtj O  _|j"#t()| j' | j*dur|j"#t+)| j* | j,dur|j"#t-.| j,| j/ t0 }t1j2|_d|_3t4||}| |I dH \}}|dur|| |I dH \}}}|dur"|t|tr,td	| 5| |jj	tjkrQ|jj	tj6krItd|jj	 td|jj	 |jj7| jvr\t8 |jj7| _9|jj| _:t;j<|jjv | _=| j>du rwd| _=tj |jjv rd| _?t@jA| _B|jj"D ] }	|	jCtDjEkrd| _?|	jFd | _B|	jCtDjGkr|	jHd | _IqtJKdd| j9  tL| jM|jjM| _MtL| jN|jjN| _NtL| jO|jjO| _O|jjP| _PtjQ|jjv | _RtjS|jjv | _TtjU|jjv | _V|jj| _W|jj| _XtYjZ| _[| jN| j\j]_^|du rd|dfW S W dS  ty0 }
 z|du r"W Y d}
~
dS d|
fW  Y d}
~
S d}
~
ww )zj
		Initiates protocol negotiation.
		First we send an SMB_COM_NEGOTIATE_REQ with our supported dialects
		Nr   Tz
NT LM 0.12z	SMB 2.???z	SMB 2.002  Fz7Server replied with SMBv1 message, doesnt support SMBv2z<SMB2 negotiate error! Server replied with error status code!c                 S   s   g | ]}|qS r1   r1   .0dialectr1   r1   r2   
<listcomp>2  s    z+SMBConnection.negotiate.<locals>.<listcomp>c                 s   s    | ]}|t v V  qd S r5   )SMB2_NEGOTIATE_DIALTECTS_3r'  r1   r1   r2   	<genexpr>6  s    z*SMBConnection.negotiate.<locals>.<genexpr>zDnegotiate_1 dialect probably not suppported by the server. reply: %sznegotiate_1 reply: %srC   zServer selected dialect: %sr  )FNN)_r   WILDCARDr   r   r   SMB_COM_NEGOTIATECommandr   SUCCESSr   r   r	   SMB_FLAGS2_UNICODEFlags2r   Dialectsr
   sendSMBrecvSMBr  rI   DialectIndexr   rD   NEGOTIATE_REQr   r  rJ   r   
ClientGuidallNegotiateCapabilities
ENCRYPTIONr   NegotiateContextListappendr   	constructr   r   r   from_enc_listr   r   r   r   from_comp_listr   SMB2Header_SYNCSMB2Command	NEGOTIATE	CreditReqr   r%  NOT_SUPPORTEDDialectRevisionSMBUnsupportedDialectSelectedr   r   r   r   r   r{   r   r   r   r   ContextTyper   ENCRYPTION_CAPABILITIESCiphersCOMPRESSION_CAPABILITIESCompressionAlgorithmsr   r   logminr   r   r   r   MULTI_CHANNELr   LEASINGr   	LARGE_MTUr   r   r   r)   r+   r   r   r  buffer_size)r@   r  r  rD   rI   r   rd   r
  	rply_datanegctxr  r1   r1   r2   r    s   


















zSMBConnection.negotiatec              
      sF  zd }t j}d}|t jkr|dkrt }z1| jj|| j | jdI d H \|_}}|d ur1||dkrF| jjd urF| jjj	d urFW W dS W n t
yd } zt|ddkr^tt||d }~ww d|_tj|_| jdu rutj|_d|_d|_d|_t }	tj|	_d|	_t|	|}
| |
I d H \}}|d ur|| |I d H \}}}|d ur|| jdkr|j j| _|j j!t j"t jfvrn!|j j!t j"kr| #| |j$j}|j j!}|d8 }|t jkr|dks|j j!t j"kr| jj|| j d	I d H \|_}}|d ur|| j% du rd
| _&| j' d d | _(| j&r~| j)t*j+t*j,t*j-fv r~| j)t*j-krZt.| j(d| j/d| _0t.| j(d| j/d| _1t.| j(d| j/d| _2t.| j(d| j/d| _3n$t.| j(ddd| _0t.| j(ddd| _1t.| j(ddd| _2t.| j(ddd| _3t4j5| _6W dS t7d|j j! t
y } z
d
|fW  Y d }~S d }~ww )Nr   r   )spnry   Tr  PreauthrC   )rU  Fr   s   SMBSigningKey    s
   SMBAppKey s   SMBC2SCipherKey s   SMBS2CCipherKey s   SMB2AESCMAC s   SmbSign s   SMB2APP s   SmbRpc s   SMB2AESCCM s
   ServerIn  s
   ServerOut z.session_setup (authentication probably failed))8r   MORE_PROCESSING_REQUIREDSESSION_SETUP_REQr}   authenticatery   to_target_stringBufferselected_authentication_contextntlmChallenger   strfindSMBKerberosPreauthFailedr   r   r   r  r{   r   rJ   ChannelPreviousSessionIdrA  rB  SESSION_SETUPr/  rD  r
   r4  r5  rF   rD   r   r0  r%  rI   is_guestr   r   r   r   r   r   r   r   r%   r   r   r   r   r   r)   r,   r   SMBException)r@   r  authdatar   maxiterrI   r  r
  r  rD   r   rd   r  rS  r1   r1   r2   r    s   (	




4$
 zSMBConnection.session_setupreturnc              
      s   zR|| j vr| j|  I dH  | j |\}}|du r|| jtjkr6| jtj	kr6|  j
|jjd 7  _
|jjtjkrG|| jv rF| j|= n| j|   ||dfW S  tyj } zdd|fW  Y d}~S d}~ww )zo
		Returns an SMB message from the outstandingresponse dict, OR waits until the expected message_id appears.
		NrC   )rg   rh   waitpopr   r)   r*   r   r   SMB202r   rD   CreditCharger   r   r   clearr   )r@   rd   r   r   r  r1   r1   r2   r5    s(   

zSMBConnection.recvSMBr   c                 C   s   | j tjtjfv r.| jr,|jjtjA |j_t	
| j| tj }|d d |j_d S d S | jrD| }t| j|t|}||j_d S d S )Nr   )r   r   rm  SMB210r   rD   r   SMB2HeaderFlagSMB2_FLAGS_SIGNEDr   newto_bytesr    sha256r$  r   r   r$   len)r@   r   r$  r   	signaturer1   r1   r2   sign_message!  s   zSMBConnection.sign_messagec                 C   s   | j tjkr9td}t }|d |_t||_| j |_	| j
|_
t| jt|dd}||| dd \}|_n6| j tjkrotd}t }|d |_t||_| j |_	| j
|_
t| jt|}||| dd \}|_t||S )	Nr   s        r   r   r   r   r   s       )r   r   r   osurandomSMB2Header_TRANSFORMr   rv  OriginalMessageSizer   rF   r!   r   r"   r=   rt  r   r   r#   r   )r@   r   noncehdrr   enc_datar1   r1   r2   encrypt_message5  s&   


 



zSMBConnection.encrypt_messagec                 C   s   |  }| jdu r<| jtjkr|}n| jtjkrt|}ntd| j t }t	||_
| j|_tj|_d|_t||S td)NFz6Common compression type is %s but its not implemented!r   z$Chained compression not implemented!)rt  r   r   r   r   r   lznt1_compressr    SMB2Header_COMPRESSION_TRANSFORMrv  OriginalCompressedSegmentSizer   r   r   r   r   )r@   r   r   compressed_datacomp_hdrr1   r1   r2   compress_message_  s   



zSMBConnection.compress_messageNc              
      s  zt j  | _| jtjkrRt|trd}|  jd7  _nd|j	_
d|j	_| j|j	_| j}|  jd7  _| |  t | j|< | j| I dH  |dfW S |j	jtjure| j|j	_|  jd7  _| j|j	_|j	j
srd|j	_
| jtjkr|d|j	_|j	j}|dur|j| j|< | jdur| jdur| |}| jdu r| | | j du r| jdur| !| }n| |  t | j|< | j| I dH  |dfW S  t"y } z
d|fW  Y d}~S d}~ww )zp
		Sends an SMB message to teh remote endpoint.
		msg: SMB2Message or SMBMessage
		Returns: MessageId integer
		r   rC   N   T)#r   r   r   r   r)   r*   r  r
   r   rD   rn  rD  r   r%  rt  r[   r  rh   r   writer/  rB  CANCELrF   r+   r]   r   r   r   r  r   rx  r   r  r   )r@   r   r_   rd   r  r1   r1   r2   r4  t  sR   








zSMBConnection.sendSMBr6   c              
      sF  z| j dks| jtjkrt |du rtdt }||_d|_t	 }t
j|_t||}| |I dH \}}|dur=|| |I dH \}}}|durN||jjtjkrlt||}	|	| j|jj< |	| j|< |	dfW S |jjtjkrvt |jjtjkrd| _ tdtjtd|jj ty }
 z
d|
fW  Y d}
~
S d}
~
ww )ze
		share_name MUST be in "\\server\share" format! Server can be NetBIOS name OR IP4 OR IP6 OR FQDN
		TNzShare name is None!r   zsession delted )r   r   r)   r-   r   r   TREE_CONNECT_REQPathr   rA  rB  TREE_CONNECTr/  r
   r4  r5  rD   r   r   r0  r4   rR   r   rE   r   BAD_NETWORK_NAMESMBIncorrectShareNameUSER_SESSION_DELETEDrg  )r@   r6   rI   rD   r   rd   r
  r  r	  rQ   r  r1   r1   r2   tree_connect  sB   


zSMBConnection.tree_connect
file_attrsimpresonation_levelc              
      s  z| j dks| jtjkrt || jvrtd| t }|	|_||_	||_
||_||_||_||_||_|
|_t }tj|_||_t||}| |I d H \}}|d urX|| |I d H \}}}|d uri||jjtjkrt||||	}|| j|j < |dkr|j!j"|j!d fW S |j!j"d fW S |jjtj#krt$d|jjj% |jjt$d|jjj% |jj ty } z|dkrd d |fW  Y d }~S d |fW  Y d }~S d }~ww )NTUnknown Tree ID! %s%s)&r   r   r)   r-   r   r   r   
CREATE_REQRequestedOplockLevelImpersonationLevelDesiredAccessr   ShareAccessCreateDispositionCreateOptionsNameCreateContextrA  rB  CREATEr/  rE   r
   r4  r5  rD   r   r   r0  rT   r`   r   rU   rI   r^   ACCESS_DENIEDrg  r   )r@   r7   	file_pathdesired_access
share_modecreate_optionscreate_dispositionr  r  rV   create_contextsreturn_replyrI   rD   r   rd   r
  r  r	  r_   r  r1   r1   r2   create  sR   

zSMBConnection.creater   c              
      s  z| j dks| jtjkrt || jvrtd| || jvr&td| | j| j4 I dH  t	 }t
j|_||_| jtjkrP| jdkrPd|d d  |_ntd|}t }||_||_||_d|_d|_t||}| j|| j| dI dH \}}	|	dur|	| |I dH \}
}}	|	dur|	|
jjtj kr|
j!j"|
j!j#dfW  d  I dH  W S |
jjtj$kr	 W d  I dH  W d	S |
jjtj%kr|
j!j"ddfW  d  I dH  W S t&d
|
jj1 I dH sw   Y  W dS  ty } zdd|fW  Y d}~S d}~ww )a  
		Will issue one read command only then waits for reply. To read a whole file you must use a filereader logic! 
		returns the data bytes and the remaining data length
		
		IMPORTANT: remaning data length is dependent on the length of the requested chunk (length param) not on the actual file length.
		to get the remaining length for the actual file you must set the length parameter to the correct file size!
		
		If and EOF happens the function returns an empty byte array and the remaining data is set to 0
		Tr  Unknown File ID! %sNrC      r   r_   )    r   NzSMB READ Error!)'r   r   r)   r-   r   r   r   r   r]   rA  rB  READr/  rE   r   r   rm  r   rn  rN  READ_REQLengthr   r^   MinimumCountRemainingBytesr
   r4  r5  rD   r   r   r0  rI   r]  DataRemainingEND_OF_FILEBUFFER_OVERFLOWrg  )r@   r7   rU   offsetlengthrD   rI   r   rd   r
  r  r	  r  r1   r1   r2   r     sV   




 #(*zSMBConnection.readc              
      s  z| j dks| jtjkrt || jvrtd| || jvr&td| | j| j4 I dH  t	 }t
j|_||_t|| jkrI|d| j }| jtjkr`| jdkr`dt|d d  |_n|dtdt| }t }t||_||_||_||_t||}| j|| j| dI dH \}}	|	dur|	| |I dH \}
}}	|	dur|	|
jjt j!kr|
j"j#dfW  d  I dH  W S t$d|
jj1 I dH sw   Y  W dS  ty } z
d|fW  Y d}~S d}~ww )	aW  
		This function will send one packet only! The data size can be larger than what one packet allows, but it will be truncated
		to the maximum. 
		Also, there is no guarantee that the actual sent data will be fully written to the remote file! This will be indicated in the returned value.
		Use a high-level function to get a full write.
		
		Tr  r  NrC   r  r  r  )%r   r   r)   r-   r   r   r   r   r]   rA  rB  WRITEr/  rE   rv  r   r   r   rm  r   rn  rN  	WRITE_REQr  r   r^   Datar
   r4  r5  rD   r   r   r0  rI   Countrg  )r@   r7   rU   r   r  rD   rI   r   rd   r
  r  r	  r  r1   r1   r2   r  W  sL   




 !zSMBConnection.writer  c              
      s  z| j dks| jtjkrt || jvrtd| || jvr&td| t }||_	||_
||_||_||_||_t }	tj|	_||	_t|	|}
| |
I dH \}}|durZ|| |I dH \}}}|durk||jjtjkr|tjkrtj|jjt j!ddfW S |tj"kr|t
j#krt$|jjdfW S |jjdfW S |tj%kr|jjdfW S |tj&kr|jjdfW S |jjdfW S t'd|jj ty } z
d|fW  Y d}~S d}~ww )a  
		Queires the file or directory for specific information. The information returned is depending on the input parameters, check the documentation on msdn for a better understanding.
		The resturned data can by raw bytes or an actual object, depending on wther your info is implemented in the library.
		Sorry there are a TON of classes to deal with :(
		
		IMPORTANT: in case you are requesting big amounts of data, the result will arrive in chunks. You will need to invoke this function until None is returned to get the full data!!!
		Tr  r  N)object_typer  )(r   r   r)   r-   r   r   r   r   QUERY_INFO_REQInfoTyper   AdditionalInformationr   r^   r  rA  rB  
QUERY_INFOr/  rE   r
   r4  r5  rD   r   r   r0  QueryInfoTypeSECURITYr   r   rI   r   SE_FILE_OBJECTFILEFileFullDirectoryInformationr   
FILESYSTEMQUOTArg  )r@   r7   rU   	info_typeinformation_classadditional_informationflagsdata_inrI   rD   r   rd   r
  r  r	  r  r1   r1   r2   
query_info  sT   







zSMBConnection.query_infor   c              
      sr  z| j dks| jtjkrt || jvrtd| || jvr&td| t }||_	d|_
|dkr;| j
tjO  _
||_||_||_t }	tj|	_||	_t|	|}
| |
I dH \}}|durc|| |I dH \}}}|durt||jjtjkr|tjkrt|j j!dfW S |j j!dfW S |jjtj"krW dS td|jj  ty } z
d|fW  Y d}~S d}~ww )z
		
		IMPORTANT: in case you are requesting big amounts of data, the result will arrive in chunks. You will need to invoke this function until None is returned to get the full data!!!
		Tr  r  r   N)NNzquery_directory reply: %s)#r   r   r)   r-   r   r   r   r   QUERY_DIRECTORY_REQFileInformationClassr   QueryDirectoryFlagSMB2_INDEX_SPECIFIED	FileIndexr^   FileNamerA  rB  QUERY_DIRECTORYr/  rE   r   r4  r5  rD   r   r   r0  r   r  r   r   rI   r  NO_MORE_FILES)r@   r7   rU   search_patternresume_indexr  maxBufferSizer  rI   rD   r   rd   r
  r  r	  r  r1   r1   r2   query_directory  sJ   



zSMBConnection.query_directoryr&  c              
      s   zW| j dks| jtjkrt t }||_||_||_||_	||_
t }tj|_||_t||}	| |	I d H \}
}|d urA|| |
I d H \}}}|d urR||jj	d fW S  tyn } z
d |fW  Y d }~S d }~ww )NT)r   r   r)   r-   r   	IOCTL_REQCtlCoder^   r   r]  MaxOutputResponserA  rB  IOCTLr/  rE   r   r4  r5  rI   r   )r@   r7   rU   ctlcoder   r  r  rI   rD   r   rd   r
  r  r	  r  r1   r1   r2   ioctl  s2   
zSMBConnection.ioctlc              
      s   zZ| j dks| jtjkrt t }||_||_t }t	j
|_||_t||}| |I dH \}}|dur8|| |I dH \}	}
}|durI||	jjtjkrY|| jv rY| j|= W dS  tyq } z
d|fW  Y d}~S d}~ww )z{
		Closes the file/directory/pipe/whatever based on file_id. It will automatically remove all traces of the file handle.
		TNr  )r   r   r)   r-   r   	CLOSE_REQr   r^   rA  rB  CLOSEr/  rE   r   r4  r5  rD   r   r   r0  r   r   )r@   r7   rU   r  rI   rD   r   rd   r
  r  r	  r  r1   r1   r2   r  "  s2   

zSMBConnection.closec              
      s   zG| j dks| jtjkrt t }||_t }tj	|_
||_t||}| |I dH \}}|dur5|| |I dH \}}	}|durF|W dS  ty^ }
 z
d|
fW  Y d}
~
S d}
~
ww )zK
		Flushes all cached data that may be on the server for the given file.
		TNr  )r   r   r)   r-   r   	FLUSH_REQr^   rA  rB  FLUSHr/  rE   r   r4  r5  r   )r@   r7   rU   rI   rD   r   rd   r
  r  r	  r  r1   r1   r2   flushB  s*   
zSMBConnection.flushc           	   
      s   zA| j dks| jtjkrt t }t }tj|_	t
||}| |I dH \}}|dur/|| |I dH \}}}|dur@|W dS  tyX } z
d|fW  Y d}~S d}~ww )z
		Logs off from the server, effectively terminates the session. 
		The underlying connection will still be active, so please either clean it up manually or dont touch this function
		For proper closing of the connection use the terminate function
		TNr  )r   r   r)   r-   r   
LOGOFF_REQrA  rB  LOGOFFr/  r   r4  r5  r   	r@   rI   rD   r   rd   r
  r  r	  r  r1   r1   r2   logoff\  s&   
zSMBConnection.logoffc           	   
      s   zW| j dks| jtjkrt t }t }tj|_	t
||}| |I dH \}}|dur/|| |I dH \}}}|dur@||jjtjkrJW dS dtd|jjj |jjfW S  tyn } z
d|fW  Y d}~S d}~ww )zi
		Issues an ECHO request to the server. Server will reply with and ECHO response, if it's still alive
		TNr  r  )r   r   r)   r-   r   ECHO_REQrA  rB  ECHOr/  r   r4  r5  rD   r   r   r0  rg  r   r   r  r1   r1   r2   r"  v  s*   
zSMBConnection.echoc              
      s&  z{| j dks| jtjkrt t }t }tj|_	||_
t||}| |I dH \}}|dur2|| |I dH \}}}|durC||jjtjkrzg }	| j| j}
| jD ]}| j| j|krh|	| j| j qU|	D ]}| j|= qk| j|= | j|
= W dS  ty } z
d|fW  Y d}~S d}~ww )zL
		Disconnects from tree, removes all file entries associated to the tree
		TNr  )r   r   r)   r-   r   TREE_DISCONNECT_REQrA  rB  TREE_DISCONNECTr/  rE   r   r4  r5  rD   r   r   r0  r   r6   r   r7   r=  rU   r   r   )r@   r7   rI   rD   r   rd   r
  r  r	  del_file_idsr6   ferU   r  r1   r1   r2   tree_disconnect  s>   


zSMBConnection.tree_disconnectc           	   
      s   zE| j dks| jtjkrt t }t }tj|_	t
||}||j_| |I dH \}}|dur3|| |I dH \}}}|durD|W dS  ty\ } z
d|fW  Y d}~S d}~ww )z6
		Issues a CANCEL command for the given message_id
		TNr  )r   r   r)   r-   r   
CANCEL_REQrA  rB  r  r/  r   rD   r   r4  r5  r   )	r@   rd   rI   rD   r   r
  r  r	  r  r1   r1   r2   rq     s(   
zSMBConnection.cancelc              
      s  zzs| j dks| jtjkrW W | jdur| j  dS dS | jtjkrct| j	 D ]}zt
j| |ddI dH  W q+   Y q+zt
j|  ddI dH  W n tyb } zW Y d}~nd}~ww t
j|  ddI dH  td W n2 t
jy   Y W | jdur| j  dS dS  ty } ztdt|  W Y d}~nd}~ww W | jdur| j  dS dS | jdur| j  w w )z
		Use this function to properly terminate the SBM connection.
		Terminates the connection. Closes all tree handles, logs off and disconnects the TCP connection.
		TNrC   r   zTerminate finished!zterminate error %s)r   r   r)   r-   r   rn   r,   listr   keysr[   r   r  r  r   r  r   r   r   r`  )r@   r7   r  r1   r1   r2   r     sH   


zSMBConnection.terminatec                    s   d| _ dd }td |  I d H  td t }t }tj|_t||}| j	||dI d H \}}zt
j| |ddI d H }W dS    Y d	S )
NTc                 S   sH   t d |  }t|}t }t||_tj|_t	j
|_d|_t||S )NzCallback is here!r   )printrt  r  r  rv  r  r   r   r   r   r   r   r   r   )r   r   r  r  r1   r1   r2   compress_callback  s   

z1SMBConnection.ghosting.<locals>.compress_callbackz[################################### TESTING compression ###################################zY################################### SPLOIT SPLOIT SPLOIT ################################)compression_cbg      ?r   F)r   r  r"  r  rA  rB  r  r/  r   r4  r[   r   r5  )r@   r  rI   rD   r   rd   r
  r  r1   r1   r2   ghosting  s    	
zSMBConnection.ghosting)TF)Fr5   )r   r   )r   )>r.   r/   r0   __doc__	SMBTargetboolrA   r   r   r   r   r  r  r  r  r  r  r  bytesr%  r  r  r   r   r   r5  rx  r   r  r   r  r4  r`  r  r  ImpersonationOplockLevelSMB2_OPLOCK_LEVEL_NONEr   r  r   r  r  r  r   FileStandardInformationr  r  r  IOCTLREQFlagsIS_IOCTLr  	CloseFlagr   r  r  r  r"  r  rq   r   r  r1   r1   r1   r2   rx      sL    g]
 
'^*? /
4
A5D4 (!rx   c                    s   |   }| I d H  d S r5   )get_connectionr  )cuconnr1   r1   r2   ctest  s   r  __main__)SMBConnectionFactory   z5smb+ntlm-password://TEST\victim:Passw0rd!1@10.10.10.2)Yenumr[   r   r   r   typingr   aiosmbr   aiosmb.commons.exceptionsaiosmb.transport.netbiosr   !aiosmb.protocol.smb.command_codesr   aiosmb.wintypes.ntstatusr   aiosmb.protocol.smb.headerr   r	   aiosmb.protocol.smb.messager
   aiosmb.protocol.smb.commonsr   aiosmb.protocol.smb.commandsr   aiosmb.protocol.smb2.messager   r   r   'aiosmb.protocol.smb2.commands.negotiater   r   r   r   r   r   r   r   r   r   aiosmb.protocol.smb2.commandsaiosmb.protocol.smb2.headers"aiosmb.protocol.smb2.command_codesaiosmb.protocol.common.aiosmb.wintypes.dtyp.constrcuted_security.guid-aiosmb.wintypes.fscc.structures.fileinfoclassr   <aiosmb.wintypes.fscc.structures.FileFullDirectoryInformationr   #aiosmb.wintypes.fscc.FileAttributesr   winacl.dtyp.security_descriptorr   winacl.functions.constantsr    aiosmb.commons.connection.target	unicryptor   r    unicrypto.symmetricr!   r"   r#   unicrypto.cmacr$   unicrypto.kdfr%   !aiosmb.protocol.compression.lznt1r&   r  r'   r   asysocks.unicomm.clientr(   Enumr)   r4   rT   ra   rx   r  r.   !aiosmb.commons.connection.factoryr  setLevelurlfrom_urlr  rv   r1   r1   r1   r2   <module>   sx    0)           


