o
    j*                  
   @   sd  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  mZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZmZmZ d d
lmZmZmZ d dlmZ d dlmZ d dl m!Z!m"Z"m#Z# d dl$Z$G dd dZ%e&dkrej'j(du re)dej'e_'e*ej+ e j,dddZ-e-j.dddd e-j.dddd e-j.dddd e-j/ddd Z0e0j1d!d"d#Z2e2j.d$dd%d&d' e0j1d(d)d#Z3e3j.d$dd%d&d' e0j1d*d+d#Z4e4j.d,dd-e5d.d/ e4j.d0dd1d e0j1d2d3d#Z6e6j.d4dd5e5dd6d7 e6j.d8dd5e5dd9d7 e6j.d:de7d;d<d= e0j1d>d?d#Z8e8j.d@dd5e5ddAd7 e0j1dBdCd#Z9e9j.d@dd5e5ddDd7 e0j1dEdFdGdHZ:e:;dIZ<e<j.dJddKd e<j.dLddMd e<j.dNddOd e<j.dPddQd e0j1dRdSd#Z=e=j.d@dd5e5ddTd7 e=j.dUddVe7d;dWd7 e=j.dXddYe7ddZd7 e0j1d[d\d#Z>e>j.d@dd5e5dd]d7 e>j.d^dd_d e>j.d`ddad e>j.dbe7dcddde e-;dfZ?e?j.dgddhdidj e?j.dkddld e?j.dmddnd e?j.doddpdqdj e-;drZ?e?j.dsddtdudj e?j.dvddtdwdj e?j.dxdydzgd{dzd|d}d~ e@ejAdkre-B  eCd e-D ZEeFeEjGeEjH eEjIdu r7e-B  eJd eCd eeEjK\ZLZMZNZOeEjPdu rIeOeE_PeLdu rPdZLeEjQdurYdeE_ReNdkreMdkreEjSdu reEjTd;u reEjQdu rd dlUmUZU eUdZNe%eMeNeLeEZVz
eVWeOeEjP W dS  eXy ZY ze$Z  eJe7eY W Y dZY[YdS dZY[Yww dS )    N)tostring)unpack)version)logger)parse_target)SMBConnection)LOG)	transportlsatlsad)RPC_C_AUTHN_GSS_NEGOTIATERPC_C_AUTHN_LEVEL_PKT_PRIVACYDCERPCException)MAXIMUM_ALLOWED)tsts)SHADOW_CONTROL_REQUESTSHADOW_PERMISSION_REQUESTSHADOW_REQUEST_RESPONSEc                   @   s   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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 )$	TSHandlerc                 C   st   || _ || _|| _|| _|j | _d| _d| _|j	| _
|j| _|j| _d | _|jd ur8|jd\| _| _d S d S )N :)_TSHandler__username_TSHandler__password_TSHandler__domain_TSHandler__optionsactionlower_TSHandler__action_TSHandler__lmhash_TSHandler__nthashaesKey_TSHandler__aesKeyk_TSHandler__doKerberosdc_ip_TSHandler__kdcHost_TSHandler__smbConnectionhashessplit)selfusernamepassworddomainoptions r.   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/../../../bin/tstool.py__init__<   s   
zTSHandler.__init__c              	   C   sp   || _ t||t| jjd| _| jr'| j| j| j	| j
| j| j| j| j d S | j| j| j	| j
| j| j d S )N)	sess_port)
remoteNamer   intr   portr&   r#   kerberosLoginr   r   r   r   r   r!   r%   loginr)   r2   
remoteHostr.   r.   r/   connectL   s   "zTSHandler.connectc                 C   sX   | j jdkrttjtjtjtjgst	d t
d | || t| d| j   d S )NshutdownzGAt least one flag is required: -logoff, -shutdown, -reboot or -poweroff   do_)r   r   maxr-   logoffr:   rebootpoweroffr   errorexitr9   getattrr   r7   r.   r.   r/   runV   s   
zTSHandler.runc                 C   s   t | j| jj| jI}| }|j|ddd }|| i | _	|D ](}|d d }t 
t j|d dd }||d	 d
d
d
d
d
d
d| j	|d < q#W d    d S 1 sWw   Y  d S )Nr;   )LevelppSessionEnumResultSessionInfoSessionEnum_Level1State_Namer   )stateSessionNameRemoteIp
ClientNameUsernameDomain
ResolutionClientTimeZone	SessionId)TSTSTermSrvEnumerationr&   r   	target_ipr#   hRpcOpenEnumhRpcGetEnumResulthRpcCloseEnumsessions
enum2valueWINSTATIONSTATECLASSr(   )r)   lsmhandle	rsessionsisessrM   r.   r.   r/   get_session_list_   s&   
"zTSHandler.get_session_listc                 C   sD  t | jrt| j| jj| j}| jD ]y}||}|d ur|d d | j| d< |d d | j| d< t |d d rQt | j| d sQ|d d | j| d< t |d d rmt | j| d sm|d d | j| d< d	|d d	 |d d
 | j| d< |d d d | j| d< qW d    d S 1 sw   Y  d S d S )NppBuffClientAddressrO   rP   UserNamerQ   rR   z{}x{}HResVResrS   rT   StandardName)
