Cyber Defense

Reset Local Administrator Password Using A Different Random String On Each Computer And Recover The Passwords Securely

-

The passwords of local administrative accounts should be changed regularly and these passwords should be different from one computer to the next. But how can this been done securely and conveniently? How can it scale to thousands of computers? And how can this be done for free?

The Securing Windows and PowerShell Automation course at SANS (course SEC505) includes free PowerShell scripts to manage local account passwords. Download the scripts in the SEC505 zip file, then look inside that zip archive for the \Day4-Admins\UpdatePasswords folder.

These PowerShell scripts are intended to be relatively easy to understand and modify, you don't have to be a PowerShell guru, just have some basic familiarity. Like all scripts in the SEC505 zip file, these scripts are in the public domain too.

If you would prefer a non-PowerShell commercial product to manage admin passwords, here are few to consider:

What about Microsoft LAPS?

There is also Microsoft's own Local Administrator Password Solution (LAPS), which is free too. You can get technical support when using LAPS, and it comes with a GUI client for admins as well as a PowerShell module too.

However, note that LAPS 1) stores passwords in plaintext in the Active Directory database, using AD permissions to restrict access to the passwords, 2) requires an update to the Active Directory schema, 3) requires a Group Policy client-side extension to be installed (an MSI package) on all managed hosts, except for Server Nano, 4) is not for stand-alone servers or workstations because of the Active Directory and Group Policy components, 5) can only be used to manage a maximum of two local user accounts on each machine, no more, 6) we don't have access to the C++ source code of the LAPS client-side extension if we need to customize it, and 7) though the LAPS tools themselves encrypt passwords while in transit over the network, admins must take care to use network encryption when using other tools when reading the passwords out of AD, e.g., a third-party utility might use LDAP in plaintext by default (this has nothing to do with LAPS per se, it's only something to be aware of).

