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

$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
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

$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.

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

Last updated