Impacket Deep Dives Vol. 1: Command Execution

Kyle Mistele
7 min readMar 31, 2021
Shelling a lab machine with Impacket’s Psexec.py

Impacket is a collection of tools built by Secure Auth Corp, for “working with networking protocols”. This is true, but it’s so much more than that. Impacket contains dozens of amazing tools for interacting with windows systems and applications, many of which are ideal for attacking Windows and Active Directory.

In this article, I’m going to cover the various utilities that Impacket offers for executing commands and getting shells on remote hosts. While many people may have used psexec.py, you might be surprised to read that Impacket offers nearly a half-dozen ways of executing commands on remote hosts! In this article, I’m going to cover all of them.

Note: if you’re using password-based authentication, the format for your command-line argument to all of the Impacket remote access tools is going to be DOMAIN/USERNAME:PASSWORD@HOST . It’s important to note that if any of these fields have special characters (e.g. the password field), then you need to use quotes around it, and escape as necessary.

In this article, I will not be covering authentication with hashes and Kerberos tickets, but keep an eye out for an article on that in the near future!

Psexec.py

One of the most commonly used tools in impacket is psexec.py. Psexec.py is named after the tool from Microsoft’s Sysinternals suite since it performs the same function: it allows us to execute a fully interactive shell on remote Windows machines, and is therefore an invaluable tool.

How it works

Like any tool, it’s important to understand how Psexec works. Impacket’s Implementation creates a remote service by uploading a randomly-named executable to the hidden Windows ADMIN$ share, registering a service via RPC and the Windows Service Control Manager, and then communicating over named a named pipe.

Using Psexec.py

Psexec requires credentials for a user with local administrator privileges or higher since reading/writing to the ADMIN$ share is required. Once you successfully authenticate, it will drop you into a NT AUTHORITY\SYSTEM shell.

Using psexec.py to get a SYSTEM shell on a Windows host with credentials

Once you’re done, make sure to exit with the exit command instead of Ctrl+C , and the tool will clean up the executable and service that it created!

Other cool features

Psexec.py has some meta-commands that can be used for uploading/downloading files: the put, get, and lcd commands:

Uploading Invoke-Mimikatz.ps1 with Psexec.py

Since Psexec is a relatively commonly used tool and since it’s easy to detect, it will often get caught by antivirus. Fortunately, Impacket has a couple of other remote access tools, some of which fly a little lower under the radar.

It’s worth noting that Psexec.py is pretty easy to detect, and is often caught by defender. Some of the other methods below tend to bypass AV more easily.

Dcomexec.py

Decomexec executes a semi-interactive shell with DCOM. Otherwise, it’s very similar to Psexec.py, and it uses the same syntax.

How it works

Dcomexec.py uses the Distributed Component Object Model (DCOM) to execute commands. DCOM is a protocol used by applications and server components to communicate over a network, and it relies heavily on RPC. Dcomexec uses the MMC20 Application (which is accessible over the network with authentication) and its ExecuteShellCommand method to execute arbitrary commands. It also supports using the ShellWindows application and the ShellBrowserWindow applications.

Using Dcomexec.py

While Domexec.py works differently than Psexec.py, its user interface is the same.

Smbexec.py

Smbexec.py functions similarly to Psexec.py, in that it allows us to execute commands on a remote windows machine. However, Smbexec.py does not give you an interactive shell.

How it works

Instead of uploading an executable and using the Windows Service Control Manager to create a service that uses named pipes to give you an interactive shell, smbexec creates a batch file for each command that you run, then creates a service to run the file using cmd.exe. It redirects STDOUT and STDERR to a temporary file on a readable SMB share (or creates a share on your attacking host, if the remote one doesn’t have one), and then pulls the contents of that file into your smbexec “shell”. This will generate a lot of windows event logs since you’re creating and deleting a lot of services, but it still tends to be detected less frequently than psexec.py. Commands that take a long time to execute may be terminated by the system since they won’t respond as a normal service would.

Using Smbexec.py

While Smbexec works differently than Psexec, its user interface is more or less the same:

Getting a semi-interactive NT AUTHORITY/SYSTEM shell with Smbexec.py

