Lateral Movement

Impacket for Pentester: tstool

Overview

Terminal Services, better known today as Remote Desktop Services, governs every interactive and remote session on a Windows host. impacket-tstool lets an operator query and control those sessions entirely over MSRPC, with no RDP client and no dropped binary on the target. This article walks through session enumeration, remote process control, live RDP session hijacking, session teardown, user messaging, and passwordless authentication against a domain controller, mapping each built-in Terminal Services command to its offensive use.

Table of Contents: 

  • Introduction to tstool
  • Enumerating Sessions with qwinsta
  • Listing Remote Processes with tasklist
  • Terminating a Process with taskkill
  • Hijacking an RDP Session with tscon
  • Disconnecting a Session with tsdiscon
  • Signing Out a Session with logoff
  • Rebooting the Target with shutdown
  • Messaging a Session with msg
  • Authenticating Without a Password
  • Conclusion
  • Mitigation Strategies 

Introduction to tstool

impacket-tstool is a Terminal Services manipulation utility shipped with Fortra’s Impacket suite. It reproduces the native Windows commands qwinsta, tasklist, taskkill, tscon, tsdiscon, logoff, shutdown, and msg, but drives them remotely through DCE/RPC against the Remote Desktop and Session Manager interfaces. Because the tool speaks RPC directly, it needs only valid credentials and network reachability; it installs no service, requires no agent, and never opens an interactive logon. That combination makes it valuable for post-exploitation reconnaissance, lateral movement, and session hijacking across Active Directory estates. Throughout this walkthrough the target is the domain controller DC1 at 192.168.1.13 in the ignite.local domain. 

Enumerating Sessions with qwinsta

The qwinsta action lists every Terminal Services session on the host and exposes each session ID, the logged-on user, the session state, its lock status, and the connect times. When run as a domain administrator, the tool reveals two interactive sessions of interest: IGNITE\administrator on the console with ID 1 in an Active state, and IGNITE\krishna over RDP with ID 2 in a Locked state. This single command maps who is logged on and marks the sessions worth targeting.

impacket-tstool ignite/administrator:Ignite@987@192.168.1.13 qwinsta

Listing Remote Processes with tasklist

The tasklist action enumerates every running process together with its PID, session number, owning SID, and memory footprint. Session 0 carries the system and service processes, including System, lsass.exe, services.exe, and the full svchost.exe fleet, giving the operator a complete inventory of what executes on the target.

impacket-tstool ignite/administrator:Ignite@987@192.168.1.13 tasklist

Scrolling into the session 1 processes expose the interactive workload owned by IGNITE\Administrator, which includes several firefox.exe instances. The operator earmarks the firefox.exe process carrying PID 6232 as the termination target for the next step.

Terminating a Process with taskkill

The taskkill action stops a process remotely by PID or image name. After re-confirming the session table with qwinsta, the operator kills the firefox.exe instance identified earlier. The tool reports “Terminating PID: 6232 … OK”, demonstrating full remote process control over the host.

impacket-tstool ignite/administrator:Ignite@987@192.168.1.13 taskkill -pid 6232

Hijacking an RDP Session with tscon

To stage the hijack, IGNITE\krishna holds a live interactive session on the target. The RDP window confirms the identity through whoami, which returns ignite\krishna, and hostname, which returns DC1. This ordinary user session is the one the operator intends to seize.

Authenticating this time as krishna, qwinsta enumerates the sessions and pinpoints the victim: the RDP-Tcp#14 session carries ID 3 and sits in an Active state. This session ID becomes the source for the hijack.

impacket-tstool ignite/krishna:Password@1@192.168.1.13 qwinsta

Session redirection requires Connect or Full Control permission on the session host, which an Administrator or SYSTEM context typically satisfies. This elevated PowerShell confirms that the operator already commands an ignite\administrator session on the target, meeting the privilege that tscon demands to attach one session to another.

The tscon action performs the hijack. Passing -source 3 for krishna and -dest 1 for the administrator console redirects krishna’s session onto the operator’s terminal. The tool confirms “Connecting SessionID 3 to 1 … OK”, and the operator now owns krishna’s desktop without ever learning krishna’s password.

impacket-tstool ignite/krishna:Password@1@192.168.1.13 tscon -source 3 -dest 1

On krishna’s endpoint the RDP client drops immediately with the message “You have been disconnected because another connection was made to the remote computer.” This eviction is the visible side effect of tscon: the original owner loses the session the instant it reattaches elsewhere.

Back on the operator’s console the reattached session now presents krishna’s desktop. A command prompt confirms the stolen context, with whoami returning ignite\krishna on host DC1. The operator holds full interactive access to the victim’s session with no credential theft involved.

