1. Sign your PowerShell Scripts
    1. RemoteSigned
      1. Execution Policies in Effect
      2. Effective Execution Policy
      3. What Scripts Can Be Executed?
      4. Set-ExecutionPolicy
  2. Signing PowerHuntShares
    1. Running the signed script
  3. Sources

Sign your PowerShell Scripts


During a recent penetration test, I wanted to run PowerHuntShares, a PowerShell script designed to find secrets in shared resources and much more. If you haven’t heard of it before, I highly recommend checking it out.

RemoteSigned


The output of Get-ExecutionPolicy -List displays the execution policies defined across various scopes. Let’s analyze it to understand which scripts can be executed based on the settings found on the device during the penetration test:

Figure 1 - Our Device's Execution Policy

Execution Policies in Effect


MachinePolicy: RemoteSigned

LocalMachine: Unrestricted

Effective Execution Policy


The precedence of the execution policy order is determined by the highest priority scope with a defined policy. The priority order is:

  1. MachinePolicy: Set by a Group Policy for all users of the computer.
  2. UserPolicy: Set by a Group Policy for the current user of the computer.
  3. Process: The Process scope only affects the current PowerShell session. The execution policy is saved in the environment variable $env:PSExecutionPolicyPreference, rather than the configuration file. When the PowerShell session is closed, the variable and value are deleted.
  4. CurrentUser: The execution policy affects only the current user. It’s stored in the CurrentUser configuration file.
  5. LocalMachine: The execution policy affects all users on the current computer. It’s stored in the AllUsers configuration file.


Based on our output, the effective execution policy is RemoteSigned because it is set at the MachinePolicy scope, which takes precedence over LocalMachine.

What Scripts Can Be Executed?


Given the RemoteSigned policy in effect:

Allowed:


Blocked:

Set-ExecutionPolicy


Just set your execution policy to unrestricted bro. Well it is set through a GPO and scoped to LocalMachine…

Figure 2 - Set-ExecutionPolicy Unrestricted
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted
Figure 3 - Setting the execution policy

Signing PowerHuntShares


So how do we go about signing our own powershell script? To start, you’ll need a self-signed certificate. This certificate will act as the key to sign your script. The following PowerShell commands will generate the certificate:

#Parameters
$CertificateName = "PowerShell Code Signing"
 
#Create a Self-Signed SSL certificate
$Certificate = New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Subject "CN=$CertificateName" -KeySpec Signature -Type CodeSigningCert
 
#Export the Certificate to "Documents" Folder in your computer
$CertificatePath = [Environment]::GetFolderPath("MyDocuments")+"\$CertificateName.cer"
Export-Certificate -Cert $Certificate -FilePath $CertificatePath
 
#Add Certificate to the "Trusted Root Store"
Get-Item $CertificatePath | Import-Certificate -CertStoreLocation "Cert:\LocalMachine\Root"
  
Write-host "Certificate Thumbprint:" $Certificate.Thumbprint

As shown in Figure 4, this process generates a self-signed certificate with a thumbprint that you’ll use in subsequent steps.

Figure 4 - Generating a self-signed certificate

Once your certificate is ready, it’s time to sign the PowerHuntShares script. This step is critical to ensure the script runs on machines with restricted execution policies. Here’s how to sign the script:

#Set Parameters
$CertificateThumbprint = "DACE40709671E330D3D7F363458DFA306419BB32"
$ScriptPath = "C:\Users\cds\Downloads\PowerHuntShares-main\PowerHuntShares-main\PowerHuntShares.psm1"
 
#Get the Certificate from Cert Store
$CodeSignCert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq $CertificateThumbprint}
 
#Sign the PS1 file
Set-AuthenticodeSignature -FilePath $ScriptPath -Certificate $CodeSignCert

In Figure 5, you can see the signed PowerHuntShares script with its certificate applied successfully.

Figure 5 - Signed PowerHuntShares.psm1

After signing, it’s good practice to verify the script’s signature to ensure the process worked as intended. Run the following command to check:

Get-AuthenticodeSignature "C:\Users\cds\Downloads\PowerHuntShares-main\PowerHuntShares-main\PowerHuntShares.psm1" | fl

As seen in Figure 6 & Figure 7, which confirm the script is properly signed, making it ready for execution.

Figure 6 - PowerHuntShares Signed pt1
Figure 7 - PowerHuntShares Signed pt2

Running the signed script


With the script signed, you can now execute it seamlessly, even in environments with restrictive execution policies. By using Invoke-HuntSMBShares, you can automate the discovery of SMB shares efficiently.

Figure 7 - Successful run of Invoke-HuntSMBShares

Sources