PowerShell Signing

Damit ein PowerShell Skript vertrauenswürdig ist, kann der Autor das Skript digital signieren. In Verbindung mit einer entsprechenden Executionpolicy auf ihren Computern können Sie damit die Ausführung von fremden, unbekannten oder nicht verifizierte Skripte unterbinden.

Zertifikat zur Codesignatur

Um Code zu signieren, benötigen wir ein Zertifikat samt privatem Schlüssel und ein Werkzeug, welches das PowerShell Script einliest, einen Hashwert darüber bildet, den mit dem Zertifikat signiert und die Signatur dann an das Skript anhängt. Der Code muss aber mit einem "Code Signing Zertifikat" signiert worden sein, welches auf dem Rechner als "vertrauenswürdig" bekannt ist, auf dem das Skript später ausgeführt wird.. Das funktioniert sogar mit einem "selbst signierten Zertifikat. Allerdings ist dies natürlich keine Basis für einen Verteilung. Insofern gibt es folgende Varianten:

Signierung durch Preis Vertrauen Eignung

Keine Signatur

0

 

Unsicher

Selbst ausgestelltes Zertifikat

0

gleicher PC

Entwickler

CodeSigning einer Unternehmens-CA

niedrig

gleicher Forest

Innerhalb der Firma

CodeSigning einer öffentlichen CA

hoch

Weltweit

Weltweit

Auch wenn die Policy "AllSigned" nicht verhindert, dass ein Anwender über Umwege vielleicht doch ein PowerShell-Skript startet, so erschwert es den Angriffsweg für "normale Malware" schon deutlich. Um als Admin oder Entwickler die ersten Schritten mit Code-Signatur zu gehen, können Sie aber auch mit einem "selbst signierten Zertifikat" arbeiten. Das können Sie sehr einfach als Benutzer anlegen.

# Funktioniert noch nicht mit PowerShell Core.

#SelfSigned Codesigning anlegen
$cert = New-SelfSignedCertificate `
                   -DnsName codesign.msxfaq.de `
                   -Type CodeSigning `
                   -CertStoreLocation Cert:\CurrentUser\My


# Kennwort für PFX-Datei vorbereiten
$CertPassword = ConvertTo-SecureString `
                   -String "supergeheimeskennwort" `
                   -Force `
                   –AsPlainText

# Zertifikat exportieren (backup)
Export-PfxCertificate `
   -Cert "Cert:\CurrentUser\My\$($cert.Thumbprint)" `
   -Password $CertPassword `
   -FilePath "$($env:userprofile)\test.pfx"

Schon nach dem ersten Schritt finden Sie das Zertifikat in ihrem persönlichen Speicher. Allerdings auch in der Liste der Zwischenzertifizierungsstellen aber nicht in der Root-CA-Liste.

Das Zertifikat ist damit also nicht vertrauenswürdig. Auf dem eigenen PC können Sie das Zertifikat nun in die Liste der vertrauenswürdigen Stammzertifikatlisten kopieren, um das Problem zu lösen.

Es sollte aber uns allen klar sein, dass dieser Trick nur auf dem eigenen PC für Tests und Entwicklung genutzt werden sollte. Für produktive Einsätze sollten Sie immer ein Zertifikat einer öffentlichen Zertifizierungsstelle oder einer firmeninternen PKI nutzen.

Code Signieren

Mit dem vorhandenen Zertifikat samt privatem Schlüssel ist es es nun ganz einfach, ein vorhandenes Skript zu signieren

# Informationen über das erste Codesigning-Zertifikat aus meinem Store laden
$signingcert =(dir Cert:\CurrentUser\My -CodeSigningCert)[0]

#Signieren eines Skript im aktuellen Verzeicnis
Set-AuthenticodeSignature .\end2end-http.ps1 -Certificate $signingcert

Wenn sie danach das Skript öffnen, dann sehen Sie am Ende einen Block, der als Kommentar angehängt wurde. Das ist die Signatur des Skripts.

Sobald ich das Skript auch nur an einer kleinen Stelle ändere, verändert sich der Hash-Wert und die Signatur ist ungültig.

How to Sign a Script with Powershell
https://www.youtube.com/watch?v=-QGITsuOXLs

Signatur prüfen

Über das Commandlet "Get-AuthenticodeSignature" können Sie die für Menschen sonst unleserliche Signatur am Ende eines Skripts überprüfen.

PS C:\End2End> get-AuthenticodeSignature -FilePath .\end2end-http.cert.ps1  | fl

SignerCertificate      : [Subject]
                           CN=codesign.msxfaq.de

                         [Issuer]
                           CN=codesign.msxfaq.de

                         [Serial Number]
                           19E7D9CC5959FE8045DD872CC6888B61

                         [Not Before]
                           22.12.2019 19:14:38

                         [Not After]
                           22.12.2020 19:34:38

                         [Thumbprint]
                           F1824F5D5CD163FFD6BC05B869215CF10382D9E7

TimeStamperCertificate :
Status                 : Valid
StatusMessage          : Signatur wurde überprüft.
Path                   : C:\End2End\end2end-http.cert.ps1
SignatureType          : Authenticode
IsOSBinary             : False

Wenn der Status ein "Valid" ist, dann passt alles, d.h. das Skript wurde nicht verändert und sie kennen den Autor bzw. zumindest den "CN".

"0"-Byte File und Signatur

Manchmal schient Windows aber etwas verwirrt zu sein. Folgendes Commandlet erzeugt eine von Microsoft signierte Datei

PS C:\temp> Set-Content -Path test.ps1 "0" -NoNewline
PS C:\temp> Get-AuthenticodeSignature .\test.ps1 | fl *

SignerCertificate      : [Subject]
                           CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US

                         [Issuer]
                           CN=Microsoft Windows Production PCA 2011, O=Microsoft Corporation, L=Redmond, S=Washington,
                         C=US

                         [Serial Number]
                           330000023241FB59996DCC4DFF000000000232

                         [Not Before]
                           02.05.2019 23:24:36

                         [Not After]
                           02.05.2020 23:24:36

                         [Thumbprint]
                           FF82BC38E1DA5E596DF374C53E3617F7EDA36B06

TimeStamperCertificate : [Subject]
                           CN=Microsoft Time-Stamp Service, OU=Thales TSS ESN:D082-4BFD-EEBA, OU=Microsoft Ireland
                         Operations Limited, O=Microsoft Corporation, L=Redmond, S=WA, C=US

                         [Issuer]
                           CN=Microsoft Time-Stamp PCA 2010, O=Microsoft Corporation, L=Redmond, S=Washington, C=US

                         [Serial Number]
                           3300000113B370873DFAF0C824000000000113

                         [Not Before]
                           24.10.2019 01:19:21

                         [Not After]
                           22.01.2021 00:19:21

                         [Thumbprint]
                           3D57569160D39D8863D2983809B2130A97B8EE95

Status                 : Valid
StatusMessage          : Signature verified.
Path                   : C:\\test.ps1
SignatureType          : Catalog
IsOSBinary             : True

Ich denke das ist so nicht im Sinne des Erfinders. Anscheinend ist das ein Sonderfall. Ich berichte, wenn sich das geändert hat.

Weitere Links