• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

War Room

Shells from above

RSM logo

  • Home
  • About
  • Blog
  • Talks/Whitepapers
  • Tools
  • Recreation
Home > Offense > Leveraging MS16-032 with PowerShell Empire

Leveraging MS16-032 with PowerShell Empire

July 6, 2016 By Mike

It’s not very often in the life of a pentester that you find a point-and-click exploit that works right out of the box. Most public scripts are simple proofs of concept that don’t work in every scenario and must be modified to perform the desired action. In fact, the OSCP course from Offensive Security has a big section dedicated to altering existing code to make it work for a specific OS or version. This came in handy recently as I had to modify an exploit to get it to work well within PowerShell Empire.

The MS16_032 vulnerability is extremely useful for several reasons. First, it is possible to execute a confirmed privilege escalation exploit on a variety of different Windows systems (Vista through Windows 10!) where the exposure is unpatched. Secondly, it does not involve any risky memory corruption techniques which may compromise a limited foothold. Finally, this vulnerability is a fairly recent release (only three months old at the time of this writing) and is likely to continue to be out in the wild for some time.

At RSM we regularly utilize Empire to navigate laterally around a compromised network. One of the most useful functions within Empire involves executing a PowerShell script on a host which creates a backdoored process known as an ‘agent’. While MS16-032 currently has a PoC powershell exploit available, the payload only triggers a local command prompt to pop up with SYSTEM privileges. This is very useful if you have physical or RDP access to the machine but not that helpful when it comes to interacting stealthily using Empire.

The exploit on Exploit-DB uses a pair of Windows API calls to check to see if the new process has a privileged token:

        # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED
        $CallResult = [Advapi32]::CreateProcessWithLogonW(
            "user", "domain", "pass",
            0x00000002, "C:\Windows\System32\cmd.exe", "",
            0x00000004, $null, $GetCurrentPath,
            [ref]$StartupInfo, [ref]$ProcessInfo)

 

As you can see this example simply created the cmd window as discussed above. In order to figure out exactly how this process worked, I consulted MSDN which had a very convenient page outlining each argument of the function call. At first I wanted be able to pass it an arbitrary command from within Empire. I added the following lines at the top:

param (
[Parameter(Mandatory = $True)] [string]$Cmd
)

 

and then modified both API calls to use powershell to execute the input:


# LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED
$CallResult = [Advapi32]::CreateProcessWithLogonW(
"user", "domain", "pass",
0x00000002, "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe", $Cmd,
0x00000004, $null, $GetCurrentPath,
[ref]$StartupInfo, [ref]$ProcessInfo)

Success! I could now use this script to execute commands with administrator privileges (e.g. adding a new administrator). Now the tricky part came when I wanted to actually create an Empire agent with SYSTEM privileges without having desktop access.

Empire has a feature that allows you to import your own custom PowerShell scripts by using the scriptimport command from an active agent’s menu. Once you load your custom PS file in memory, you can tab complete the functions by using scriptcmd.

script import
Importing custom Powershell scripts in Empire

In order to get an agent to run, I tried passing the default launcher staging output as a parameter but that failed. My guess was that the encoded string was just too long, so I decided to try it without the Base64 encoding. The one-liner without encoding is very ugly looking, so I had to use Python string replace() to fix all of the nasty characters before it would work as a parameter.

shell1
Success! An agent is sent back to our listener.

 

shell2
The agent is running with SYSTEM privileges!

 

The final working code can be found below. Remember that the stager output must NOT be Base64 and must have all quotes and $ characters properly formatted to be literals.

Share this...
  • Reddit
  • Email
  • Facebook
  • Twitter
  • Linkedin

Mike

Penetration tester and former educator.

Primary Sidebar

Categories

  • Defense
  • Forensics
  • Offense
  • Physical
  • R&D

Most Viewed Posts

  • DLL Injection Part 1: SetWindowsHookEx 10.8k views
  • Sophos UTM Home Edition – 3 – The Setup 10.8k views
  • Leveraging MS16-032 with PowerShell Empire 10k views
  • Bypassing Gmail’s Malicious Macro Signatures 9.8k views
  • How to Bypass SEP with Admin Access 8.9k views

Footer

  • RSS
  • Twitter
  • Tools
  • About
  • RSM US LLP

+1 800 903 6264

1 S Wacker Dr Suite 800
Chicago, IL 60606

Copyright © 2023 RSM US LLP. All rights reserved. RSM US LLP is a limited liability partnership and the U.S. member firm of RSM International, a global network of independent audit, tax and consulting firms. The member firms of RSM International collaborate to provide services to global clients, but are separate and distinct legal entities that cannot obligate each other. Each member firm is responsible only for its own acts and omissions, and not those of any other party. Visit for more information regarding RSM US LLP and RSM International.