Below is a description of the options available for executing PowerShell script files, and what is possible by signing them.
For testing, a simple PowerShell script was created and run on a freshly installed Windows 10 client.
By default, a Windows 10 client is prevented from running because the execution policy for Windows PowerShell is set to "Restricted", which means that scripts are generally not allowed to run.
File C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 cannot be loaded because running scripts is disabled on this system.
The PowerShell Execution Policy
Do you know TameMyCerts? TameMyCerts is an add-on for the Microsoft certification authority (Active Directory Certificate Services). It extends the function of the certification authority and enables the Application of regulationsto realize the secure automation of certificate issuance. TameMyCerts is unique in the Microsoft ecosystem, has already proven itself in countless companies around the world and is available under a free license. It can downloaded via GitHub and can be used free of charge. Professional maintenance is also offered.
Windows PowerShell has an execution policy that defines the behavior regarding the execution of scripts. This policy differs depending on the operating system variant:
Operating system variant | Execution policy set by default |
---|---|
Windows clients | Restricted |
Windows Server | RemoteSigned |
The settings relevant for the further procedure briefly explained:
Setting | Description |
---|---|
Restricted | No PowerShell scripts of any kind may be executed. |
RemoteSigned | Locally stored PowerShell scripts are allowed to run even if they are not signed. PowerShell scripts that reside on network locations are allowed to run only if they are signed. |
AllSigned | PowerShell scripts, whether stored locally or on network locations, must not be executed unless they are signed. |
Manually configure execution policy
Our goal is to allow only signed scripts to be executed. Therefore, the execution policy is set to "AllSigned" with the following command.
Set-ExecutionPolicy AllSigned
Configure execution policy via group policy
The same effect can be achieved via group policies using the following setting: Computer Configuration" - "Administrative Templates" - "Windows Components" - "Windows PowerShell" - "Turn on Script Execution" - "Allow only signed scripts".
Digitally sign the script
The execution of the script will still not succeed because it does not have a digital signature yet.
File C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 cannot be loaded. The file C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 is not digitally signed. You cannot run this script on the current system.
Code signing certificate
To sign a script file you need a certificate with the Extended Key Usage (EKU) for code signature. This circumstance is taken for granted for the rest of the article and will not be discussed in more detail.
Perform the signature
To digitally sign PowerShell scripts, the Set-AuthenticodeSignature command can be used.
First, the code signing certificate is identified in the local certificate store and loaded into a variable.
$SigningCertificate = (Get-ChildItem -Path Cert:\CurrentUser\My\26716942D0BDBB2D3825C2469C611C59AAE11DE6)
Optional but very useful is the use of a timestamp according to RFC 3161. If the code signature is time-stamped, the signature continues to be recognized as valid even after the signature certificate has expired. In this example, the publicly accessible time stamp server from Sectigo is used.
$TimeStampingAuthority = 'http://timestamp.sectigo.com'
Now all information is available and the script can be signed.
Set-AuthenticodeSignature ` -FilePath .\HelloWorld.ps1 ` -Certificate $SigningCertificate ` -TimestampServer $TimeStampingAuthority
If you now look at the properties of the script file, you can see that it now has a digital signature.
A look at the details of the sigature also reveals that there is also a countersignature (time stamp).
If you open the script with a text editor, you will see that the digital signature has been appended to the script code in BASE64 encoded form.
Enter in the memory for "trusted publishers" (or not)
One would now think that the script could finally be executed. However, it is now noted that the editor is not trusted.
Do you want to run software from this untrusted publisher? File C:\Users\rudi.INTRA\Desktop\HelloWorld.ps1 is published by CN=Rudi Ratlos, OU=User Accounts, OU=ADCSLabor Users, DC=intra, DC=adcslabor, DC=en and is not trusted on your system. Only run scripts from trusted publishers.
Now you have the option not to execute it, to execute it once, to execute it always, or to never execute it.
Selecting Always run causes the signing certificate to be imported into the Trusted Issuer store in the user's certificate store.
Leveraging the protection
However, the fact that the execution policy accepts only signed scripts is in no way a guarantee that unsigned scripts cannot be executed. There are many ways to subvert the execution policy and still run unsigned scripts.
Here is a simple example:
type .\HelloWorld.ps1 | powershell -
Related links
External sources
- About Execution Policies (Microsoft)
- Set-AuthenticodeSignature (Microsoft)
- Add, remove, or view a trusted publisher (Microsoft)
- Manage Trusted Publishers (Microsoft)
- Use Policy to Distribute Certificates (Microsoft)
- 15 Ways to Bypass the PowerShell Execution Policy (NetSPI LLC)
One thought on “Codesignatur für PowerShell Scriptdateien”
Comments are closed.