Tag Archives: InfoSec

[Powershell] Detect and attempt to remediate/isolate WannaCry

*** This has NOT undergone thorough testing yet ***

*** UPDATE:  Upon further testing, I have found that this script MUST be run as NT/AUTHORITY SYSTEM, otherwise the Windows Updates will fail.

*** UPDATE 2:  It was found that unpatched clients would not update unless and until the CCM client was remediated.  Apparently, broken SCCM updating breaks Windows Updates, even when checking online.  That being the case, I recommend Jason Sandys’ excellent client health script.

This script is designed to be deployed via GPO to detect machines that are vulnerable to or infected by WannaCrypt.  If they are vulnerable, it will attempt to run online updates.  If they are infected, it will attempt to remove them from the network via setting NICs to APIPA address and alert the user to contact technical support.  I have commented out the APIPA portion for ease of testing.

This script was created at the request of management over concerns of machines with nonfunctional SCCM clients.  I hereby release this script to the public domain, and you may use this script in part or in whole.

This is a rough draft, and will likely undergo further revisions/improvements, but has passed minimal QA.  I have attempted to give credit where I borrowed portions of code via comments.

$message = “***WARNING***`n`nWe have disabled this computer to prevent the spread of a WannaCry malware infection, which has been detected on this machine.  Please contact Technical Support as soon as possible to correct this.”
 
$buildDate = (Get-Item c:\windows).CreationTime
$dateDiff = New-TimeSpan -Start $buildDate -End $(get-date)
 
if ($dateDiff.TotalDays -lt 2) {exit} # For freshly-imaged machines
 
function checkForInfection {
 
    if (test-path “c:\windows\mssecsvc.exe”) {return $true}
    if (test-path “c:\windows\tasksche.exe”) {return $true}
    if (test-path “c:\windows\qeriuwjhrf”) {return $true}
    if (test-path “HKLM:\SOFTWARE\WanaCrypt0r\”) {return $true}
    $arrVolumes = gwmi Win32_Volume | ? {$_.DriveLetter}
    foreach ($volume in $arrVolumes) {
        $driveletter = $volume.DriveLetter + “\”
        if (gci $driveletter -Recurse -ErrorAction SilentlyContinue | ? {($_.Extension -Match “wnry”) -or ($_.Extension -Match “wncry”)}) {return $true}
    }
 
    return $false
 
}
 
function checkVuln {
 
    if ($strOsVer -eq “10.0.15063”) {return $false} # 1703 is NOT vulnerable, at least according to https://www.askwoody.com/2017/how-to-make-sure-you-wont-get-hit-by-wannacrywannacrypt/
    foreach ($kb in $arrKbs) {if ($installedPatches.Title -like “*$kb*”) {return $false}}
    return $true
 
}
 
function getInstalledPatches {
 
    #http://stackoverflow.com/questions/36761787/how-to-get-all-details-from-installed-updates-window
    $session = [activator]::CreateInstance([type]::GetTypeFromProgID(“Microsoft.Update.Session”))
    $us = $session.CreateUpdateSearcher()
    $qtd = $us.GetTotalHistoryCount()
    return $us.QueryHistory(0, $qtd)
 
}
 
function killAdapters {
 
    $netIndex = (gwmi win32_networkadapter | ? {($_.netconnectionid -like “*ethernet*”) -or ($_.netconnectionid -like “*wi*”)})
    foreach ($net in $netIndex) {netsh interface ip add address $($net.interfaceindex) 169.254.0.0}
 
}
 
function runUpdates {
 
    $Searcher = New-Object -ComObject Microsoft.Update.Searcher
    $Session = New-Object -ComObject Microsoft.Update.Session
    $Installer = New-Object -ComObject Microsoft.Update.Installer
 
    $Searcher.Online = $true
   
    $SearchResult = $Searcher.Search(“IsInstalled=0 and Type=’Software'”).Updates
 
    $Downloader = $Session.CreateUpdateDownloader()
    $Downloader.Updates = $SearchResult
    $Downloader.Download()
   
    $Installer.Updates = $SearchResult
    $Installer.Install()
 
}
 
$boolVulnerable = $false
$boolInfected = $false
 
$strOS = (gwmi Win32_OperatingSystem).Caption
$strOsVer = (gwmi Win32_OperatingSystem).Version
$installedPatches = getInstalledPatches
 
 
if (($strOS -like “*Windows 10*”) -or ($strOS -like “*2016*”)) {$arrKbs =@(“KB4012606”,“KB4019474”,“KB4015221”,“KB4016637”,“KB4013198”,“KB4015219”,“KB4016636”,“KB4019473”,“KB4013429”,“KB4015217”,“KB4015438”,“KB4016635”,“KB4019472”)}
else {$arrKbs = @(“KB4012212”,“KB4012213”,“KB4012214”,“KB4012598”,“KB4015550”,“KB4019215”,“KB4015549”,“KB4019264”,“KB4012216”)} #For Windows 7, Server 2008 R2 SP1, Windows Server 2012, Server 2012 R2 and Windows 8.1, Windows Vista and Server 2008 SP2, and XP
 
$boolVulnerable = checkVuln
$boolInfected = checkForInfection
 
if ($boolInfected) {
 
    [System.Windows.MessageBox]::Show($message)
    #killAdapaters
    exit
 
}
 
if ($boolVulnerable) {
 
    runUpdates
 
}
Advertisements