$VT_API_Key = "08fac995e35a056695d5fdf5079318a1eb939539429d8217afa3572239f23fd2"
function Get-FileHashSHA256($FilePath) {
if (Test-Path $FilePath) {
return (Get-FileHash -Algorithm SHA256 -Path $FilePath).Hash
}
return $null
}
function Check-VirusTotal($Hash) {
$VT_URL = "https://www.virustotal.com/api/v3/files/$Hash"
$Headers = @{ "x-apikey" = $VT_API_Key }
try {
$Response = Invoke-RestMethod -Uri $VT_URL -Headers $Headers -Method Get
return $Response.data.attributes.last_analysis_results
}
catch {
Write-Output "VirusTotal query failed for hash: $Hash"
return $null
}
}
function Get-SignatureStatus($FilePath) {
return Get-AuthenticodeSignature -FilePath $FilePath
}
function Is-CertificateRevoked($Cert) {
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.Build($Cert)
foreach ($element in $chain.ChainElements) {
if ($element.ChainElementStatus -match "Revoked") {
return $true
}
}
return $false
}
$drives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Root -notlike "C:\
Windows" }
# Create arrays to store unsigned, revoked, and malicious EXEs
$unsignedExes = @()
$revokedExes = @()
$maliciousExes = @()
foreach ($drive in $drives) {
Write-Host "`nChecking drive: $($drive.Name)"
$filePaths = Get-ChildItem -Path $drive.Root -Recurse -Filter "*.exe" -
ErrorAction SilentlyContinue |
Where-Object {
$_.FullName -notlike "C:\Windows\*" -or
$_.FullName -like "C:\Windows\System32\*" -or
$_.FullName -like "C:\Windows\SysWOW64\*" -and
$_.FullName -notlike "C:\Program Files (x86)\*" -and
$_.FullName -notlike "C:\Program Files\Adobe\*" -and
($_.Name -split '\.').Count -eq 2
} |
Sort-Object LastAccessTime -Descending
$counter = 1
foreach ($filePath in $filePaths) {
$signature = Get-SignatureStatus -FilePath $filePath.FullName
if ($signature.Status -eq "Valid") {
# Skip processing valid signed EXEs
continue
}
Write-Host "`n[$counter] Processing: $($filePath.FullName)"
$fileHash = Get-FileHashSHA256 -FilePath $filePath.FullName
if ($fileHash) {
Write-Host "`n - File hash: $fileHash"
$scanResults = Check-VirusTotal -Hash $fileHash
if ($scanResults) {
Write-Host "`n - VirusTotal Analysis for file $
($filePath.FullName):"
# Initialize detection categories
$maliciousCount = 0
$suspiciousCount = 0
$undetectedCount = 0
foreach ($engineName in $scanResults.PSObject.Properties.Name) {
$detectionCategory = $scanResults.$engineName.category
if ($detectionCategory -eq "malicious") {
$maliciousCount++
}
elseif ($detectionCategory -eq "suspicious") {
$suspiciousCount++
}
elseif ($detectionCategory -eq "undetected") {
$undetectedCount++
}
}
Write-Output "`n - VirusTotal Detections:"
Write-Output " - Malicious: $maliciousCount"
Write-Output " - Suspicious: $suspiciousCount"
Write-Output " - Undetected: $undetectedCount"
if ($maliciousCount -gt 0) {
$maliciousExes += $filePath.FullName
}
}
else {
Write-Host "`n - No analysis found for $($filePath.FullName). You
may need to upload it to VirusTotal."
}
if ($signature.Status -ne "Valid") {
$unsignedExes += $filePath.FullName
}
if ($signature.SignerCertificate) {
$revoked = Is-CertificateRevoked -Cert $signature.SignerCertificate
if ($revoked) {
Write-Output " - WARNING: The certificate chain for
module '$($filePath.Name)' is revoked."
$revokedExes += $filePath.FullName
}
}
}
else {
Write-Host "`n - Failed to compute SHA256 hash for file: $
($filePath.FullName)"
}
$counter++
}
}
if ($unsignedExes.Count -gt 0) {
Write-Host "`n--- Unsigned EXEs ---"
$unsignedExes | ForEach-Object { Write-Host $_ }
}
else {
Write-Host "`nNo unsigned EXEs found."
}
if ($revokedExes.Count -gt 0) {
Write-Host "`n--- Revoked EXEs ---"
$revokedExes | ForEach-Object { Write-Host $_ }
}
else {
Write-Host "`nNo revoked EXEs found."
}
if ($maliciousExes.Count -gt 0) {
Write-Host "`n--- Malicious EXEs (Malicious count > 0) ---"
$maliciousExes | ForEach-Object { Write-Host $_ }
}
else {
Write-Host "`nNo malicious EXEs found."
}