PRIMARY CATEGORY → WINDOWS PRIVESC   •   WINDOWS CREDENTIAL HUNTING

Theory

Powershell Credential Objects ( PSCredentials ) are often used for scripting and automation tasks

These objects store plain credentials that are subsequently encrypted by Windows Data Protection API ( DPAPI ), which usually means that this type of object can only be decrypted by the same user on the same computer where it was created on

This Powershell Credential Objects are typically stored within XML files, which are generated using the Export-Clixml PS cmdlet


Enumeration

In this case, since we do not know how a sysadmin or developer might refer to these XML files containing a PSCredential object, we can simply look for any existing XML file in the system that contains the strings below

Pattern Strings
System.Management.Automation.PSCredential
PSCredential
<SS N="Password">
<S N="UserName">
Looking for PSCredential Objects

PS

Get-ChildItem -Path C:\ -Recurse -File -Filter '*.xml' -ErrorAction SilentlyContinue | Select-String -Pattern 'System.Management.Automation.PSCredential','PSCredential','<SS N="Password">','<S N="UserName">' -SimpleMatch | Select-Object -ExpandProperty Path -Unique

Retrieving Plain Credentials from a PSCredential Object

Workflow

Imagine we achieved to access the remote system by leveraging an existing flaw on the web application which allowed us to send a reverse shell to our TCP listener

Once we are in, the first occurrence is to check the privileges associated with the current access token as we have a shell as the service account running the web application, which is likely to have the seImpersonatePrivilege

whoami /priv

But this time there is no luck 💀

The current user does not have any sensitive privileges and is not member of any interesting group

So we continue searching throughout the system to see if anything can help us to achieve privesc, until we find an XML file that contains a PSCredential object

This file appears to be the result of running the Export-CLIXML cmdlet, which exports a PSCredential object to an XML file

Therefore, whenever we deal with an XML file resulting from a Powershell CLI-XML operation, we can proceed as follows in order to obtain the plain password from the PSCredential object

Abuse - Windows
Importing the PSCredential Object from CLI-XML file into a PS Variable

Import-CLIXML

$encCred = Import-CLIXML -Path '<XML_FILE>'
Extracting Username and Plain Password from the PSCredential Object

GetNetworkCredential

$encCred.GetNetworkCredential().username
$encCred.GetNetworkCredential().password