-
-
Save trackd/1600e22b5ba8e2453ea165c3eb63eeb1 to your computer and use it in GitHub Desktop.
minor refactor, outputs objects etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Scan-LOLDrivers { | |
<# | |
.EXAMPLE | |
Scan-LOLDrivers -Path C:\Windows\System32\drivers | |
$Results = Scan-LOLDrivers -Path C:\Windows\inf | |
$Results | Select-Object * | |
$Results[0].all | |
$Results[0].all.KnownVulnerableSamples | |
.EXAMPLE | |
$iwantitall = 'C:\WINDOWS\inf', | |
'C:\WINDOWS\System32\drivers', | |
'C:\WINDOWS\System32\DriverStore\FileRepository' | | |
Scan-LOLDrivers -Verbose | |
.NOTES | |
if you are unsure if something is working or not, use -Verbose to see what's happening. | |
.PARAMETER Path | |
The path to scan. | |
.PARAMETER FloodMyScreen | |
Floods your screen with the results. Useful for debug? | |
usually enough to just use -Verbose. | |
#> | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs','')] | |
param( | |
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[Alias('FullName')] | |
[string] | |
$Path, | |
[Switch] | |
$FloodMyScreen | |
) | |
begin { | |
$stopwatch = [Diagnostics.Stopwatch]::StartNew() | |
Update-TypeData -TypeName 'LOL.please.no.cve.hell' -DefaultDisplayPropertySet 'Created','MitreID','Vendor','FilePath' -Force | |
if (-Not ('LOLScanner' -as [type])) { | |
Write-Verbose "Compiling LOLScanner class..." | |
Add-Type -TypeDefinition @' | |
using System; | |
using System.IO; | |
using System.Security.Cryptography; | |
using System.Security.Cryptography.X509Certificates; | |
public class LOLScanner { | |
public static string ComputeSha256(string path) { | |
try { | |
using (FileStream stream = File.OpenRead(path)) | |
using (SHA256 sha = SHA256.Create()) { | |
byte[] checksum = sha.ComputeHash(stream); | |
return BitConverter.ToString(checksum).Replace("-", String.Empty); | |
} | |
} | |
catch (Exception) { | |
return null; | |
} | |
} | |
public static string GetAuthenticodeHash(string path) { | |
try { | |
using (X509Certificate2 cert = new X509Certificate2(path)) { | |
return BitConverter.ToString(cert.GetCertHash()).Replace("-", String.Empty); | |
} | |
} | |
catch (Exception) { | |
return null; | |
} | |
} | |
public static string GetAuthenticodeCertSubject(string path) { | |
try { | |
using (X509Certificate2 cert = new X509Certificate2(path)) { | |
return cert.Subject; | |
} | |
} | |
catch (Exception) { | |
return null; | |
} | |
} | |
} | |
'@ | |
} | |
Write-Verbose "Downloading drivers.json..." | |
$driversJsonUrl = "https://www.loldrivers.io/api/drivers.json" | |
$ProgressPreference = 'silentlyContinue' | |
# weird json formatting issue with the init property. | |
$driverData = (Invoke-WebRequest -Uri $driversJsonUrl).Content.Replace('"init"', '"INIT"') | ConvertFrom-Json | |
Write-Verbose "Download complete. $($driverdata.count) drivers found." | |
Write-Verbose "Building correlation tables" | |
$fileHashes = @{} | |
$authenticodeHashes = @{} | |
foreach ($driverInfo in $driverData) { | |
foreach ($sample in $driverInfo.KnownVulnerableSamples) { | |
'MD5 SHA1 SHA256'.Split() | ForEach-Object { | |
$fileHashValue = $sample.$_ | |
if ($fileHashValue) { | |
$fileHashes[$fileHashValue] = $driverInfo | |
} | |
$authCodeHashValue = $sample.Authentihash.$_ | |
if ($authCodeHashValue) { | |
$authenticodeHashes[$authCodeHashValue] = $driverInfo | |
} | |
} | |
} | |
} | |
Write-Verbose "Done building correlation tables for $($fileHashes.count) file hashes and $($authenticodeHashes.count) authenticode hashes." | |
function Scan-Directory { | |
[CmdletBinding()] | |
param( | |
[string] | |
$Directory, | |
[Switch] | |
$FloodMyScreen | |
) | |
Write-Verbose "Starting scan of $Directory" | |
$sep = '-' * $host.ui.RawUI.WindowSize.Width | |
$i = 0 | |
Get-ChildItem -Path $Directory -Recurse -File -ErrorVariable aclproblem -ErrorAction SilentlyContinue | ForEach-Object { | |
$i++ | |
$filePath = $_.FullName | |
$filehash = [LOLScanner]::ComputeSha256($filePath) | |
$fileAuthenticodeHash = [LOLScanner]::GetAuthenticodeHash($filePath) | |
if ($Floodmyscreen) { | |
Write-Verbose "Hash computed for -> $filePath`nFilehash: $fileHash`nAuthenticode: $fileAuthenticodeHash`n$sep" | |
} | |
if ($fileHashes.ContainsKey($fileHash)) { | |
$driverInfo = $fileHashes[$fileHash] | |
$Certinfo = [LOLScanner]::GetAuthenticodeCertSubject($filePath) | |
$vendor = if ($Certinfo -match 'O=(.*?)(,|$)') { $Matches[1] } else { $Certinfo } | |
Out-LOLDrivers $filePath $fileHash $driverInfo $vendor | |
} | |
if ($fileAuthenticodeHash -and $authenticodeHashes.ContainsKey($fileAuthenticodeHash)) { | |
$driverInfo = $authenticodeHashes[$fileAuthenticodeHash] | |
$Certinfo = [LOLScanner]::GetAuthenticodeCertSubject($filePath) | |
$vendor = if ($Certinfo -match 'O=(.*?)(,|$)') { $Matches[1] } else { $Certinfo } | |
Out-LOLDrivers $filePath $fileAuthenticodeHash $driverInfo $vendor | |
} | |
} | |
$aclproblem | ForEach-Object { | |
# maybe we should just use error instead, i prefer this. | |
Write-Warning "$($_.exception.message)" | |
} | |
Write-Verbose "Scan complete. $i files scanned in $Directory" | |
} | |
function Out-LOLDrivers { | |
param($filePath,$hash,$driverInfo,$vendor) | |
return [PSCustomObject]@{ | |
PSTypeName = 'LOL.please.no.cve.hell' | |
FilePath = $filePath | |
Hash = $hash | |
Vendor = $vendor | |
Category = $driverInfo.Category | |
Created = $driverInfo.Created | |
MitreID = $driverinfo.MitreID | |
Resources = $driverInfo.Resources -join ', ' | |
KnownVulnerableSamples = ($driverInfo.KnownVulnerableSamples.filename | Sort-Object -Unique) -join ', ' | |
Commands = $driverInfo.Commands.Command -join ', ' | |
All = $driverInfo | |
} | |
} | |
} | |
process { | |
$splat = @{ | |
Directory = $Path | |
} | |
if ($FloodMyScreen) { | |
$VerbosePreference = 'Continue' | |
$splat.FloodMyScreen = $true | |
} | |
Scan-Directory @splat | |
} | |
end { | |
Write-Verbose "Scan complete. $($stopwatch.Elapsed.TotalSeconds) seconds elapsed." | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment