📜 ⬆️ ⬇️

How to sign your first script in 48 hours

Problem


When a task that requires solving is small, I don’t want to write a separate utility for solving it, especially if you are a .NET programmer.
Script? Definitely, yes, but putting a third-party interpreter on a combat machine running Windows is not at all Christian. So why not use Windows Powershell? I am ready to honestly admit at once: there was practically no experience with him, but it looked painfully tempting.
The script, solving the problem, was ready in 15 minutes, if you do not take into account one “but”. It was difficult to call it a script yet, because it was a set of instructions that was unsuitable for execution as a script. Unsuitable from the point of view of PowerShell.

There is a rational explanation for everything - of course, certain restrictions are imposed on the execution of scripts, which are set by the script execution policy . Having created the script, I could not execute it right there on my own machine. However, the problem solved for the local machine by temporarily changing the execution policy to Unrestricted or, more correctly, RemoteSigned , on the production server is raised seriously.

There is always a way out. It is logical that the finished script for execution must be signed. The process of organizing the signature mechanism is long and thorny, but served as a good ground for this post.

After two days of torment at home and in the office, I submit to the public a brief manual on the signature of scripts for PowerShell.
')

Decision


By default, execution of any scripts is prohibited. First, you need to allow execution of only signed scripts from trusted publishers with a trusted root certificate. As part of a Powershell admin session:

> Set-ExecutionPolicy AllSigned

Further dances with a tambourine relate to the utility for creating the root and personal certificates.
All certificates, according to the "instructions" for signing scripts

> Get-Help About_Signing

are created using the makecert.exe utility located in % Program Files% \ Microsoft SDKs \ Windows \ v7.0A \ bin \ makecert

The following two actions are performed as part of a normal command line session:

> makecert -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr localMachine

> makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer


The first line creates a root certificate using the local machine as the authentication center. The most popular "free" way to get a certificate.
The second line creates a personal PowerShell user certificate with which scripts will be signed, certifying it with a root certificate. If everything went well, both lines should show the result succeded .

The above manipulations can also not be performed if the personal certificate X509 already exists.

After that, just in case, you can check that the OS is aware of the newly created certificate. PowerShell:

> Get-Childitem cert:\CurrentUser\my -codesigning

It is already possible to sign scripts, but in this case, the following Powershell line will go to the script signature each time:

> Set-AuthenticodeSignature "FileName" @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

It would be logical to create a script that will sign other scripts. The script must be created in any text editor, except PowerShell ISE. For scripts created inside this environment, there will be problems with signing as Unknown Error . The decision is made here .

The script itself looks like this:
param([string] $file=$(throw "Please specify a filename."))
$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
Set-AuthenticodeSignature $file $cert

Using the instructions above, we will sign this script itself in interactive PowerShell.
After that, the script for execution on another machine can be signed like this:

> .\Add-Signature.ps1 MyScript.ps1

About sad


On any machine, except the one on which the certificate was created:
  1. If the root certificate is not trusted, the script will not succeed at all.
  2. If the personal certificate of the publisher who signed the script is not trusted, the script will be executed only with confirmation.

In order to add the root and personal certificates to the trusted ones, you need to use the mmc admin console with the Certificates snap-in. Add certificates to the Trusted Root Certification Authorities and Trusted Publishers folders.

It does not claim to be the only right decision, but the results of studies show that so far this is more or less the normal way. I ask knowledgeable to help clarify the situation and poke a link, if possible.

Source: https://habr.com/ru/post/137884/


All Articles