Frequently, PowerShell functions work with sensitive information, i.e. log-on information including passwords, and store this information in variables. Let’s assume a function like this to play with:

function Connect-Server
{
    param
    (
        [Parameter(Mandatory)]
        [pscredential]
        [System.Management.Automation.Credential()]
        $Credential
    )
    
    "You entered a credential for {0}." -f $Credential.UserName
    # now you could do something with $Credential
}

When you run this function, you get prompted for a credential and a password. Your information surfaces inside the function as $Credential, and when the function completes, the internal information is removed from memory automatically:

 
PS> Connect-Server -Credential tobias
You entered a credential for Tobias.

PS> $Credential

PS> 
 

However, any attacker could easily run the function dot-sourced. Now, all internal variables remain in memory after the function completed:

 
PS> . Connect-Server -Credential tobias
You entered a credential for Tobias.

PS> $Credential

UserName                     Password
--------                     --------
Tobias   System.Security.SecureString



PS> $Credential.GetNetworkCredential().Password
test

PS> 
 

As you see, the attacker now has access to the credential object and can also extract the original password.

To prevent this, you should manually remove sensitive data from memory again. You can remove variables using Remove-Variable:

function Connect-Server
{
    param
    (
        [Parameter(Mandatory)]
        [pscredential]
        [System.Management.Automation.Credential()]
        $Credential
    )
    
    "You entered a credential for {0}." -f $Credential.UserName
    # now you could do something with $Credential, i.e. submit it to
    # other cmdlets that support the -Credential parameter
    # i.e.
    # Get-WmiObject -Class Win32_BIOS -ComputerName SomeComputer -Credential $Credential    
    
    Remove-Variable -Name Credential
}

Now the variable can no longer be retrieved:

 
PS> Remove-Variable -Name Credential

PS> . Connect-Server -Credential tobias
You entered a credential for Tobias.

PS> $credential

PS>
 

Twitter This Tip! ReTweet this Tip!

Anonymous
  • But..But..But... this is a post exploitation thing, since the hacker would have already another avenue to get on your box remotely. Since they already have domain creds to logon to the box remotely, then, sure, but they already own the box with the creds the use to get the foothold or am I missing the point. Yet, sure, if you call / use / instantiate something in any environment, in any way, and you are done with it, the kill it/dump it/garbage collect it all. Not only because of this risk management need, but to release resources, so the next process, action, code and do its thing without interference from left behind junk.