The solution presented below never stores or transmits passwords in plaintext, not even temporarily, does not require an Active Directory schema update (or AD for that matter), does not require a Group Policy extension, works on stand-alone computers, can manage any number of local user accounts, you have access to the PowerShell source code for inspection or customization (it's in the public domain), and it works with any SMB server, including Samba and FreeNAS.

However, the solution does require, at a minimum, PowerShell to be installed and enabled on every managed host, and it scales best in an Active Directory environment with Group Policy. You will also need a digital certificate, either self-signed or from a PKI, but this is a good thing because it uses the public key from the certificate for encryption.

Solution

A trusted administrator should obtain a certificate and private key, then export that certificate to a .CER file into a shared folder (\server\share\cert.cer). Any certificate from any source for any intended purpose will do, but a 2048-bit RSA public key (or larger) from one's own PKI is preferred.

Copy the Update-PasswordArchive.ps1 script into that shared folder (\server\share).

Using Group Policy, SCCM, a third-party EMS, schtasks.exe or some other technique, create a scheduled job on every computer that runs once per week (or every night) under Local System context which executes the following command:

powershell.exe \server\share\update-passwordarchive.ps1 `
-certificatefilepath \server\share\cert.cer `
-passwordarchivepath \server\share `
-localusername Administrator

This resets the password on the local Administrator account (or whatever account is specified at the command line) with a 15-25 character, random complex password. The password is encrypted in memory with the public key of the certificate (cert.cer) and saved to an archive file to the specified share (\server\share).

When a password for a computer (for example, laptop47) needs to be recovered, the trusted administrator should run the following PowerShell script at their local computer:

recover-passwordarchive.ps1 -passwordarchivepath \server\share `
-computername laptop47 -username administrator

This downloads the necessary encrypted files, decrypts them locally in memory using the private key of the administrator, then outputs the plaintext password within PowerShell. The password can then be piped into other commands to open an RDP session, copy files, execute another command, etc.

Requirements

PowerShell 2.0 or later must be installed on both the computer with the local user account whose password is to be reset and also on the administrators' computers who will recover these passwords in plaintext.

The Update-PasswordArchive.ps1 script, which resets the password, must run with administrative or Local System privileges.

The private key for the certificate cannot be managed by a Cryptography Next Generation (CNG) key storage provider, such as the Microsoft Software Key Storage Provider. However, the universally-supported Microsoft Enhanced Cryptographic Provider is compatible, which is often the default for certificates anyway.

Also, the certificate you use must have the "Key Encipherment" purpose in the "Key Usage" list in the properties of that certificate (see the Details tab). You get this when the template for the certificate on the Certification Authority (CA) has "Encryption" listed as an allowed purpose in the properties of that template (see the Request Handling tab in the properties of the certificate template).

Note that the scripts are not compatible with FIPS Mode being enabled in Windows.

Testing Example

From the SEC505 zip file, copy the Day4-Admins\UpdatePasswords folder to your hard drive.

In File Explorer, double-click the "Password-is-password.pfx" file to import the test certificate and private key into your current user store (accept all the defaults). The password is "password".

Open PowerShell with administrative privileges and run this command to reset the password on the Guest account:

.\Update-PasswordArchive.ps1 -LocalUserName Guest -CertificateFilePath .\PublicKeyCert.cer

Do a "dir" listing and you will see a new file with a very long name, similar to the following:

MYCOMPUTER+Guest+635108515647128197+F5FF0247B0CF6A81148CE83D2EBA4A141CB095F3

If you open the file in Notepad or a hex editor, you'll see that it has been encrypted with the public key in the PublicKeyCert.cer file. The private key for this public key has already been imported into your local user certificate store, hence, you can use your private key to extract the password from the encrypted file. Unless hackers have stolen your private key, they will not be able to decrypt the file and obtain the password inside it.

To obtain the plaintext password, run this command:

.\Recover-PasswordArchive.ps1 -ComputerName $env:computername -UserName Guest

The output is an object with the plaintext password and other properties, similar to this:

ComputerName : MYCOMPUTER
FilePath : MYCOMPUTER+Guest+635108515647128197+F5FF024E83D2EBA4A141CB095F3
UserName : Guest
TimeStamp : 7/31/2015 7:12:44 AM
Thumbprint : F5FF0247B0CF6A81148CE83D2EBA4A141CB095F3
Valid : True
Password : TheRandomComplexPassword

The password property can now be piped into other commands or copied into the wetware clipboard through your retina.

To see the full help for this script, run:

get-help -full .\Update-PasswordArchive.ps1

 

Notes

The password is never sent over the network in plaintext, never saved to disk in plaintext, and never exposed as a command-line argument, either when resetting the password or when recovering it later. The new password is generated randomly in the memory of the PowerShell process running on the computer where the password is reset. The process runs for less than a second as Local System as a background process.

Different certificates can be used at different times, as long as their private keys are available to the administrator. When recovering a password, the correct certificate and private key will be used automatically, even if multiple certificates are in use. A smart card can be used too. The script has been successfully tested with the Common Access Card (CAC) used by the U.S. military and DoD.

If the shared folder is not accessible to the computer when the scheduled job runs, the password is not reset.

If multiple administrators must be able to recover the plaintext passwords, export the relevant certificate and private key to a PFX file and import it into each administrator's local profile. Because this is not a certificate used to uniquely identify a person or device (non-repudiation is not an intended feature), everyone on the help desk could have a copy of its private key.

To delegate authority to different administrators over different computers, then simply use different public/private key pairs. When using Group Policy to create the scheduled job on the machines in an organizational unit, for example, any certificate can be specified, and this does not have to be the same certificate used for all machines in a domain. The corresponding private keys can be shared with whatever subset of administrators is desired. If the private key is on a smart card, that card can be physically protected from unauthorized admins.

The password update script writes to the local Application event log on the machine where it runs (Source: PasswordArchive, Event ID: 9013). When the password is used to log into the computer, this can also be logged if the appropriate audit policies are enabled. The SEC505 zip file includes another script (SendTo-SysLog.ps1) if you'd like to modify the update script to also send a syslog message whenever the script runs.

The script can only be used to reset the passwords of local accounts, not domain accounts in Active Directory, though it could be modified for this purpose.

 

Threats

Keep the private key for the certificate used to encrypt the password archive files secure, such as on a smart card. This is the most important factor. Do not use the sample keys provided here for anything other than testing.

If the private key for the certificate is compromised, create a new key pair, replace the certificate file (.CER) in the shared folder, and immediately remotely trigger the scheduled job on all machines using Group Policy, schtasks.exe or some other technique. Once all passwords have been changed, the fact that the old private key has been compromised does not mean any current passwords are known.

Use an RSA public key at least 2048 bits in size. The public key encrypts the random 256-bit Rijndael key in each file which is used to encrypt the password in that file. Each archive file has a different Rijndael key. RSA and Rijndael are used for backwards compatibility (using AES explicitly requires .NET Framework 3.5 or later). Rijndael was selected by NIST for the AES cipher.

Prevent modification of the Update-PasswordArchive.ps1 script itself by digitally signing the script, enforcing script signature requirements, and using restrictive NTFS permissions. Only allow NTFS read access to the script to those identities (computer accounts) which need to run it. Use NTFS auditing to track changes to the script.

Attackers may try to corrupt the existing password archive files to prevent access to current passwords. Each archive file contains an encrypted SHA256 hash of the username, computername and password in that file in order to detect bit-flipping attacks; the hash is checked whenever a password is recovered.

To deter file deletion, it's best to store the certificate and archive files in a shared folder whose NTFS permissions only allow the client computer accounts the following permissions:

Principal: Domain Computers
Apply to: This folder, subfolders and files
Allow: Full Control
Deny: Delete subfolders and files
Deny: Delete
Deny: Change permissions
Deny: Take ownership
Deny: Create folders/append data

Principal: Domain Computers
Apply to: Files only
Deny: Create files/write data

The trusted administrators can be granted Full Control to the archive files, certificates, and scripts as needed of course. The above permissions are for just for Domain Computers.

An attacker might try to generate millions of spoofed archive files and add them to the shared folder. This is possible because the script and public key would be accessible to the attacker too. NTFS auditing on the share can log which computer(s) added the spoofed files and when. The archive files might be digitally signed, but with what key? We must assume the attacker can extract any signing keys from kernel memory on the computers they have already compromised. Realistically, though, a DoS attack in which millions of new archive files are created would likely be of low value for the attacker since it would be easy to detect, easy to log the name or IP of the machine creating the new files, easy to use timestamps in the share to identify post-attack files, nightly backups of the archive files can be retained for 30+ days, and the DoS attack would not allow the hacker to expand their existing powers to new machines. Besides, the benefit to us of managing local administrative account passwords correctly far exceeds the potential negative of this sort of DoS attack.

IPSec permissions which limit access to the SMB ports of the file server is recommended, but not for the encryption, but for restricting access to the SMB ports (TCP 139/445) based on group memberhips, e.g., domain computer, administrators, help desk personnel, etc.

 

Tips

The output of the Recover-PasswordArchive.ps1 script can be piped into other scripts to automate other tasks which require the plaintext password, such as executing commands, doing WMI queries, opening an RDP session, or immediately resetting the password again when finished.

When recovering a password, you can pipe the password into the built-in clip.exe utility to put the password into the clipboard, like this:

\controller\password-archives\Recover-PasswordArchive.ps1 `
-PasswordArchivePath \controller\password-archives -ComputerName laptop47 `
-UserName Administrator | select-object -expandproperty password | clip.exe

What prevents an endless accumulation of encrypted password archive files in the shared folder? The CleanUp-PasswordArchives.ps1 script will remove older or obsolete archive files which are no longer needed. Run this script as a scheduled job once per month. See the help in that script for its command-line parameters to customize what it deletes, e.g., by default it keeps the last five password archive files for each computer and username combination, but this can be changed.

To optimize the performance of the Recover-PasswordArchive.ps1 script when there are more than 100,000 files in the folder containing the password archives, disable 8.3 file name generation and strip all current 8.3 names on the volume containing that folder. Search the Internet on "fsutil.exe 8dot3name" to see how.

To maximize fault tolerance and scalability, use Distributed File System (DFS) shared folders across two or more servers, and back up the folder at least weekly. With DFS and Group Policy management of the scheduled jobs, the solution can scale to large networks.

The solution works on stand-alone computers as well, but the scheduled task, shared folder, and permissions will need to handled appropriately; for example, a wrapper script will likely be needed to automate the creation of the scheduled task and the copying of the encrypted password file to some kind of archival server, perhaps via FTP or secure copy.

You can also perform an immediate password update with commands like these, but wrapped in a function or placed in another script:

Copy-Item -Path .PublicKeyCert.cer -Destination \laptop47\c$ 

Invoke-Command -ComputerName laptop47 -filepath .Update-PasswordArchive.ps1 -argumentlist "C:publickeycert.cer","Administrator","c:"

Copy-Item -Path \laptop47\c$\laptop47+Administrator+* -Destination C:LocalFolder

Remove-Item -Path \laptop47\c$\PublicKeyCert.cer

Remove-Item -Path \laptop47\c$\laptop47+Administrator+*

The above Invoke-Command can be done by specifying UNC paths instead, but this requires delegation of credentials to the remote computer, which is not ideal for limiting token abuse attacks, so the certificate and archive files should be copied back-and-forth manually. Besides, wrapped in a function or script with some error-handling code, all these steps would be hidden from us anyway.

Do not use the sample certificate and private key provided with these scripts. You must obtain your own key pair and never share your private keys with outsiders.

Each password archive file name includes a ticks timestamp number. To manually convert the ticks timestamp in the file name (e.g., 635093865618276588) to a human-readable date and time in PowerShell, run this command:

[DateTime][Int64] 635093865618276588

If all the password archive files are moved to another volume, it would be convenient to reset the NTFS LastWriteTime property of the archive files to match the ticks timestamp in the archive file names themselves, such as with this command:

dir *+*+* | foreach { $_.LastWriteTime = [DateTime][Int64] $(($_.Name -split '+')[2]) }

Update History

24.Sep.2013: Thanks to Timothy Carroll for uncovering a formatting bug in the password generator found in Update-PasswordArchive.ps1. The fix does not affect compatibility with earlier versions of the other scripts or with previously-created encrypted password files.

25.Sep.2013: Added support for the minimum and maximum length of the random password generated.

13.Nov.2013: This is a breaking change from the prior 2.x versions. This update adds much improved support for keyboards and code pages outside of US-EN for international users, each encrypted archive file now includes an SHA256 hash for integrity checking, and a StatusMessage property has been added to the output for troubleshooting and easier international conversions.

16.Nov.2013: Removed a dependency on .NET Framework 3.5 which, unfortunately, also changed the file format again, hence, at version 4.0.

20.May.2014: Updated notes and scripts about incompatibility with CNG key storage providers. Thanks to Daniel F. for the heads up.

9.Jun.2015: Updated notes and scripts to warn about certificates not having the Key Encipherment allowed usage.

3.Sep.2015: Added a few notes about Microsoft LAPS.

22.Oct.2015: Added a note about FIPS Mode incompatibility.

 

Caveats & Legal Disclaimers

The scripts are free and in the public domain, you may use it for any purpose whatsoever without restriction. However, that being said...

THESE SCRIPTS ARE 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 DO NOT DOWNLOAD OR USE THE SCRIPTS. NO TECHNICAL SUPPORT WILL BE PROVIDED.

43 Comments

Posted September 5, 2013 at 12:47 PM | Permalink | Reply

OldguardMD

Would it be more secure to encrypt with ECDH based keys (Elliptic Curve) instead of RSA'' I have not seen an example of how to encrypt using ECHD using Powershell, but hope to find one and amend the script you have supplied in this article.

Posted September 9, 2013 at 4:09 PM | Permalink | Reply

Jason Fossen

Hi OldguardMD:
RSA is used for backwards compatibility, and a 4096-bit RSA key should last a while. In a few years when everyone is running a more recent version of the .NET Framework, I plan to change the ciphers.
Cheers,
Jason

Posted September 9, 2013 at 2:27 AM | Permalink | Reply

stephen

As far as I know, no matter how strong the password is, you can break it in seconds with PCUnlocker Live CD.

Posted September 9, 2013 at 3:59 PM | Permalink | Reply

Jason Fossen

Hi Stephen:
With properly-implemented whole disk encryption under the right circumstances, it wouldn't be possible to boot to another OS and reset a local account's password. Also, we have to worry about not just physical theft of portables, but also internal PCs and hackers who are try to leapfrog laterally from one box to another, in which case having a different local admin password on every computer is useful.
Cheers,
Jason

Posted October 22, 2013 at 3:22 PM | Permalink | Reply

Timothy Carroll

I created a management pack for OpsMgr for this script. With it, you can set up a server to monitor your password file location for problems. It will raise an alert if it sees any error files. It also does a check against your local Active Directory to see if any computers in your domain have not had a password set by the script. You can set up a list of computers you want the MP to ignore for computers that shouldn't be managed by the script, such as domain controllers. Download link is here: http://d-h.st/pGT
To use, you need to set up a registry entry on the computer you want to do the monitoring. Discovery runs once per day, so if you want immediate discovery, set the registry key before installing the MP.
HKLMSoftwareLocalPasswordResetScript
There is one mandatory and one optional value.
MonitoredFilePath: [REG_SZ] MANDATORY. This is the path to the folder where the password files are stored.
IgnoreComputers: [REG_MULTI_SZ] Optional. This is the list of computers to ignore for missing password monitoring. Enter one computer name per line. The name should be the name of the object in Active Directory, not the DNS name.

Posted December 30, 2013 at 8:19 PM | Permalink | Reply

Eddie

I ended up setting up a batch script that prompts for the computer ID to be entered first before a decryption of the admin password occurs. This eliminates the need to manually change the computer id in your script each time you need to run it.
*******************************************************************************
@ECHO OFF
SET /P computername=Please enter Computer Name for Admin Password Decryption:
powershell.exe \\uncpathRecover-PasswordArchive.ps1 -PasswordArchivePath \\uncpath -ComputerName %computername% -UserName Administrator
PAUSE
*******************************************************************************
Putting a pause will allow the command prompt window to stay open if you need to mark the password and copy it to a clipboard.

Posted August 27, 2014 at 11:44 AM | Permalink | Reply

Rich

Pardon my ignorance here, but I have a question. This solution is great and I'm eager to implement it. However, is there a way to encrypt the files using a key which any of ten or so administrators could use to decrypt whatever machine's password when needed?
Or is the only solution to this to have a shared account which would be used for encryption and decryption?

Posted August 28, 2014 at 2:48 AM | Permalink | Reply

Jason Fossen

Hello Rich:
Yes, just share the private key of the cert which is used to encrypt the passwords. Import that cert and private into the user profiles of the admins who need it. No need for a shared user account. This cert is not used for identification, authentication or non-repudiation in any way, so it's OK to share the private key with multiple (trusted) administrators.
Hope this helps! Best Regards, Jason

Posted February 3, 2015 at 4:17 PM | Permalink | Reply

Hugh

If I were to update this to use a remote call to the computer (so that the script can be run from a central job scheduler), what level of encryption does the WinNT provider offer?
I did a quick Wireshark trace and see the password operation described in clear text but the password itself isn't readable (though it may be a hash, which would be just as bad).
I see a similar question posed here but the answer seems to be LDAP specific and therefore might not apply to the SAM scenario.
https://groups.google.com/forum/#!topic/microsoft.public.windows.powershell/pSgW-9ydj2k

Posted February 22, 2015 at 2:49 PM | Permalink | Reply

Jason Fossen

Hi Hugh:
Great questions! For security reasons, the current script does not remotely reset passwords, it is always done in memory of the target computer, encrypting the password with a public key before the ciphertext is transmitted over the network for archival. If you want to remotely trigger the reset, it's best to use PowerShell remoting. Also, if I remember correctly, the WinNT provider you mention requires NTLM authentication (at least in the past) and not Kerberos, but it's better to migrate away from any dependencies on NTLM going forward. If you must, then another option is always use IPSec when doing the remote reset. Hope this helps!

Posted February 20, 2015 at 3:14 PM | Permalink | Reply

mike

What about Linux bash script for recovering the password? (Recover-PasswordArchive.ps1)
Anyone has written such a thing may be?

Posted February 22, 2015 at 2:39 PM | Permalink | Reply

Jason Fossen

None that I know of, but it would be great to have!

Posted February 26, 2015 at 12:28 PM | Permalink | Reply

mike

Following is a proof-of-concept script one can use as a starting point for writing a password recovery Linux bash script.
Please note that:
* it assumes RSA public key size is 4096
* I modified the Update-PasswordArchive.ps1 script to be more compatible with OpenSSL, however it is still compatible with Recover-PasswordArchive.ps1 (tested on Windows 8.1)
* ISO10126 padding is deprecated ''" replaced with PKCS7:
$Rijndael.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
''" $Rijndael.Padding = [System.Security.Cryptography.PaddingMode]::ISO10126
* explicit keysize and blocksize:
$Rijndael.KeySize = 256
$Rijndael.BlockSize = 128
* it is not necessarily secure to run

Posted March 20, 2015 at 11:24 AM | Permalink | Reply

mike

Following is a proof-of-concept script one can use as a starting point for writing a password recovery Linux bash script:
https://github.com/mikiemike4420/sec505linux

Posted March 23, 2015 at 5:33 PM | Permalink | Reply

mike

Running the powershell script like this (as suggested):
powershell.exe \\\\server\\share\\update-passwordarchive.ps1 `
-certificatefilepath \\\\server\\share\\cert.cer `
-passwordarchivepath \\\\server\\share `
-localusername Administrator
how can we make sure no one sets up a malicious \\\\server\\share\\update-passwordarchive.ps1
After all we don't check authenticity of the share nor we sign/verify the script file, do we?
mike

Posted April 6, 2015 at 2:01 AM | Permalink | Reply

Jason Fossen

Hi Mike:
It's just like you said, we could sign the script, use SMB signing, SMB encryption (Server 2012), IPSec for the SMB channel, DNSSEC/IPSec for the DNS query, and Kerberos is already used for authentication. The script could also be run from the machine's local drive instead of from a share.
Cheers, Jason

Posted April 8, 2015 at 1:44 PM | Permalink | Reply

Adam

Hi Jason,
Thanks so much for this solution. Its pretty much exactly what we are looking for in an answer to the local admin password issue. I'm currently in the process of testing though and running into one problem if you could offer some advice.
When I use the certs you provide it works great. However when I generate my own from our local CA (Microsoft Active Directory Certificate Services) I run into issues. When I run the script to recover the password I get a powershell error:
Exception calling "Decrypt" with "2" argument(s): "Bad Key."
At C:\\Recover-PasswordArchive.ps1:203 char:84
'' iphertext[0..$($pubkeysize ''" 1)]), $false) #Must be $false for smart card to wo ''
~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : CryptographicException
Then in the status that is printed below that I see:
Valid : False
StatusMessage : ERROR: Decryption of symmetric key and IV failed, possible archive file corruption.
Password :
Can you lend any hints to how the certificate should be created? Should it be of a specific type/template or have specific "Key Usage" and "Extended Key Usage (application policies)" properties? Does it matter if the exported public .cer is in DER or Base64?
Any help would be appreciated. Cheers

Posted June 9, 2015 at 6:15 PM | Permalink | Reply

Jason Fossen

Hi Adam:
OK, I found the issue causing the "Bad Key" error message. If you examine the properties of a certificate, Details tab, there is a field named "Key Usage". To use a certificate with the script, that certificate must have "Key Encipherment" in the Key Usage list in the certificate (the scripts have been updated to warn about this). If you are requesting your certificate from a Windows Certification Authority (CA), confirm that the template used in the request has "Encryption" selected for an allowed purpose of the certificate (see the Request Handling tab in the properties of the template).
Hope this helps!
Jason

Posted April 10, 2015 at 10:35 AM | Permalink | Reply

samualhassi

Thanks for sharing this informative article.
I would also like to share a free tool named Lepide local user management tool (http://www.lepide.com/local-user-management.html ) that helps the administrators to enable, disable the accounts and reset their passwords within few clicks.

Posted June 18, 2015 at 10:02 PM | Permalink | Reply

Rob Oberto

Jason,
Thank you for the script. We just started testing it. I have the key pair. The password change and archive work fine, but when I run the recovery (we're running on W2008R2) the password decrypts just fine, but along with the decrypted password is contained the error "Method invocation failed because [System.Security.Cryptography.SHA256Managed] doesn't contain a method named ''Dispose'." It's having an issue with $SHA256Hasher.Dispose. Can this error be safely ignored? Is it because we're running an older PS version?
Thanks in advance!

Posted June 21, 2015 at 1:17 AM | Permalink | Reply

Jason Fossen

Hi Rob:
Yes, it is safe to ignore it, but I have also updated the script in the SEC505 zip file to avoid the error anyway when using older versions of PowerShell. Thanks for the heads up!
Cheers,
Jason

Posted June 24, 2015 at 9:27 AM | Permalink | Reply

Carlton flintoff

Thanks for sharing this informative article.
In my situation to reset local administrator password, I use a free tool named Lepide local user management tool (http://www.lepide.com/local-user-management.html ) that works like a charm.
It helps to reset local admin passwords, enable/disable their accounts within few clicks without having any further interruption.

Posted September 3, 2015 at 12:18 PM | Permalink | Reply

Andre

Jason,
For my workgroup windows cliets I would like to store the content of the file ($cipherbytes) into registry for SCCM to include it in the hardware inventory. (with custom MOF).
I succeeded to put in registry on the client with the following lines added to your script Update-PasswordArchive.ps1 where you write the content to file:
New-Item -Path hklm:\\SOFTWARE -Name Custom Force
New-Item -Path hklm:\\SOFTWARE\\Custom -Name Local-adm-pwd Force
New-ItemProperty -Path hklm:\\SOFTWARE\\Custom\\Local-adm-pwd -Name FileName -PropertyType String -Value $filename -Force
New-ItemProperty -Path hklm:\\SOFTWARE\\Custom\\Local-adm-pwd -Name Content -PropertyType MultiString -Value $cipherbytes -Force
This will work fine with SCCM and the registry content will be available in the SCCM database after the hardware inventory.
But now I would like the content in registry to be converted in the right byte encoding and written to a file again like the script Update-PasswordArchive.ps1 initially does.
(this is what I would like to do with the content from SCCM for particular client)
This is where I am stuck.
I probably used the wrong stringtype for the registry item I am adding, but i am not sure.
Can you help me out?

Posted September 4, 2015 at 2:13 AM | Permalink | Reply

Jason Fossen

Hi Andre:
Something you might research is the "-Encoding Byte" parameter for Set-Content and Get-Content, or maybe encoding raw bytes in Base64 before saving (for examples, look in the SEC505 zip file from the Downloads page of this blog, \\Day1-PowerShell\\BinaryData folder, there's a script there with Base64 examples). Beyond this kind of general information, I can't do specific development or give specific advice due to liability insurance reasons (sorry).
Best Wishes,
Jason

Posted October 8, 2015 at 7:49 PM | Permalink | Reply

Nick

Is it possible to make this script work with FIPS enabled? Right now I get a padding error when this is ran on a FIPS enabled system.
Thanks for any info.
Nick,

Posted October 21, 2015 at 2:38 PM | Permalink | Reply

Kevin

Jason,
We are also unable to get the script to run on FIPS enabled systems. I have included the actual command, ps version number, and the group policy object that enables FIPS on the system. Thanks for any assistance that you can provide.

Posted October 23, 2015 at 4:43 AM | Permalink | Reply

Jason Fossen

Hello Nick and Kevin:
Thank you for bringing this up, the problem is my fault. The original script I wrote to be FIPS compliant, but I later made changes and forgot to test with FIPS again. Unfortunately, there are other benefits to these changes (mainly for wider compatibility) so I have to think about the majority of users. Sorry for this outcome. I've updated the blog article and script notes.
On a related note, you might be interested in this Microsoft article: "Why We're Not Recommending FIPS Mode Anymore" (http://blogs.technet.com/b/secguide/archive/2014/04/07/why-we-re-not-recommending-fips-mode-anymore.aspx). Not that this article would change the requirements for your environment, you probably have no choice, but just to add some larger context to the problem. In the SEC505 course, we eliminate the insecure hashing algos and ciphers by directly managing the Windows cipher suites, not enabling FIPS Mode.
Best Regards,
Jason

Posted October 23, 2015 at 6:34 PM | Permalink | Reply

Kevin

Jason,
Thanks for your reply. I totally understand in regards to your choices in your scripts. However i was able to use your scripts as a baseline and configure it to use tripple des as a hash and aes as a cipher for FIPS enabled systems.
We do actully remove all the hashing and ciphers directly but for some reason we still need to run in FIPS's mode.
Thanks
-kevin

Posted October 28, 2015 at 1:53 AM | Permalink | Reply

Jason Fossen

That is great news Kevin!

Posted February 9, 2016 at 7:26 PM | Permalink | Reply

R Logan

To the list of commercial products that manage Local Administrator Password, consider adding ..
SYNERGIX AD Client Extensions ( ADCE )
http://www.synergix.com
''" Encrypted Password
''" Unique key
''" Password checkout
''" Password masking
''" RDP to target server without exposing credentials
''" Auditing
20 more features in same product.

Posted April 15, 2016 at 8:28 PM | Permalink | Reply

Frank Walsh

Hi Jason,
This code is great. However I've run into a road block. I applied the permissions you suggested to my share:
c:\\share DOMAIN\\Domain Computers:(OI)(CI)(DENY)(D,WDAC,WO,AD,DC)
DOMAIN\\Domain Computers:(OI)(IO)(DENY)(S,WD)
DOMAIN\\Domain Admins:(OI)(CI)(F)
DOMAIN\\Domain Computers:(OI)(CI)(RX,WD,WEA,WA)
c:\\share\\PublicKeyCert.cer DOMAIN\\Domain Computers:(I)(DENY)(D,WDAC,WO,AD,DC)
DOMAIN\\Domain Computers:(I)(DENY)(S,WD)
DOMAIN\\Domain Admins:(I)(F)
DOMAIN\\Domain Computers:(I)(RX,WD,WEA,WA)
I need to trigger the script via an agent that runs as local system. I assumed that local system would attempt to authenticate with the share using the Computer Account for which the Domain Computers ACLs would suffice. However, I get an access denied. I then tried implementing the GPO described here: https://technet.microsoft.com/en-us/library/jj852275.aspx but that also has no effect.
I am able to PsExec to a LOCAL SYSTEM command line and if I add

Posted May 13, 2016 at 9:06 PM | Permalink | Reply

Eskil Moe

Hi, the script Update-PasswordArchive.ps1 do not work on Norwegian Windows 10, because the local administrator group is called "Administratorer". I believe is it better to use the SID of the Administrators group.
If you change this line:
if (-not $? -or -not $CurrentPrincipal.IsInRole("Administrators"))
To:
if (-not $? -or -not $CurrentPrincipal.IsInRole(([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value))
Then it works on Norwegian OS
Eskil Moe

Posted May 15, 2016 at 7:35 PM | Permalink | Reply

Jason Fossen

Great idea, I should have done this to begin with! SEC505 zip file updated, thanks!

Posted September 22, 2016 at 1:02 PM | Permalink | Reply

Stevie

Jason,
Wanted to add my thanks to that of everyone else here for some excellent work here. We're moving to implement this solution, and as is natural, arrived at a couple of questions that weren't easy to answer:
What might the ACL look like on a share which would be used by WORKGROUP computers?
(I'm tempted to use file integrity monitoring rather than NTFS permissions as a control in this scenario)
Regarding targets: has anyone else considered using this on domain controllers, against the built-in "Administrator" account? At face value it could be an additional benefit to automatically manage that account's password ''" even though the scope of the "shared/common password" issue in that context is smaller (assuming one has many less DCs than member servers or workstations).
Thanks!
Stevie

Posted September 22, 2016 at 1:06 PM | Permalink | Reply

Stevie

Sorry,
One more thing I forgot to include!
I'm probably being thick, or derp'ing really hard, but wouldn't the suggested NTFS permissions actually prohibit the members of "Domain Computers" from creating the archive files?
Principal: Domain Computers
Apply to: Files only
Deny: Create files/write data
Looking forward to being corrected (as in "publicly shamed")
Stevie

Posted September 22, 2016 at 2:25 PM | Permalink | Reply

Jason Fossen

Hi Stevie:
It's a good question, NTFS permissions are hard. Look at both sets of permissions together, which allows files to be created by Domain Computers (this is implied by the Full Control checkbox), but not edited or deleted afterwards (kind of like a mailbox). As for workgroups, the permissions will have to be more relaxed (insecure) because computers will not be able to authenticate with their global computer accounts in AD; like you said, in this scenario, it's probably better to monitor and make frequent backups to prepare for future abuse. And while it's possible to manage global user account passwords with a script similar to this one, this particular script is not designed for it deliberately, so you would have to edit it yourself to do this. Cheers!

Posted September 26, 2016 at 2:38 PM | Permalink | Reply

Stevie

Thanks very much Jason ''" agreed, NTFS perms are always difficult to structure well!
I think file integrity monitoring and some analytics there will be a better defence against abuse of the scripts or relatively open access to the share(s).
We're well on our way through this now, and are looking at decoupling the process to use a database rather than an SMB share, as there could be some architectural benefits to move away from using SMB in this process.
Once again, thanks for some well-thought-out, high-quality work here.

Posted September 28, 2016 at 10:57 PM | Permalink | Reply

ray klassen

great little set of scripts.
edited CleanUp-PasswordArchive.ps1 because I wanted to run it from server side and linux has a built in ''sort' command that was fouling things up
Lines 148 and 157 only work when you are invoking Sort-Object and as I said the shorthand version ''sort' executes /usr/bin/sort instead of Sort-Object (as it would on windows)
so changed it back to longhand Sort-Object and now I can run it in a cron job.

Posted October 6, 2016 at 11:09 PM | Permalink | Reply

ray klassen

one more note about running CleanUp-PasswordArchive.ps1 from linux. I had to add the -force parameter to remove-item or the files would not delete. (Access Denied, or some such)

Posted October 6, 2016 at 11:19 PM | Permalink | Reply

Jason Fossen

Thanks Ray, I'll update the script!

Posted October 19, 2016 at 11:49 PM | Permalink | Reply

Paul Flatt

Hi,
Can anyone provide guidance on how to create the certificate so that it works from a Windows 2012 R2 CA? I have tried numerous times, each time ensuring that the Request Handling either has Signature

Posted October 20, 2016 at 4:34 AM | Permalink | Reply

Jason Fossen

Hi Paul: Sorry to hear about the difficulties. For whatever certificate you use, please check that it has ''Key Encipherment' listed under ''Key Usage' in its properties. The certificate template used by the CA should have ''Encryption' listed as one of the allowed purposes on the ''Request Handling' tab in the properties of that template. You might make a duplicate copy of the User template and then modify that new copy.

Posted October 27, 2016 at 8:36 PM | Permalink | Reply

Paul Flatt

I finally figured out the problem, and it was of my own undoing.
When I created the certificate, I exported the private key and the certificate chain associated with that and then imported into my personal key store. I had assumed this would import the public certificate but it did not.
So, I manually installed the certificate first, then installed the private key and voila it all worked.

Post a Comment






Captcha


* Indicates a required field.