lenr\   rV   	RCMPublicr&   r   rX   r#   hRpcGetClientDataformat)r)   termsrvrU   respr.   r.   r/   enumerate_sessions_configs   s(   


""

"z#TSHandler.enumerate_sessions_configc                 C   sd  t | jrt| j| jj| j}| j D ]}|	|}t
tj|d d d }|| j| d< |d d d }t | j| d sMt |rM|| j| d< |d d d }t | j| d sit |ri|| j| d< |d d d	 | j| d	< |d d d
 | j| d
< |d d d | j| d< |d d d | j| d< qW d    d S 1 sw   Y  d S d S )NLSMSessionInfoExPtrLSM_SessionInfo_Level1SessionFlagsflags
DomainNamerR   rg   rQ   ConnectTimeDisconnectTime	LogonTimeLastInputTime)rk   r\   rV   TermSrvSessionr&   r   rX   r#   keyshRpcGetSessionInformationExr]   SESSIONFLAGS)r)   r{   rU   sessdata	sessflagsr,   r*   r.   r.   r/   enumerate_sessions_info   s&   

"z!TSHandler.enumerate_sessions_infoc              
      sn   j }dddd}   t jstd d S    |jr#   t fdd jD }td|k r7|ntdd	 }t fd
d jD d	 }td|k rS|ntdd	 }tdd  jD }td|k rk|ntdd	 }t fdd jD }td|k r|ntdd	 }t fdd jD }td|k r|ntdd	 }t fdd jD }td|k r|ntdd	 }d||||f }	d||f }
g }|	j	dddddddd}|	
ddj	dddddddd}d}d}|jr	|
j	ddddd}|

