Last updated at Tue, 27 Oct 2020 13:38:23 GMT
Late one night at Derbycon, Mubix and I were discussing various techniques of mass ownage. When Mubix told me about the WinRM service, I wondered: "Why don't we have any Metasploit modules for this yet?" After I got back , I began digging.
WinRM is a remote management service for Windows that is installed but not enabled by default in Windows XP and higher versions, but you can install it on older operating systems as well. WinRM's sister service is called Windows Remote Shell (WinRS). Both of these authenticated services are tied to an HTTP or HTTPS SOAP listener and support Kerberos and NTLM authentication by default. I started looking at NTLM authentication since it's already supported in Metasploit.
If you're setting up WinRM, please be aware that the default quickconfig setup will leave the service in an awkward, non-functional state. It will set AllowUnencrypted to false, meaning it will refuse to establish any sessions over HTTP without SSL. Unfortunately, the quickconfig setup will not configure the HTTPS listener. The user can now either set AllowUnecrypted to true or configure the HTTPS listener.
If the listener is HTTPS, some adjustments will need to be made to the module default options. Just set SSL to true, set SSLVersion to the correct SSL Version, and adjust RPORT appropriately. Default settings for the WinRM ports vary depending on whether they are encrypted and which version of WinRM is being used. In older versions of WinRM, it listens on 80 and 443 respectively. On newer versions, it listens on 5985 and 5986 respectively. Metasploit can connect to both HTTP and HTTPS ports; use the standard SSL options for HTTPS.
The listener has two back ends: The first one is WMI, which provides powerful querying of system information and remote management functionality. The second is a remote shell interface.
More information about WinRM can be found here.
Discovery (use auxiliary/scanner/winrm/winrm_auth_methods)
The first thing to build, was a basic discovery module that determines if a WinRM service is listening on a given HTTP(S) port. If it does, it also enumerates the supported authentication methods. The screenshot shows how the discovery module creates a service entry for WinRM with the authentication types included in the info.
Bruteforce (use auxiliary/scanner/winrm/winrm_login)
In this example, the service supports Negotiate (NTLM) authentication. However, we cannot do anything with WinRM without working credentials. The winrm_login module is a standard Metasploit login scanner to bruteforce passwords. After you supply a list of targets (HOSTS), the WinRM port (RPORT), and specify which credentials to try, it will attempt to find a working password for the service.
Running WMI Queries (use auxiliary/scanner/winrm_wql)
Once we have found valid credentials for the WinRM service, we can abuse the WMI functionality to execute arbitrary WQL queries against the target. The module will also save the query results as loot. In the example below, we run a WQL query to get the architecture of the remote system (32 or 64 bit).
Running Commands (use auxiliary/scanner/winrm/winrm_cmd)
WinRM's conjoined twin sister, WinRS, allows the user to instantiate a shell on the remote box, send commands, and receive output streams. Metasploit can send any arbitrary Windows command, and receive both STDOUT and STDERR, essentially providing a stateless shell over HTTP/SOAP.
It is important to note that WinRS shells have a maximum time to live before the service will close them out. The service also has a configurable concurrent command limit, but these don't matter in this case as we are only executing a single command and cleaning up the shell. Here, we execute a simple ipconfig command as an example.
Getting Shells! (use exploit/windows/winrm/winrm_script_exec)
Now we're in a great position to get shells. For many years, the PSExec module has been the main way of using system credentials to obtain a shell. This has become less and less reliable as many of the Metasploit Framework payloads are detected by anti-virus solutions. Metasploit Pro users have the option of dynamically generating EXE payloads, but this is not foolproof.
The advantage of the WinRM Script Exec exploit module can obtain a shell without triggering an anti-virus solution, in certain cases. This module has two different payload delivery methods. Its primary delivery method is through the use of PowerShell 2.0. The module checks to see if PowerShell 2.0 is available on the system. It then tries to enable unrestricted script execution, an important step because PowerShell does not execute unsigned script files by default. If either of these checks fail, it will default to the VBS CmdStager payload method, otherwise it will use our Powershell 2.0 method.
When using the PowerShell 2.0 method, the module writes the payload into a script file using the Append-Content cmdlet and executes it. This is where other payload delivery methods tend to get caught. The VBS Cmdstager PSExec, and other similar modules write out an EXE on the filesystem and run it. These EXEs often get picked up by AV. With the PowerShell 2.0 method, we are only dropping pure PowerShell onto the file system. These scripts do not appear to be flagged by any known AV.
We're not quite done yet - there's some more trickiness afoot. Remember that we said WinRS shells have a limited time to live. This means that any child processes spawned in that shell will also get killed inside 5 minutes, including our shell. The traditional migrate –f option is not an option. It creates the notepad.exe process, which is also a child of the shell, and therefore subject to the same limitation. We need an alternate migration method, to get out of that process tree. This is where the new smart_migrate Metasploit post-exploitation module comes in. SmartMigrate takes a snapshot of the process environment on the victim machine, grabbing the PIDs for winlogon.exe and any explorer.exe processes. It first attempts to migrate to Winlogon, a very stable system process for migration purposes and a highly desirable target. If we lack sufficient permissions, the module looks at the explorer.exe processes. If there is an explorer.exe process for our current user context it will try to migrate to that one first. If one does not exist within our current user context, it will go down the list trying each one. This clear, automated process helps successfully migrate the shell before WinRS times out.
With the PowerShell 2.0 method, it is important that you select an x64 payload if you are targeting an x64 system, otherwise you won't be able to obtain a session. If there is a mismatch between the remote architecture and your payload when using PowerShell 2.0, the module will not launch the exploit and warn you of the error.
If any of the initial checks failed, i.e PowerShell 2.0 installed, and an Unrestricted Execution Policy, we fall back to the VBS CmdStager. This method writes out two files to the filesystem. It writes out a base64 encoded copy of the actual payload, and a VBScript file. The VbScript file is then executed. It decodes the base64 files and writes out an exe. The VbScript then executes the EXE it has written out. This method is far less stealthy as it involves actually writing an EXE to the filesystem. It is a reasonable fallback position though, as VBS should be available on any system that does not support PowerShell. This method still requires the same migration as the Powershell 2.0 method.
We hope you've had fun abusing the WinRM/WinRS service with Metasploit. What we have seen here is only the begining of what can be accomplished with WinRM in Metasploit. We expect to see more WinRM modules in the futures. Also, the discovery, bruteforce, and exploit modules will soon be integrated into Metasploit Pro's automated features. Metasploit Pro users will be able to discover WinRM services, bruteforce WinRM services, and use the script_exec module to to gain a shell using credentials.