The first step to make Powershell more secure is to create a certificate to sign my scripts. Then you actually sign it with this command:

Set-AuthenticodeSignature -FilePath myScript.ps1 -Certificate (Get-ChildItem -Path Cert:\CurrentUser\My\ -CodeSigningCert)

What creates a bit of a headache for me, is that you don't even need to specify the name of the certificate, it is chosen automatically.

Let's say somehow the password of the user owning that certificate get's leaked or a program somehow gains entry into that account. How do I prevent someone from using PowerShell to just sign their own, malicious script, to attack my infrastructure?

For example, by executing this on the command shell:

powershell /command Set-AuthenticodeSignature -FilePath .\myScript.ps1 -Certificate (Get-ChildItem -Path Cert:\CurrentUser\My\ -CodeSigningCert)

I have also studied the New-SelfSignedCertificate command and I do not find any indication that the certificate itself can be protected by a password or similar mechanics. What am I overlooking here?

  • What exactly is your threat model here? What are you trying to protect yourself against? – MechMK1 May 17 '19 at 13:40
  • @MechMK1 Various ransomware, including Matrix, which actually use PowerShell to infect the system, also known as "living off the land". But I am just generally curious, how the signing of scripts helps security, when it is so easy to get around it if you can get a hold of the computer holding the key certificate. – BadSnowflake May 17 '19 at 16:08

Aside: requiring the cert (and key) name wouldn't be any more secure, because those names aren't secret. Also even if your policy calls for signing, if the malware is executing on your system so that it could sign scripts it can also change the policy and run without signing. What signing prevents is tampering or forgery when you copy scripts from one system to another as data, like via a net share, website, email, or document. IME best practice is to do code signing (which scripts are) on separate machines with the highest defenses possible -- no browser, no email, maybe even no network connection (aka 'air gap'), and key in hardware (see below).

Yes, certs and (more important) keys in the normal Windows cert store(s) can be accessed without a password. If you use a smartcard or similar hardware module instead, it might require a PIN on each use; I don't have one myself and am not up-to-date on how modern Windows handles them. Plus this would give you the ability/option to remove the smartcard from the machine and physically protect it, like in a safe or such.

What would definitely require a password on each use is to keep the cert and key in a PFX file (aka PKCS12). https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature?view=powershell-6 gives an example of doing that. New-SelfSignedCertificate apparently can only write to the normal store or a smartcard, but it looks like you could Export-PfxCertificate to a file and then delete from the store. (I haven't tested, though.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.