Security: credentials, SecureString, no passwords in code
The ZEUS probes connect to domain controllers and remote machines — they
operate on sensitive credentials. In a security product our own scripts must be
exemplary: no passwords in code, credentials as a PSCredential.
Never passwords in a script
A password in code ends up in the repository, the logs and the git history forever.
# bad — a password in code, leaked forever
$pass = "P@ssw0rd123"
$cred = New-Object PSCredential("corp\svc", (ConvertTo-SecureString $pass -AsPlainText -Force))
# good — credentials supplied from outside as a parameter
param([Parameter(Mandatory)][pscredential]$Credential)
ProfessNet standard: a probe script contains no password or token. It accepts credentials as a
[pscredential]parameter or fetches them from a secure store. A plain-text password in code = a critical review failure.
PSCredential — the standard credential type
PSCredential stores a username and a password as a SecureString. All remote
cmdlets (Invoke-Command, New-PSSession) accept it via -Credential.
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$ComputerName,
[Parameter(Mandatory)][pscredential]$Credential
)
Invoke-Command -ComputerName $ComputerName -Credential $Credential -ScriptBlock {
Get-Service
}
Interactively, we fetch credentials securely with Get-Credential:
$cred = Get-Credential -UserName "corp\svc-zeus" -Message "Probe credentials"
SecureString — why not a plain string
SecureString keeps data encrypted in memory and lets you wipe it. It does not
accidentally appear in logs or a transcript.
# conversion when you really must (e.g. for an API that requires plain)
$plain = $Credential.GetNetworkCredential().Password # use and clear immediately
ProfessNet standard: we extract plain text from a
SecureStringonly at the moment of use (at the boundary with an API that can't do otherwise) and don't keep it in a variable longer than necessary. We never log this value.
A credential store — SecretManagement
For persistent storage we use the Microsoft.PowerShell.SecretManagement
module with a vault (e.g. Windows Credential Manager), not files.
# write once, outside the code
Set-Secret -Name "ZeusProbeCred" -Secret $cred
# read in the script — no password in code
$cred = Get-Secret -Name "ZeusProbeCred"
Remote execution and WinRM
Remote connections go through WinRM with credentials and, where possible, over an encrypted transport.
$session = New-PSSession -ComputerName $dc -Credential $Credential -UseSSL
try {
Invoke-Command -Session $session -ScriptBlock { Get-ADForest }
}
finally {
Remove-PSSession $session
}
| Rule | Implementation |
|---|---|
| No passwords in code | a [pscredential] parameter or SecretManagement |
| Safe password in memory | SecureString / PSCredential |
| Interactive retrieval | Get-Credential |
| Persistent credentials | Get-Secret / Set-Secret (vault) |
| No leak into logs | we don't log the password, we clean up sessions |
Tip: disable transcription of sensitive fragments and remember that
ConvertTo-SecureString ... -AsPlainTextin code is a red flag — it means plain text is somewhere in the script.
Credentials as a PSCredential, secrets in a vault, plain text only for the
moment of use and never in the repo. In the ZEUS probes credential security is
not an add-on — it's the definition of a correctly written script.