Get-EternalBlueVulnerabilityStatistics.ps1

<#PSScriptInfo
 
.Version
    1.0
.Guid
    038a1c05-b1da-48c9-893d-4084b99f831b
.Author
    Thomas J. Malkewitz @dotps1
.Tags
    WannaCry, WannaCrypt, EternalBlue, SMB1, Malware
.ProjectUri
    https://github.com/dotps1/PSFunctions
.ExternalModuleDependencies
    NetTCPIP
.ReleaseNotes
    Refactor of Test-WannaCryVulnerability, uses a CIM Session to gather data, rather then multipule WMI calls.
 
#>


<#
 
.Synopsis
    Gets EternalBlue vulnerability information.
.Description
    Test for applicable patches to prevent the WannaCry malware. Tests for SMB1 protocol and component.
.Inputs
    System.String
    Microsoft.Management.Infrastructure.CimSession
.Outputs
    System.Management.Automation.PSCustomObject
.Parameter ComputerName
    System.String
    ComputerName to gather information from.
.Parameter Credential
    System.Management.Automation.PSCredential
    Credential used to establish a connection.
.Parameter CimSession
    Microsoft.Management.Infrastructure.CimSession
    Pre established CimSession used to connect.
.Example
    PS C:\> Get-EternalBlueVulnerabilityStatistics
 
    PSComputerName : my-win7-rig
    OperatingSystemCaption : Microsoft Windows 7 Professional
    OperatingSystemVersion : 6.1.7601
    LastBootUpTime : 5/14/2017 3:38:38 PM
    AppliedHotFixID : KB4012212;KB4015546;KB4015549
    SMB1FeatureEnabled : False
    SMB1ProtocolEnabled : False
    Port139Enabled : True
    Port445Enabled : True
.Example
    PS C:\> Get-ADComputer -Identity domain-win7-rig | Get-EternalBlueVulnerabilityStatistics
 
    PSComputerName : domain-win7-rig
    OperatingSystemCaption : Microsoft Windows 7 Professional
    OperatingSystemVersion : 6.1.7601
    LastBootUpTime : 3/14/2017 3:38:38 PM
    AppliedHotFixID :
    SMB1FeatureEnabled : False
    SMB1ProtocolEnabled : True
    Port139Enabled : True
    Port445Enabled : True
.Notes
    WannaCry/WannaCrypt (EternalBlue) vulnerability is only applicable to Microsoft Windows 10 1607 and prior, 1702 was not affected.
.Link
    https://technet.microsoft.com/en-us/library/security/ms17-010.aspx
.Link
    https://support.microsoft.com/en-us/help/2696547/how-to-enable-and-disable-smbv1,-smbv2,-and-smbv3-in-windows-vista,-windows-server-2008,-windows-7,-windows-server-2008-r2,-windows-8,-and-windows-server-2012
.Link
    https://dotps1.github.io
.Link
    https://www.powershellgallery.com/packages/Get-EternalBlueVulnerabiltyInforamtion
.Link
    https://grposh.github.io
 
#>



#requires -Module NetTCPIP

[CmdletBinding(
    DefaultParameterSetName = "ByComputerName"
)]
[OutputType(
    [PSCustomObject]
)]

param (
    [Parameter(
        ParameterSetName = "ByComputerName",
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true
    )]
    [ValidateScript({
        if (Test-Connection -ComputerName $_ -Count 1 -Quiet) {
            return $true
        } else {
            throw "Failed to contact '$_'."
        }
    })]
    [Alias(
        "ComputerName"    
    )]
    [String[]]
    $Name = $env:COMPUTERNAME,

    [Parameter(
        ParameterSetName = "ByComputerName"
    )]
    [System.Management.Automation.PSCredential]
    $Credential = [PSCredential]::Empty,

    [Parameter(
        ParameterSetName = "ByCimSession",
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true
    )]
    [Microsoft.Management.Infrastructure.CimSession[]]
    $CimSession
)

