Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save systemautomater/638e472c44170326b44fe65dfdafbcb1 to your computer and use it in GitHub Desktop.
Save systemautomater/638e472c44170326b44fe65dfdafbcb1 to your computer and use it in GitHub Desktop.
<#
Script Name: MS17-010 System Vulnerability Analysis Script
Description: This script is designed to analyze a list of systems gather through messagebox input in simple text format; to determine if they are protected
against the vulnerabilities outlined under EternalBlue from the Shadow Broker and remediated by Microsoft beginning in March of 2017 via several KB releases
to address what they labeled as MS17-010.
Author: Tim Rondeau
www.systemautomater.com
tim@systemautomater.com
#>
#create global arrays
$systems = @()
$online = @()
$offline = @()
$vulnerable = @()
$protected = @()
$initialDirectory = $env:USERPROFILE + "\desktop"
#function for input popup box to gather list of systems or names
function Read-MultiLineInputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
# Create the Label.
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Size(10,10)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.AutoSize = $true
$label.Text = $Message
# Create the TextBox used to capture the user's text.
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Size(10,40)
$textBox.Size = New-Object System.Drawing.Size(575,200)
$textBox.AcceptsReturn = $true
$textBox.AcceptsTab = $false
$textBox.Multiline = $true
$textBox.ScrollBars = 'Both'
$textBox.Text = $DefaultText
# Create the OK button.
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Size(415,250)
$okButton.Size = New-Object System.Drawing.Size(75,25)
$okButton.Text = "OK"
$okButton.Add_Click({ $form.Tag = $textBox.Text; $form.Close() })
# Create the Cancel button.
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(510,250)
$cancelButton.Size = New-Object System.Drawing.Size(75,25)
$cancelButton.Text = "Cancel"
$cancelButton.Add_Click({ $form.Tag = $null; $form.Close() })
# Create the form.
$form = New-Object System.Windows.Forms.Form
$form.Text = $WindowTitle
$form.Size = New-Object System.Drawing.Size(610,320)
$form.FormBorderStyle = 'FixedSingle'
$form.StartPosition = "CenterScreen"
$form.AutoSizeMode = 'GrowAndShrink'
$form.Topmost = $True
$form.AcceptButton = $okButton
$form.CancelButton = $cancelButton
$form.ShowInTaskbar = $true
# Add all of the controls to the form.
$form.Controls.Add($label)
$form.Controls.Add($textBox)
$form.Controls.Add($okButton)
$form.Controls.Add($cancelButton)
# Initialize and show the form.
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() > $null # Trash the text of the button that was clicked.
# Return the text that the user entered.
return $form.Tag
}
#function for capturing user input for file name and director to save outputs
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null
$SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$SaveFileDialog.initialDirectory = $initialDirectory
$SaveFileDialog.filter = “CSV Files (*.csv)|*.csv|All files (*.*)|*.*”
$SaveFileDialog.ShowDialog() | Out-Null
$SaveFileDialog.filename
}#end Function
<#List of approved hotfixes that address MS17-010. Note: If a system has a single hotfix it is considered protected. A system will not have a hotfix
installed for which it is not applicable to that specific operating system. Therefor, if a system is queried and returns at least a single hotfix installed
per the list supplied; it is considered protected.
#>
$hotfixes = @("KB4012212" , "KB4012215" , "KB4012218" , "KB4015549" , "KB4015552" , "KB4019263" , "KB4019264" , "KB4012214" ,
"KB4012217" , "KB4012220" , "KB4015551" , "KB4015554" , "KB4019214" , "KB4019216" , "KB4012213" , "KB4012216" , "KB4012219" ,
"KB4015550" , "KB4015553" , "KB4019213" , "KB4019215" , "KB4012606" , "KB4016637" , "KB4015521" , "KB4019474" , "KB4013198" ,
"KB4016636" , "KB4015219" , "KB4019473" , "KB4013429" , "KB4016635" , "KB4015217" , "KB4019472" , "KB4012598")
#display window for input of system names as a list then ensure they are all lowercase and scrub / trim the list
$multiLineText = Read-MultiLineInputBoxDialog -Message "Enter the names of the systems you wish to evaluate." -WindowTitle "Petya Vulnerability Analysis Script" -DefaultText "Enter one system per line..."
if ($multiLineText -eq $null) { Write-Host "You have provided no input or clicked Cancel. Please press enter to exit the script."
pause
Exit }
#cleanup names entered and reduce all to lowercase letters and remove trailing spaces from each record
Else {
$systems += $multilinetext
$systems | Foreach {$_.TrimEnd() } | Foreach {$_.ToLower()}
}
<#Begin processing systems in the above systems array. This processes as a ForEach loop which validates all systems are reachable. If a system is not reachable
it is placed in a seperate collection titled "offline" for later review. If systems are online they are placed in the "online" collection which is used to
query for hotfixes. This query returns all hotfixes assigned to that machine and checks to see if it matches any of the hotfixes that remediate the vulnerability
per the Microsoft Technet Article located at https://support.microsoft.com/en-us/help/4023262/how-to-verify-that-ms17-010-is-installed.
If the machine contains a patch it is placed in an array collection called "protected" for reporting.
If the machine does not contain at least one patch to remediate the vulnerability it is placed in an array collection titled "vulnerable".
These are displayed and printed out at the end of the script for the user.
#>
Write-Host "Checking all systems for availability. Please wait..."
ForEach($system in $systems){
If(Test-Connection -ComputerName $system -Quiet -Count 1)
{
$online += $system
}#end If
Else
{
$offline += $system
}#end Else
If($offline.count -ne $null)
{
Write-Host -ForegroundColor Yellow "One or more systems are currently unreachable. You can review the report at the end to see a full list of unavailable systems."
}#end If
}#end foreach
#if at least one system is online then proceed with analysis
If($online -ne $null){
#ForEach loop to begin processing of hotfix collection and systems analysis
ForEach($system in $online)
{
#collect hotfix information for the system into a variable for analysis
$hotfix = Get-Hotfix -ComputerName $system | Where-Object { $hotfixes -contains $_.HotfixID}
#if statement to evaluate if a hotfix is present from the list of applicable hotfixes
If($hotfix -contains $_.HotfixID)
{
Write-Host -ForegroundColor Green "System $system is protected by " + $hotfix.HotfixID
$protected += $system
}#end If hotfix contains hotfixID
Else
{
Write-Host -ForegroundColor Red "System $system is NOT protected!"
$vulnerable += $system
}#end Else
} #end ForEach
Write-Host -ForegroundColor White "Reference the Microsoft Technet article located at this link for information on specific patches for specific systems."
Write-Host " "#blank space for asthetics
Write-Host -ForegroundColor White "https://support.microsoft.com/en-us/help/4023262/how-to-verify-that-ms17-010-is-installed"
Write-Host " "#blank space for asthetics
Write-Host -ForegroundColor White "Individual Microsoft update packages can be searched and downloaded from: www.catalog.update.microsoft.com/Home.aspx"
Write-Host " "#blank space for asthetics
Write-Host -ForegroundColor White "The following list of systems are NOT protected against EternalBlue based threats such as WannaCry and Petya. Please patch these systems as soon as possible."
$vulnerable | Format-List
#prompt user if they would like a printout list in text document form of the vulnerable systems
$printVul = Read-Host -ForegroundColor Yellow "Would you like to save a CSV file of the vulnerable systems? [y/n]"
If($printVul -eq "y")
{
$savevuln = Get-FileName
If($savevuln -ne $null)
{
$vulnerable | Export-Csv -Path $savevuln -NoTypeInformation -Append
}#end if
}#end If
#does the user wish to print protected system list?
$printpro = Read-Host -ForegroundColor Yellow "Would you like to save a CSV of your currently protected systems? [y/n]"
If($printpro -eq "y")
{
$savepro = Get-FileName
If($savepro -ne $null)
{
$protected | Export-Csv -Path $savepro -NoTypeInformation -Append
}#end If
}#end If
#create list of offline or unreachable systems
$printoffline = Read-Host -ForegroundColor White "Would you like to save a CSV file of your systems that were unreachable during this analysis? [y/n]"
If($printoffline -eq "y")
{
$saveoffline = Get-FileName
IF($saveoffline -ne $null)
{
$offline | Export-CSV -Path $saveoffline -NoTypeInformation -Append
}#end if
}#end If
Write-Host -ForegroundColor Green "The script has completed. Please press enter to exit the script session."
Pause
}#end If
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment