I have a windows service that downloads a script and then runs it.
I've been trying to make my windows service more secure, making it accept only signed power-shell scripts.
I have ran the Set-ExecutionPolicy AllSigned command on the server, and this works in the windows power shell command prompt.
However, my code still runs both signed and unsigned scripts, even if the set-executionpolicy is set to restricted.
I have tried two approaches:
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(@"Set-ExecutionPolicy AllSigned");
pipeline.Commands.AddScript(@"Get-ExecutionPolicy");
pipeline.Commands.AddScript(script);
Collection<PSObject> results = pipeline.Invoke();
And another approach:
using (PowerShell ps = PowerShell.Create())
{
ps.AddCommand("Set-ExecutionPolicy").AddArgument("Restricted");
ps.AddScript("Set-ExecutionPolicy Restricted");
ps.AddScript(script);
Collection<PSObject> results = ps.Invoke();
}
In both situations the code runs unsigned scripts as well.
Have I missed something?
I found the solution. The only way to restrict the code from running unsigned scripts was to check the scripts myself with Get-AuthenticodSignature:
public bool checkSignature(string path)
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(String.Format("Get-AuthenticodeSignature \"{0}\"", path));
Collection<PSObject> results = pipeline.Invoke();
Signature check = (Signature)results[0].BaseObject;
runspace.Close();
if (check.Status == SignatureStatus.Valid)
{
return true;
}
return false;
}
Thanks,
Dan
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With