ddj	ddddd}|||  ||| d    jD ]} j| d }|jd!kr0|d"nd#} j| d }|jd!krD|d"nd#}t j| d r` j| d$ d%  j| d  nd}|	j	 j| d& || j| d' | j| d(  ||d}d}|jr|
j	 j| d  j| d)  j| d  j| d d}|||  q|D ]}t| qd S )*Nr   LockedUnlocked)WTS_SESSIONSTATE_UNKNOWNWTS_SESSIONSTATE_LOCKWTS_SESSIONSTATE_UNLOCKzNo sessions found...c                    "   g | ]}t  j| d  d qS )rN   r;   rk   r\   .0rb   r)   r.   r/   
<listcomp>      " z(TSHandler.do_qwinsta.<locals>.<listcomp>SESSIONNAMEr;   c                    0   g | ]}t  j| d   j| d  d qS rQ   rR   r;   r   r   r   r.   r/   r         0 rQ   c                 S   s   g | ]}t t|qS r.   )rk   strr   r.   r.   r/   r          IDc                    r   )rM   r;   r   r   r   r.   r/   r      r   STATEc                    r   )rO   r;   r   r   r   r.   r/   r      r   RemoteAddressc                    r   )rP   r;   r   r   r   r.   r/   r      r   rP   zg{SESSIONNAME: <%d} {USERNAME: <%d} {ID: <%d} {STATE: <%d} {DSTATE: <9} {CONNTIME: <20} {DISCTIME: <20} zC{CLIENTNAME: <%d} {REMOTEIP: <%d} {RESOLUTION: <11} {TIMEZONE: <15}USERNAMEDesktoprw   rx   )r   r   r   r   DSTATECONNTIMEDISCTIME <=<rS   rT   )
CLIENTNAMEREMOTEIP
RESOLUTIONTIMEZONE
iA  z%Y/%m/%d %H:%M:%SNonerR   \rN   rM   ru   rO   )r   rd   rk   r\   printr   verboserq   r=   rn   replaceappendyearstrftime)r)   r-   desktop_statesmaxSessionNameLenmaxUsernameLenmaxIdLenmaxStateLenmaxRemoteIpmaxClientNametemplatetemplate_verboseresultheaderheader2header_verboseheader2_verboserb   connectTimedisconnectTimeuserNamerowrow_verboser.   r   r/   
do_qwinsta   s   




8	zTSHandler.do_qwinstac              
   C   s  zd| j j }t|}|| j | }| jr|t	 |
t |  |tj t| j }t|dkr@|d d }t|ttjB }|d }zt|||tjj}W n! tyz } zt|ddkro| }n W Y d }~nd }~ww t||d d D ]3\}}	|	d }
|
d	krd
 d|	d | j|< q|
dkrd
 |d d |	d  d |	d }|| j|< q|!  W d S    t"#t$%  Y d S )Nzncacn_np:%s[\pipe\lsarpc]    PolicyHandleSTATUS_SOME_NOT_MAPPEDr   TranslatedNamesNamesDomainIndexrK   z{}\{}z???rL   ReferencedDomainsDomains)&r   rX   r	   DCERPCTransportFactoryset_smb_connectionr&   get_dce_rpcr#   set_auth_typer   set_auth_levelr   r9   bindr
   MSRPC_UUID_LSATlistsidsr|   rk   r   hLsarOpenPolicy2r   POLICY_LOOKUP_NAMEShLsarLookupSidsLSAP_LOOKUP_LEVELLsapLookupWkstar   r   find
get_packetziprn   
disconnectloggingdebug	traceback
format_exc)r)   stringbindingrpctransportdcer   rp   policyHandleesiditemdomainIndexnamer.   r.   r/   
lookupSids  sF   



$
zTSHandler.lookupSidsc                 C   s(   |d d dkr|| j v r| j | S |S )N   S-)r   )r)   r   r.   r.   r/   	sidToUser4  s   
zTSHandler.sidToUserc                    s   j }t j|j j]}| }||}t|s%	 W d    d S i  _	|D ]}|
 }|d d dkrB| j	vrB| j	|< q*   tdd |D }tdd |D }|jr      t fdd jD d }	|	dk ryd}	d	||	|f }
t|
jd
dddddddd t|
ddjdddddddddd  |D ]f}| }|d }d}t j| d r| j| d d 7 }t j| d r| j| d 7 }|
ddj|d  |d  j| d |d  j| d  d!d" |
 ||d# d$ d%}t| qnMd&||f }
t|
d
dd'dd t|
d(d)dddddd  |D ]0}| }|
|d  |d |d  |
 d*|d# d$ }t| q2W d    d S W d    d S 1 sow   Y  d S )+Nr   r   c                 S   s    g | ]}t | d   qS )	ImageName)rk   getProcessInfogetValuer   process_entryr.   r.   r/   r   I  s     z)TSHandler.do_tasklist.<locals>.<listcomp>c                 S   s   g | ]}t | qS r.   )rk   getSidr   r.   r.   r/   r   J  r   c                    r   r   r   r   r   r.   r/   r   N  r   r;      z{{imagename: <%d} {pid: <6} {sessid: <6} {sessionName: <16} {sessstate: <11} {sessionuser: <%d} {sid: <%d} {workingset: <12}z