Unlike Psexec.py, smbexec.py does not have the same built-in utilities for uploading and downloading files. Additionally, since it’s not an interactive shell, it’s important to be careful what commands you run and how you run them. If you have to run PowerShell commands then you should build one-liners, otherwise smbexec.py will hang.

Wmiexec.py

Like Smbexec, Wmiexec doesn’t give you an interactive shell, but it tends to fly lower under the radar since it doesn’t generate lots of windows event logs about services being created. Unlike some of the other tools described here, Wmiexec.py runs commands as the authenticated local administrator, rather than NT AUTHORITY\SYSTEM . Like psexec, wmiexec supports the put and get meta-commands to upload and download files

How it works

Wmiexec.py uses the Windows Management Instrumentation and DCOM to create a windows process to run commands. Like some of the above methods, it writes the output out to a temp file in an SMB share ( ADMIN$ by default) and then retrieves the output and deletes the file.

Using wmiexec.py

Wmiexec’s syntax is the same as psexec and smbexec:

Running a command with Wmiexec.py

Atexec.py

Unlike the previous tools, atexec doesn’t give you a shell at all. Rather, it allows you to execute some command or one-liner as the NT Authority\System user, and then sends the output back to you.

How it works

Atexec.py connects to the target host over RPC and uses the Task Schedule Service to register a task. The task uses cmd.exe to run each command, and it redirects the STDOUT and STDERR to a temporary file in the ADMIN$ share. Atexec runs the task, then deletes it. Finally, it connects to the ADMIN$ share over SMB, retrieves the output file, and deletes it.

Using atexec.py

Atexec’s syntax is mostly the same as the previous tools, except that you must specify a command to run:

Using Atexec.py to execute a command

Bonus: Mssqlclient.py and xp_cmdshell

If you happen to find an MS-SQL server on a pentest, Impacket’s Mssqlclient.py is your best friend. Aside from being able to interact with the SQL server, it provides not one, but two ways to execute system commands:

The xp_cmdshell

The xp_cmdshell is an optional feature of MS-SQL servers that allows you to spawn a system shell and execute commands. It is disabled by default, but you may find it enabled on older versions of MS-SQL. Alternatively, if you have a high-privilege user, you can enable the xp_cmdshell and then use it to run commands. We can use Impacket’s mssqlclient.py tool to connect to and interact with MS-SQL servers and use the xp_cmdshell . Commands are executed with the privileges of the SQL service account.

sp_start_job

The sp_start_job command can be used to start SQL jobs, but it can also be abused to execute system commands. It’s important to note that this feature results in blind command execution, i.e. you don’t get any output back, so it’s important to build your commands and one-liners correctly. Commands are executed with the privileges of the SQL service account.

Using xp_cmdshell and sp_start_job

Unfortunately, I don’t have a MS-SQL server setup in the lab, and I’m running a bit low on disk space, so I wasn’t able to set up a demo for this one. However, there are some machines on HTB VIP that will allow you to practice these techniques if you’re interested. The commands are pretty simple:

mssqlclient.py SQL_USER:SQL_PASS@RHOST
SQL> enable_xp_cmdshell
SQL> disable_xp_cmdshell
SQL> xp_cmdshell SOMECOMMAND
SQL> sp_start_job SOMECOMMAND

It’s really pretty self-explanatory.

Conclusion

In this article, I’ve detailed a half-dozen ways to use Impacket to execute commands on remote Windows systems. Each tool works differently, and each has its advantages and disadvantages. In this article, I only addressed password authentication, but in my next article, I’ll cover using NTLM hashes, Kerberos tickets, and even AES keys to authenticate with these tools.

It’s worth noting some of these tools will almost certainly be caught by Windows Defender or other antivirus solutions depending on the vendor and how up-to-date the program is. If one tool gets caught, I recommend trying another until you find one that works (depending on if you’re trying to be stealthy :) ). In my experience, I’ve had Wmiexec.py or Smbexec.py slip past Windows Defender where Psexec.py has gotten caught.

Did you enjoy this article? Let me know what you think below!

--

--

Kyle Mistele

Student, hacker, OSCP. My other computer is your computer.