# PowerShell Code Signing

PowerShell code should be signed, from an offensive standpoint, to allow it to be executed under stricter application whitelisting policies and circumvent execution policy enforcement.

The following formats can have signatures

* ps1
* psm1
* psd1
* ps1xml
* psc1
* cdxml
* mof

To create a self-signed certificate we can use

```powershell
$Arguments = @{
	Subject = 'CN=My Self-signed Code Signing'
	Type = 'CodeSigningCert'
	KeySpec = 'Signature'
	KeyUsage = 'DigitalSignature'
	FriendlyName = 'My Self-signed Code Signing'
	NotAfter = ((Get-Date).AddYears(3))
	CertStoreLocation = 'Cert:\CurrentUser\My'
}
$TestCodeSigningCert = New-SelfSignedCertificate @Arguments
```

```powershell
Add-Type -TypeDefinition @'
	using System;
	public class Test {
		public static void Main(string[] args) {
		Console.WriteLine("Hello, PowerShell!");
		Console.ReadKey();
	}
}
'@ -OutputAssembly HelloPowerShell.exe

$MySigningCert = ls Cert:\CurrentUser\My\ | ? { $_.Subject -eq 'CN=My Self-signed Code Signing' }
Set-AuthenticodeSignature -Certificate $MySigningCert -TimestampServer 'http://timestamp.digicert.com' -FilePath .\HelloPowerShell.exe
```

And to add a trusted root certificate

```powershell
$MySigningCert = ls Cert:\CurrentUser\My\ | ? { $_.Subject -eq 'CN=My Self-signed Code Signing' }
Export-Certificate -FilePath exported_cert.cer -Cert $MySigningCert
Import-Certificate -FilePath exported_cert.cer -CertStoreLocation Cert:\CurrentUser\Root
Get-AuthenticodeSignature HelloPowerShell.exe
```

Catalog-signing permits signing of any file type regardless of “signability”. A catalog file is effectively a list of hashes that can be signed.

```powershell
mkdir NewModule
'Write-Host "This is an awesome module!!!"' | Out-File .\NewModule\NewModule.psm1

New-FileCatalog -CatalogVersion 2 -CatalogFilePath .\NewModule.cat -Path .\NewModule\
Move-Item -Path .\NewModule.cat -Destination .\NewModule\

Test-FileCatalog -FilesToSkip .\NewModule\NewModule.cat -CatalogFilePath .\NewModule\NewModule.cat -Detailed

$MySigningCert = ls Cert:\CurrentUser\My\ | ? { $_.Subject -eq 'CN=My Self-signed Code Signing' }

Set-AuthenticodeSignature -Certificate $MySigningCert -TimestampServer 'http://timestamp.digicert.com' -FilePath .\NewModule\NewModule.cat
```
