PowerShell: Updating Local Admin Passwords Securely (2 of 3)

 Below is an example of how to remotely (using PowerShell) update and change the Local Administrator password securely.  This is not my script, I received this script along with many others from the SANS SEC 505 course.  I have not altered it in any way.

Updating the Passwords of the Local Administrator on remote mahcines (You must have a Certificate either from your CA or another Certificate Authority):

This script will recover the local administrator password that you have created with the first part (1 of 3) which is decrypted by your Private Key Certificate.

Copy this text into a PowerShell Script called Recover_PasswordArchive.ps1


####################################################################################
#.Synopsis
# Recover the plaintext password from an encrypted file originally
# created with the companion script named Update-PasswordArchive.ps1.
#
#.Description
# Recover the plaintext password from an encrypted file originally
# created with the companion script named Update-PasswordArchive.ps1. The
# file is encrypted with a public key chosen by the administrator. The
# password generated by Update-PasswordArchive.ps1 is random. Recovery
# of the encrypted password from the file requires possession of the
# private key corresponding to the chosen public key certificate.
#
#.Parameter PasswordArchivePath
# The local or UNC path to where the encrypted password files are kept.
#
#.Parameter ComputerName
# Name of the computer with the local account whose password was reset
# and whose password was encrypted and saved to a file. The computer
# name will match the names of files in the PasswordArchivePath. This
# parameter can accept a computer name with a wildcard in it.
#
#.Parameter ShowAll
# Without this switch, only the most recent plaintext password is shown.
# With this switch, all archived passwords for the computer are shown.
# This might be necessary when the passwords of multiple local user
# accounts are being managed with these scripts.
#
#
#.Example
# .\Recover-PasswordArchive.ps1 -ComputerName LAPTOP47
#
# Displays in plaintext the last recorded password updated on LAPTOP47.
# The user running this script must have loaded into their local cache
# the certificate AND private key corresponding to the certificate used
# to originally encrypt the password archive files in the present
# working directory. A smart card may be used instead.
#
#.Example
# .\Recover-PasswordArchive.ps1 -PasswordArchivePath \\server\share -ComputerName WKS*
#
# Instead of the present working directory of the script, search the
# password archive files located in \\server\share. Another local
# folder can be specified instead of a UNC network path. The wildcard
# in the computer name will show the most recent password updates for
# all matching computer names in \\server\share.
#
#.Example
# .\Recover-PasswordArchive.ps1 -PasswordArchivePath \\server\share -ComputerName LAPTOP47 -ShowAll
#
# Instead of showing only the last password update, show all archived passwords
# in the \\server\share folder for the computer named LAPTOP47.
#
#
#Requires -Version 2.0
#
#.Notes
# Author: Jason Fossen, Enclave Consulting (http://www.sans.org/windows-security/)
# Version: 1.0
# Updated: 11.Nov.2012
# LEGAL: PUBLIC DOMAIN. SCRIPT PROVIDED "AS IS" WITH NO WARRANTIES OR GUARANTEES OF
# ANY KIND, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY AND/OR FITNESS FOR
# A PARTICULAR PURPOSE. ALL RISKS OF DAMAGE REMAINS WITH THE USER, EVEN IF
# THE AUTHOR, SUPPLIER OR DISTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF
# ANY SUCH DAMAGE. IF YOUR STATE DOES NOT PERMIT THE COMPLETE LIMITATION OF
# LIABILITY, THEN DELETE THIS FILE SINCE YOU ARE NOW PROHIBITED TO HAVE IT.
####################################################################################
Param ($PasswordArchivePath = ".\", $ComputerName = "$env:computername", [Switch] $ShowAll)

# Construct and test path to encrypted password files.
$PasswordArchivePath = $(resolve-path -path $PasswordArchivePath).path
if ($PasswordArchivePath -notlike "*\") { $PasswordArchivePath = $PasswordArchivePath + "\" }
if (-not $(test-path -path $PasswordArchivePath)) { "`nERROR: Cannot find path: " + $PasswordArchivePath + "`n" ; exit }

# Get encrypted password files and sort by name, which sorts by tick number, i.e., by creation timestamp.
$files = @(dir ($PasswordArchivePath + "$ComputerName+*+*+*") | sort Name)
if ($files.count -eq 0) { "`nERROR: No password archives for " + $ComputerName + "`n" ; exit }

# Get the latest archive file only, unless -ShowAll is used.
if (-not $ShowAll){ $files = @($files[-1]) }
# Load the current user's certificates and private keys.
$flags = new-object System.Security.Cryptography.X509Certificates.OpenFlags #ReadOnly
$store = new-object System.Security.Cryptography.X509Certificates.X509Store #CurrentUser
if (-not $? -or ($store.GetType().fullname -notlike "*X509Stor*")) { "`nERROR: Could not load your certificates and private keys.`n" ; exit }
$store.open($flags)
$certstore = $store.Certificates
$store.close()
if ($certstore.count -eq 0) { "`nERROR: You have no certificates or private keys.`n" ; exit }
# Process encrypted password archive files and $output objects.
foreach ($lastfile in $files) `
{
 $output = ($output = " " | select-object ComputerName,FilePath,UserName,TimeStamp,Thumbprint,Valid,Password)

$output.ComputerName = $($lastfile.Name -split '\+')[0]
 $output.FilePath = $lastfile.fullname
 $output.UserName = $($lastfile.Name -split '\+')[1]
 $output.TimeStamp = [DateTime][Int64]$($lastfile.Name -split '\+')[2]
 $output.Valid = $false #Assume password recovery will fail.
 $output.Thumbprint = $($lastfile.Name -split '\+')[3]
 # Check for password reset failure files.
 if ($output.Thumbprint -eq "PASSWORD-RESET-FAILURE")
 {
 $output.Password = "ERROR: Try to use prior password(s) for this computer."
 $output
 continue
 }
 # Read in password archive binary file.
 [byte[]] $ciphertext = get-content -encoding byte -path $lastfile.fullname
 if (-not $?)
 {
 $output.Password = "ERROR: Failed to read " + $lastfile.fullname
 $output
 continue
 }
 # Load the correct certificate and test for possession of private key.
 $certpriv = $certstore | where { $_.thumbprint -eq $output.thumbprint }
 if (-not $certpriv.hasprivatekey)
 {
 $output.Password = "ERROR: You do not have the private key for this certificate."
 $output
 continue
 }
 # Attempt decryption with private key.
 $plaintextout = $certpriv.privatekey.decrypt($ciphertext,$false) #Must be $false for my smart card to work.
 if (-not $?) { $output.Password = "ERROR: Decryption failed." }
 else { $output.Password = ([char[]]$plaintextout -join "") }
 # Confirm that archive file name matches the nonce string encrypted into the file.
 # Nonce helps to thwart attackers and can be used for troubleshooting too.
 if ($lastfile.name -like $output.Password.substring(0,60) + "*")
 {
 $output.Password = $output.Password.substring(60) #Strip out the 60-char nonce.
 $output.Valid = $true
 }
 else
 {
 $output.Password = $output.Password.substring(60) #Strip out the 60-char nonce.
 $output.Password = "ERROR: Integrity check failure: " + $output.Password.substring(60) + " (" + $output.Password + ")"
 }
 $output
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s