Friday, March 6, 2015

CANVAS - Psexec & Kerberos credentials

With the recent release of MS14-068 it became quite clear that a PSEXEC (sysinternals) module would be a fine addition in CANVAS. We wrote and released in CANVAS 6.99 a quite simple yet rather effective one with a couple of fine features.

1. PSEXEC and its basics

First of all let us remember how the original SysInternals tool works. A remote command (be it interactive or not) is executed following this procedure:

  • The PSEXEC client extracts out of its own binary a Windows service (PSEXESVC.exe) and uses the current user token (or alternate credentials) to store it in one of the writable SMB shares of the target, usually ADMIN$.
  • The client then uses the DCE/RPC API associated with the SVCCTL named pipe to create a Windows service associated with PSEXESVC.exe. This obviously requires ADMIN privileges on the remote host.
    • The client remotely starts the service.
    • Once started this service creates a control pipe (\PSEXESVC) on the target.
  • The client remotely opens this pipe using the SMB API. It reads and writes on it following an internal protocol.
    • An internal cookie is used to ensure that both the client and the server are using a same version of the protocol (this is mandatory in case the Windows service would be left running on the target). 
    • The service gets the knowledge of various options requested by the client such as the command to execute, if the command should be run with lower privileges, etc.
  • The service creates 3 named pipes and starts a new process whose STDIN, STDOUT and STDERR file descriptors may be redirected to the 3 aforementioned pipes.
  • The client connects to the 3 pipes using the SMB API and initiates a read polling on STDOUT/STDERR pipes. If necessary (CMD.exe), it will also write to the STDIN pipe.
  • When the new process' life is over, the service may be stopped and destroyed.
  • The service binary may be removed from the share.
That said, people usually either use PSEXEC to:
  • Execute a command (RCE)
  • Start CMD.exe (interactive shell)
For obvious reasons, in a security context such as a penetration test they rarely use the Desktop interaction feature.

2. Our PSEXEC module

2.1. Implementation of the RCE/interactive shell features

We chose to keep the original PSEXEC named pipes polling model to implement the RCE functionality in our module. This was not strictly mandatory as other ways to do this exist. MSF for example relies on the redirection of the standard output in a file which is later downloaded using SMB. We decided to use named pipes in order to anticipate future needs (and avoid leaving files on disk in the event of a disconnection, which is slightly better OSPEC). On the other hand, we decided to use a traditional MOSDEF connect back to mimic the interactive shell. This is exactly what was implemented in our MS14-068 exploit.

Both methods have their pros and cons:
  • The RCE only requires a client connection to the 445 TCP port. However the pipe management is not 100% perfect and side effects may sometimes be observed with the current version. 
  • The MOSDEF shell is quite powerful (it includes the RCE and interactive shell abilities) but may not be possible if egress filtering is used. While you might eventually be able to disable the Windows firewall of your target using the RCE, there is nothing you could do against an external equipment.
Note: The choice between both of them is done by filling the "cmd" parameter. If "mosdef" is specified, then the MOSDEF connect back is used otherwise what ever command is specified will be executed (if possible).

2.2. The authentication in SMB

This module provides two ways to authenticate the user:
  • Using NTLMSSP (login + password)
  • Using Kerberos (login + password + domain OR login + domain + credential file)

The NTLMSSP authentication may use the plaintext password or the NTLM hash of the password. This is the so called pass-the-hash technique as shown below:

Computing the NTLM hash

Using the NTLM hash in the CLI

The Kerberos authentication is used in two cases:

  • Implicitly as a fallback method if the NTLMSSP fails (this can happen with domain policies enforced) but only if the user had also specified the domain FQDN (which is not mandatory with NTLMSSP).
  • Explicitly if we have Kerberos credentials (potentially retrieved using post-intrusion tools) and we intend to use them. We decided that these credentials would always be stored in a UNIX ccache file because we had done the effort to write an API for MS14-068. 
To illustrate the situation, let's generate artificial ADMIN credentials (basically the TGT of the domain administrator) using kinit in the IMMU4.COM domain:

Artificially generating a Kerberos TGT
We can then fill the appropriate field in CANVAS to specify these credentials:

Using a Kerberos credential file to compromise the target
And we finally get our node popping:

Target is owned!

2.3. Upload and execution of a specific binary

In a few cases, you may want to run your own binary on the target. Our module will take care of both the upload and the execution of this specific binary. It will basically be seen as a specific RCE.

Several options may be specified either on the command line or using the GUI:
  • The command and argument to execute (cmd)
  • The local directory in which is stored the binary to upload (local_upl)
  • The directory in which should be stored the binary once uploaded (remote_path_upl)
For example, suppose the user is running this command:

$ python exploits/psexec/ -t -p 445 -Ocmd:"mybinary mybinaryargument" -Ouser:administrator -Odomain:IMMU2.COM -Okrb5_ccache:/tmp/krb5cc_1000 -Olocal_upl:/tmp/BABAR -Oremote_path_upl:"C:\\"

Then /tmp/BABAR will be uploaded in C:\\ as mybinary.exe (the .exe suffix being automatically added) and executed from this directory.

3. Stealing credentials using "kerberos_ticket_export"

We wrote a command module that allows us to detect the presence of kerberos credentials on both Windows and Unix targets. This module is used to list the credentials that are associated with a compromised account under which is running the MOSDEF callback:
  • If the node is a Linux/BSD system, all the Kerberos tools will be using standard MIT libraries which store credentials in specific directories (for example /tmp/krb5cc_%{uid} on Ubuntu/FreeBSD).
  • If the node is Windows we use LsaCallAuthenticationPackage() in a MOSDEF-C payload.
Here is a little demo:

We also wrote a similar module to actually extract the tickets and convert them (if necessary) to ccache files. This is where PSEXEC comes to play. Both modules are quite similar:
  • Exporting credentials on Unix systems basically means copying a file that we can immediately reuse. The ccache file may include a TGT but also one of several TGS.
  • On Windows systems, we are (currently) limited to TGT extraction. Basically we keep using LsaCallAuthenticationPackage but with different parameters. This may allow you to extract the TGT and the associated session key. In a couple of circumstances and for security reasons that we may explain in another blogpost, the session key cannot always be retrieved in which case the TGT is useless. Once the TGT, the session key, and other parameters are extracted, we use our ccache API to build and store the tickets locally (in a session directory).
The following screenshot illustrates the ticket extraction:

Ticket is extracted and saved (oops small typo in the module code :P)

And the subsequent use of PSEXEC to own a new node:

The previous relative path is specified (although cut by the GUI here)

4. Last words

The Kerberos ticket modules are currently in an early stage of development. There is lots of room for improvement including full 64 bits support, corner case situations and privileged account related tricks. As for the PSEXEC module itself, we may add a couple of features such as a "runas" option.