MSEndpointMgr / ConfigMgr

Microsoft Endpoint Configuration Manager scripts and tools
628 stars 282 forks source link

Crypted password? #270

Open nodiaque opened 3 years ago

nodiaque commented 3 years ago

Hello,

I was wondering if the script could implement using securestring and credentials for password instead of plain text. In the past, I've modified the script and added some function I created.

At first, I create a key file using:

`function createKey { param ( [string]$keyPath = "$scriptPath\aes.key" ) $Key = New-Object Byte[] 32

$Key | out-file $keyPath

}`

After, I create a file containing the crypted password with the keyfile using get-credential function createSecurePassword { param ( [string]$keyPath = "$scriptPath\aes.key", [string]$passwordPath = "$scriptPath\password.txt" ) (get-credential).Password | ConvertFrom-SecureString -key (get-content $keyPath) | set-content "$passwordPath" }

This will prompt the user with a user/pass window and will encrypt the result.

After, in the script needing these, you need to supply the file containing the key and the file containing the password. using the next funciton, you get a securestring containing the password.

function getSecurePassword { param ( [string]$keyPath = "$scriptPath\aes.key", [string]$securePasswordPath = "$scriptPath\password.txt" ) $securePass = Get-Content $securePasswordPath | ConvertTo-SecureString -Key (Get-Content $keyPath) return $securePass }

You can also use another function to retrieve the password in clear, which need the username used during the get-credential phase:

function getClearPassword() { param ( [string]$keyPath = "$scriptPath\aes.key", [string]$securePasswordPath = "$scriptPath\password.txt", [string]$credUsername ) if (((Test-Path -Path $keyPath) -eq $true) -and ((Test-Path -path $securePasswordPath) -eq $true)) { $credPass = Get-Content $securePasswordPath | ConvertTo-SecureString -Key (Get-Content $keyPath) $cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $credUsername, $credPass return $($cred.GetNetworkCredential().password) } }

In case you would need the credential object, you can use this function

`function getCredential { param ( [string]$user, [System.Security.SecureString]$securePass ) $credential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $user, $securePass

$credential = New-Object System.Management.Automation.PsCredential($user, $pass)

return $credential

}`

Thus what could be accomplish is have a switch, let's say -encryptedPassword. When this is on, it need to have 3 arguments. 1 for the encrypted key filename, 1 for the secure password and 1 for the username used during the get-credential phase. You need all 3 of these parameter to allow decryption, thus the password can't be read in logfile and if someone steal the files, it still need the username. In the script, it would use the getClearPassword command to retrieve the password. Using a try/catch in the method would prevent any missing file error from crashing the script.