Image NamePIDSessNameSessIDSessUserrI   SIDz	Mem Usage)	imagenamepidsessionNamesessidsessionuser	sessstater   
workingsetr   r   r   r   rU   rR   r   rQ   z{workingset: <12}z{workingset: >10,} Kr   UniqueProcessIdrN   rM   DisconnectedDiscWorkingSetSizei  )r   r   r   r   r   r   r   r   z&{: <%d} {: <8} {: <11} {: <%d} {: >12}zSession#z: z:=z{:,} K)r   rV   	LegacyAPIr&   rX   r#   hRpcWinStationOpenServerhRpcWinStationGetAllProcessesrk   r   r   r   r=   r   rd   rq   r\   r   rn   r   r   r   r   )r)   r-   legacyr`   process_entry_listr   r   maxImageNameLen	maxSidLenmaxUserNameLenr   process_infosessIdfullUserNamer   r.   r   r/   do_tasklist9  s   

	



"
L$zTSHandler.do_tasklistc                    sv  | j   jd u r jd u rtd d S g }t| j j| j	}|
 } jd u re jd ure||}t|sFtd 	 W d    d S  fdd|D }t|sdtd j  	 W d    d S n jg}|D ]=}td| dd z|||d	 rtd
 ntd W qk ty } ztd|  tt| W Y d }~qkd }~ww W d    d S 1 sw   Y  d S )Nz-One of the following is required: -pid, -namezCould not get process listc                    s6   g | ]}|  d     j kr|  d qS )r   r   )r   r   r   r   r   r-   r.   r/   r     s    
z)TSHandler.do_taskkill.<locals>.<listcomp>z!Could not find %r in process listzTerminating PID: %d ...r   end	ErrorCodeOKFAILzError terminating pid: %d)r   r   r   r   rA   rV   r  r&   rX   r#   r  r  rk   r   hRpcWinStationTerminateProcess	Exceptionr   )r)   pidListr  r`   rr   r   r.   r  r/   do_taskkill  sD   


	
"zTSHandler.do_taskkillc                 C   s  | j }t| j|j| j}zcd }td|j|jf dd z|	|j}W n3 t
yX } z'td |jdkr?td|j  ntt| W Y d }~W W d    d S d }~ww |j||j|jdd d	krltd
 ntd W n< t
y } z0td |jdkrtd|j  n|jdkrtd|j|jf  ntt| W Y d }~nd }~ww W d    d S W d    d S 1 sw   Y  d S )Nz!Connecting SessionID %d to %d ...r   r  r        z#Could not find source SessionID: %d)hSessionTargetSessionIdPasswordr  r   r  z(Could not find destination SessionID: %dl     z4Session in the invalid state. Did you mean %d -> %d?)r   rV   r{   r&   rX   r#   r   sourcedesthRpcOpenSessionr  
error_coder   rA   r   hRpcConnectr+   r)   r-   	TSSessionsession_handler   r.   r.   r/   do_tscon  sP   



" zTSHandler.do_tsconc                 C   s  | j }t| j|j| jk}z#td|j dd ||j}|	|d dkr,td ntd W n6 t
yg } z*td |jdkrHtd	 n|jd
krVtd|j  ntt| W Y d }~nd }~ww W d    d S W d    d S 1 s{w   Y  d S )NzDisconnecting SessionID: %d ...r   r  r  r   r  r  r;   z!Maybe it is already disconnected?r  Could not find SessionID: %d)r   rV   r{   r&   rX   r#   r   sessionr  hRpcDisconnectr  r  r   rA   r   r!  r.   r.   r/   do_tsdiscon  s,   


" zTSHandler.do_tsdisconc                 C   s  | j }t| j|j| jv}z#td|j dd ||j}|	|d dkr,td ntd W nA t
yr } z5|jdkrOtd W Y d }~W d    d S td |jd	kratd
|j  ntt| W Y d }~nd }~ww W d    d S W d    d S 1 sw   Y  d S )NzSigning-out SessionID: %d ...r   r  r  r   r  r  i   r  r%  )r   rV   r{   r&   rX   r#   r   r&  r  
hRpcLogoffr  r  r   rA   r   r!  r.   r.   r/   	do_logoff  s0   



" zTSHandler.do_logoffc                 C   sH  | j }t| j|j| j}| }d}g }|j|j|j	|j
g}t|g dD ]\}}|r2|| q'd|}t|g dD ]
\}}|rI||O }q?z"td| dd ||d|}	|	d rctd	 n|	  td
 W n ty }
 ztd
 tt|
 W Y d }