Disconnecting a Session with tsdiscon

The tsdiscon action forcibly disconnects a session while leaving its programs running in the background. Targeting session 1 disconnects it, and the follow-up qwinsta confirms the state has flipped to Disconnected. Operators use this to boot a user off a session or to tidy up after a hijack.

impacket-tstool ignite/krishna:Password@1@192.168.1.13 tsdiscon -session 1

Signing Out a Session with logoff

The logoff action terminates a session outright and closes every process the user was running. Here it signs out session 3, and the tool returns “Signing-out SessionID: 3 … OK”. Unlike tsdiscon, this operation is destructive to any unsaved work in the session.

impacket-tstool ignite/krishna:Password@1@192.168.1.13 logoff -session 3

Rebooting the Target with shutdown

The shutdown action issues a power event to the host. The -reboot flag triggers a restart, and the tool confirms “Sending shutdown (reboot) event … OK”. On a domain controller this is a high-impact operation and warrants deliberate care during an engagement.

impacket-tstool ignite/krishna:Password@1@192.168.1.13 shutdown -reboot

 Messaging a Session with msg

The msg action pushes a message box to a chosen session. This example delivers the string “Welcome to Hacking Articles” to session 1, and the tool acknowledges “Sending message to SessionID: 1 … OK”.

impacket-tstool ignite/krishna:Password@1@192.168.1.13 msg -session 1 -message 'Welcome to Hacking Articles'

On the target desktop the message renders as a native pop-up dialog. Beyond the novelty, it proves that the operator can interact with a live user session in an arbitrary and attributable way.

 

Authenticating Without a Password

Because tstool inherits Impacket’s authentication stack, it accepts far more than a plaintext password. NTLM hashes, Kerberos AES keys, and cached tickets all work, which keeps the tool effective deep inside a compromised domain where credentials are recovered rather than guessed.

Supplying the administrator’s NTLM hash with -hashes authenticates without the cleartext password. The qwinsta output returns normally, confirming a successful Pass-the-Hash against the target.

impacket-tstool -hashes :32196B56FFE6F45E294117B91A83BF38 ignite.local/administrator@192.168.1.13 qwinsta

The -aesKey flag authenticates with the account’s Kerberos AES256 key. Despite the “CCache file is not found. Skipping” notices, the tool falls through to key-based Kerberos authentication and returns the session table, demonstrating a Pass-the-Key attack.

impacket-tstool ignite.local/administrator@dc1.ignite.local -aesKey \
  e1182a9a34827cabac57a635ae47ce2b2945b4e9397d369b07d4d714c6c525b7 qwinsta

Exporting a Kerberos ccache to KRB5CCNAME and running with -k and -no-pass authenticates purely from the cached ticket. The successful qwinsta confirms a clean Pass-the-Ticket, closing the loop on credential-less access to the domain controller.

export KRB5CCNAME=Administrator.ccache
impacket-tstool -k -no-pass ignite.local/administrator@dc1.ignite.local qwinsta

Conclusion

impacket-tstool turns Windows’ own Terminal Services management surface into a compact offensive toolkit. From a single authenticated foothold an operator can enumerate sessions, control processes, hijack a live RDP session without stealing a password, evict or log off users, reboot a host, and message a desktop, and can do all of it through Pass-the-Hash, Pass-the-Key, or Pass-the-Ticket. Its stealth comes from abusing legitimate, signed functionality rather than dropping malware, which is exactly why defenders must watch this surface closely.

Mitigation Strategies 

  • Enforce least privilege and tiered administration. Session hijacking through tscon hinges on holding a privileged destination session, so tightly restricting local Administrator and SYSTEM rights blunts the technique.
  • Limit “Allow log on through Remote Desktop Services” to required accounts, and constrain Remote Control behaviour through Group Policy by disabling it or requiring explicit user consent.
  • Enable RestrictedAdmin mode and Remote Credential Guard for RDP, and remove interactive and RDP logon rights from domain controllers wherever operationally possible.
  • Contain Pass-the-Hash, Pass-the-Key, and Pass-the-Ticket with the Protected Users group, LAPS for local administrator passwords, strong credential tiering, and regular krbtgt rotation.
  • Monitor the behaviour, not just the tool. Alert on MSRPC calls to the Terminal Services interfaces and on Windows Event IDs 4778 and 4779 for session reconnect and disconnect, 4634 and 4647 for logoff, and 1074 for shutdown, alongside unexpected taskkill activity on servers.
  • Segment the network so that TCP 135 and 445 to domain controllers are reachable only from designated administrative hosts.