begin {
    $hotFixIDs = @(
        "KB3205409", 
        "KB3210720", 
        "KB3210721", 
        "KB3212646", 
        "KB3213986", 
        "KB4012212", 
        "KB4012213", 
        "KB4012214", 
        "KB4012215", 
        "KB4012216", 
        "KB4012217", 
        "KB4012218", 
        "KB4012220", 
        "KB4012598", 
        "KB4012606", 
        "KB4013198", 
        "KB4013389", 
        "KB4013429",
        "KB4015217", 
        "KB4015438", 
        "KB4015546", 
        "KB4015547", 
        "KB4015548", 
        "KB4015549",
        "KB4015550",
        "KB4015551",
        "KB4016635",
        "KB4019215",
        "KB4019216",
        "KB4019472"
    )

    function Get-Data ([Microsoft.Management.Infrastructure.CimSession]$CimSession, [Array]$HotfixIDs) {
        # Operating System Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve operating system information" -PercentComplete 20
        $osInformation = Get-CimInstance -CimSession $CimSession -ClassName Win32_OperatingSystem -Property Caption, LastBootUpTime, Version

        # Hotfix Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve operating hotfix id" -PercentComplete 40
        $appliedHotFixID = (Get-CimInstance -CimSession $CimSession -ClassName Win32_QuickFixEngineering).Where({
            $_.HotFixID -in $HotfixIDs
        }).HotFixID

        # SMB1Feature Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve SMB1 feature state" -PercentComplete 60
        $smb1Feature = (Get-CimInstance -CimSession $CimSession -ClassName Win32_OptionalFeature -Property InstallState -Filter "Name = 'SMB1Protocol'").InstallState
        if ($smb1Feature -eq 1) {
            $smb1FeatureEnabled = $true
        } else {
            $smb1FeatureEnabled = $false
        }

        # SMB1Protocol Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve SMB1 protocol state" -PercentComplete 80
        $smb1Protocol = (Invoke-CimMethod -CimSession $CimSession -ClassName StdRegProv -MethodName GetDwordValue -Arguments @{ hDefKey = [uint32]2147483650; sSubKeyName = "SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"; sValueName = "SMB1" }).uValue
        if ($smb1Protocol -eq 0) {
            $smb1ProtocolEnabled = $false
        } else {
            $smb1ProtocolEnabled = $true
        }

        # SMB1Port Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve SMB port state" -PercentComplete 100
        $port139TestConnection = (Test-NetConnection -ComputerName $CimSession.ComputerName -Port 139).TcpTestSucceeded
        $port445TestConnection = (Test-NetConnection -ComputerName $CimSession.ComputerName -Port 445).TcpTestSucceeded

        return [PSCustomObject]@{
            PSComputerName = $CimSession.ComputerName
            OperatingSystemCaption = $osInformation.Caption
            OperatingSystemVersion = $osInformation.Version
            LastBootUpTime = $osInformation.LastBootUpTime
            AppliedHotFixID = $appliedHotFixID -join ";"
            SMB1FeatureEnabled = $smb1FeatureEnabled
            SMB1ProtocolEnabled = $smb1ProtocolEnabled
            Port139Enabled = $port139TestConnection
            Port445Enabled = $port445TestConnection
        }
    }
}

process {
    switch ($PSCmdlet.ParameterSetName) {
        "ByComputerName" {
            foreach ($nameValue in $Name) {
                try {
                    $protocol = "WSMAN"
                    $protocolTest = Test-WSMan -ComputerName $name
                    if ($null -eq $protocolTest -or $protocol.ProductVersion -contains "Stack: 2.0") {
                        $protocol = "DCOM"
                    }
                } catch {
                    $protocol = "DCOM"
                }

                try {
                    $sessionParameters = @{
                        ComputerName = $nameValue
                        SessionOption = (New-CimSessionOption -Protocol $protocol)
                        ErrorAction = "Stop"
                    }

                    $credentialBoundParameter = $PSBoundParameters.ContainsKey(
                        "Credential"
                    )

                    if ($credentialBoundParameter) {
                        $sessionParameters.Add(
                            "Credential", $Credential
                        )
                    }

                    $session = New-CimSession @sessionParameters
                } catch {
                    Write-Error -Message $_.ToString()
                    continue
                }
                $output = Get-Data -CimSession $session -HotfixIDs $hotFixIDs

                Write-Output -InputObject $output

                Remove-CimSession -CimSession $session
            }
        }

        "ByCimSession" {
            foreach ($cimSessionValue in $CimSession) {
                $output = Get-Data -CimSession $cimSessionValue -HotfixIDs $hotFixIDs

                Write-Output -InputObject $output
            }
        }
    }
}