~
nd }
~
ww W d    d S W d    d S 1 sw   Y  d S )Nr   )r>   r:   r?   r@   |)r;   r         zSending shutdown (%s) event ...r   r  r  r  r  )r   rV   r  r&   rX   r#   r  r>   r:   r?   r@   r   r   joinr   hRpcWinStationShutdownSystemdumpr  r   rA   r   )r)   r-   r  r`   ru   	flagsListShutdownFlagsr"   vrp   r   r.   r.   r/   do_shutdown  s@   


"zTSHandler.do_shutdownc                 C   s   | j }t| j|j| jd}z'td|j dd ||j}|	||j
|jd dkr0td ntd W n+ ty` } ztd |jdkrOtd	|j  ntt| W Y d }~nd }~ww W d    d S W d    d S 1 stw   Y  d S )
Nz$Sending message to SessionID: %d ...r   r  r  r   r  r  r  r%  )r   rV   r{   r&   rX   r#   r   r&  r  hRpcShowMessageBoxtitlemessager  r  r   rA   r   r!  r.   r.   r/   do_msg  s(   

" zTSHandler.do_msgc                 C   s  | j jrtjjntjj}| j jrtjjntjj	}t
d| j j d| j j d| j j d z=t| j| j j| j(}|| j j||d}| j jrRt
d|   |d }|d }W d	   n1 sdw   Y  W n ty } zt
d
|  W Y d	}~d	S d	}~ww |d	urztt|}W n ttfy   d}Y nw t
d| d| d |tjjjkrht
d |st
d td t
dt| d z| d! }t"#|}W nC t"j$y!   |%dr|&dsd|v r|'dd }	|d	|	 }zt"#|}W n t"j$y   d	}Y nw d	}nd	}Y nw |rat(|ddd)d}t
d t*| j j+ddd}
|
,| t
d| j j+ d W d	   d	S 1 sZw   Y  d	S t
d  d	S t
d! td d	S )"z
        Request a Remote Connection String to shadow a Remote Desktop Services session.
        Author: Ilya Yatsenko (@fulc2um)
        zCalling RpcShadow2 (SessionId=z
, Control=z, Permission=)i    z
Response: pePermissionpszInvitationNzRPC Exception: UnknownzPermission: z (zRpcShadow2 call succeeded!z)RpcShadow2 failed: No invitation receivedr;   zInvitation received (z characters)z 
<>z</E>r,  zutf-8xml)encodingmethodzInvitation is well-formed XMLw)r@  z	Saved to z filez0Invitation does not appear to be well-formed XMLz$RpcShadow2 failed: Permission denied)-r   controlr   	enumItems"SHADOW_CONTROL_REQUEST_TAKECONTROLSHADOW_CONTROL_REQUEST_VIEWpromptr   +SHADOW_PERMISSION_REQUEST_REQUESTPERMISSION SHADOW_PERMISSION_REQUEST_SILENTr   infor&  rV   SessEnvPublicRpcr&   rX   r#   hRpcShadow2r   getDatar   rA   r]   r   KeyErrorAttributeErrorSHADOW_REQUEST_RESPONSE_ALLOWvaluesysrB   rk   rstripstripET
fromstring
ParseError
startswithendswithrfindr   decodeopenfilewrite)r)   rC  permsErpcresponse
permission
invitationr   descend_posfr.   r.   r/   	do_shadow$  s~   

*
	





$
zTSHandler.do_shadowN)__name__
__module____qualname__r0   r9   rD   rd   rq   r   r   r   r   r  r  r$  r(  r*  r4  r8  rg  r.   r.   r.   r/   r   ;   s$    
	v%Y r   __main__utf8Tz$Terminal Services manipulation tool.)add_helpdescriptiontargetstorez6[[domain/]username[:password]@]<targetName or address>)r   helpz-debug
store_truezTurn DEBUG output ONz-tsz&Adds timestamp to every logging outputactionsr   )rq  r  qwinstaz;Display information about Remote Desktop Services sessions.)rq  z-vr   zTurn VERBOSE output ON)r   r  rq  tasklistz<Display a list of currently running processes on the system.taskkillz2Terminate tasks by process id (PID) or image name.z-pidr   zSpecifies process id (PID))r   metavartyperq  z-namezdSpecifies process name (ImageName). Internally it willexecute tasklist to retrieve PID by ImageName.tsconz4Attaches a user session to a remote desktop session.z-source	SessionIDzSource SessionId)r   rw  rx  requiredrq  z-destzDestination SessionIdz	-passwordFzDestination Session's password)r   rx  r{  rq  tsdisconz.Disconnects a Remote Desktop Services session.z-sessionzSessionId to disconnectr>   z+Sign out a Remote Desktop Services session.zSessionId to sign outr:   z:Remote shutdown, affects ALL sessions and logged-in users!zESend Remote Shutdown event. Affects ALL sessions and logged-in users!)rq  rn  z Shutdown Flags [Multiple Choice]z-logoffzForces sessions to logoff.z	-shutdownzShuts down the system.z-rebootzReboots after shutdown.z	-poweroffzPowers off after shutdown.msgz;Send a message to Remote Desktop Services session (MSGBOX).zReceiver SessionIdz-titlez'Your Title'z"Title of the MessageBox [Optional]z-messagez'Your Message'zContents of the MessageBoxshadowz)Shadow a Remote Desktop Services session.zSessionId to shadowz-controlz5Request control of the session (default is view only)z-promptz+Request user permission (default is silent)z-filezSave invitation to filezinvite.msrcIncident)rx  rq  defaultauthenticationz-hasheszLMHASH:NTHASHz$NTLM hashes, format is LMHASH:NTHASH)r   rw  rq  z-no-passz&don't ask for password (useful for -k)z-kzUse Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command linez-aesKeyzhex keyz<AES key to use for Kerberos Authentication (128 or 256 bits)
connectionz-dc-ipz
ip addressztIP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameterz
-target-ipzIP Address of the target machine. If omitted it will use whatever was specified as target. This is useful when target is the NetBIOS name and you cannot resolve itz-port139445?zdestination portz)Destination port to connect to SMB Server)choicesnargsr  rw  rq  r;   zToo few arguments...r   )getpassz	Password:)[argparsecodecsr   rR  xml.etree.ElementTreer   etreeElementTreerU  structr   impacketr   impacket.examplesr   impacket.examples.utilsr   impacket.smbconnectionr   r   impacket.dcerpc.v5r	   r
   r   impacket.dcerpc.v5.rpcrtr   r   r   impacket.dcerpc.v5.dtypesr   r   rV   impacket.dcerpc.v5.tstsr   r   r   r   r   rh  stdoutr@  	getwriterr   BANNERArgumentParserparseradd_argumentadd_subparsers
subparsers
add_parserqwinsta_parsertasklist_parsertaskkill_parserr3   tscon_parserr   tsdiscon_parserlogoff_parsershutdown_parseradd_argument_groupshutdown_parser_group
msg_parsershadow_parsergrouprk   argv
print_helprB   
parse_argsr-   inittsr   r   rA   ro  r,   r*   r+   r2   rX   r    r"   r'   no_passr  	tsHandlerrD   r  r   	print_excr.   r.   r.   r/   <module>   s        
9










8