Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Friday, December 20, 2013

Use PowerShell to Look for Viruses

I’m sitting in the USO at the San Jose airport this evening waiting on a flight back home.  A good friend and Shipmate of mine contacted me with a bit of a virus issue.  He needed a way to scan all of his clients for this bad bug.  He unfortunately did not have access to his organizations central antivirus system.
After a bit of online research, I found what I was looking for.  Either files or registry keys that would mark a potential infection.  I wrote up some code and sent it over to him.  Yes, I could have wrote code very quickly that focused only the little critter running around his network, but what fun would that be.  This code is reusable.
The cmdlet is Search-VirusSignature.  I included a help file to show you how to use it.  It does require access to the Active Directory module and also for all of your clients to have PowerShell Remoting turned on.
Happy Hunting!
Function Search-VirusSignature
{
[cmdletbinding()]
Param(
    [String[]]$RegKey = $Null,
    [String[]]$Files
)

    Function New-ScriptObject
    {
        # Empty VirusSignatureObject
        $Obj = New-Object -TypeName PSObject -Property @{
            'ComputerName' = $Null;
            'Online' = $False;
            'RegValueMatch' = $False;
            'FileValueMatch' = $False;
            'PSSessionAvailable' = $True
        }
        $Obj.PSObject.Typenames.insert(0,"VirusSignatureObject")

        Write-Output $Obj
    } # End: Function New-ScriptObject

    Function Search-RegValue
    {
    Param (
        [String[]]$RegKey,
        [String]$C,
        $Session)

        # Initialize the memory to be used in this function.
        $Found = $False
        $PSPro = $Null
        $OutResult = $False

        # Cycle through each provided registry key.
        ForEach ($R in $RegKey)
        {
            # Discover the key being used.  Since documentation can
            # list the PSDrive value differently, convert the
            # provided drive name to one that PowerShell will
            # recognize.
            Switch -Wildcard ($R)
            {
                "HKEY_CURRENT_USER*" {$PSPro = "HKCU"
                                      $Key = $R.Replace("HKEY_CURRENT_USER","")}
                "HKCU*" {$PSPro = "HKCU"
                         $Key = $R.Replace("HKCU","")}
                "HKEY_LOCAL_MACHINE*" {$PSPro = "HKLM"
                                       $Key = $R.Replace("HKEY_LOCAL_MACHINE","")}
                "HKLM*" {$PSPro = "HKLM"
                         $Key = $R.Replace("HKLM","")}
            }
           

            # Determine if this key is present.
            $Result = $False
            $Result = Invoke-Command -ScriptBlock {Param ($PSPro, $Key) Test-path -Path "$($PSPro):$($Key)"} `
                -Session $Session `
                -ArgumentList $PSPro, $Key
           
            If ($Result -eq $True {$OutResult = $True}
        }
        Write-Output $OutResult

    } # End: Function Search-RegValue

    Function Search-File
    {
    Param ([String[]]$Files,
           [String]$C,
           $Session)
       
        # Initialize the memory to be used in this function.
        $Found = $False
        $PSPro = $Null
        $OutResult = $False

        ForEach ($F in $Files)
        {

            # Determine if this file is present.
            $Result = $False
            $Result = Invoke-Command -ScriptBlock {Param ($F) Test-path -Path "$($F)"} `
                -Session $Session `
                -ArgumentList $F
           
            If ($Result -eq $True {$OutResult = $True}
        }
        Write-Output $OutResult

    } # End: Search-File


    # For PowerShell V2 Compatibility
    Import-Module ActiveDirectory

    ForEach ($C in (Get-ADComputer -Filter * | Select-Object -ExpandProperty Name))
    {
        #Create the object for this instance.
        $Obj = New-ScriptObject

        # Write the name of the client for this instance.
        $Obj.ComputerName = $C

        # Test for online
        $Obj.Online = Test-Connection -ComputerName $C -Count 1 -Quiet
   
        If ($Obj.Online -eq $True)
        {
            # Establish a PSSession to the client.
            Try
            {
                $Session = New-PSSession -ComputerName $C -ErrorAction Stop
            }
            Catch
            {
                $Obj.PSSessionAvailable = $False
            }

            If ($Obj.PSSessionAvailable -eq $True)
            {
                # Search for a matching registry value.
                If ($RegKey -ne $NUll)
                    {
                         $Obj.RegValueMatch = Search-RegValue -RegKey $RegKey `
                                                                -c $Obj.ComputerName `
                                                                -Session $Session
                    }
           
                # Search for a matching file.
                If ($Files -ne $NUll)
                    {$Obj.FileValueMatch = Search-File -Files $Files `
                                                       -C $Obj.ComputerName `
                                                       -Session $Session
                    }
                $Session | Remove-PSSession
            } # End: If ($Obj.PSSessionAvailable -eq $True)
        } # End: If ($Obj.Online -eq $True)  

       
        # Send the object to the pipeline
        Write-Output $Obj
    }

<#
.SYNOPSIS
Allows you to scan for potential viruses signatures in your environment.

.DESCRIPTION
Allows you to search for registry keys and files that may signal if a virus is present.

You will have to provide the registry keys and or files to search for.  This script does
not contain any virus signatures.

.PARAMETER RegKey
A comma separated list of all registry keys to search for.  The is a comma separate list
of possible values.  Each value must be contained inside of double quotes.

The following example contains 2 separate registry keys.
"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\aqjunayn", "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\aqjunayn"

.PARAMETER Files
A comma separated list of all files to search for.  The is a comma separate list
of possible values.  Each value must be contained inside of double quotes.

The following example contains 2 separate files to be searched for.
"C:\Windows\System32\aqjunayn.exe", "C:\Documents and Settings\user-account-name\aqjunayn.exe"

.EXAMPLE
Search-VirusSignature -RegKey "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\aqjunayn", "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\aqjunayn" -Files  "C:\Windows\System32\aqjunayn.exe", "C:\Documents and Settings\user-account-name\aqjunayn.exe"

Searches for 2 potential registry keys and 2 potential files that may signal a particular virus.

.NOTES
Script requirements:
- Active Directory Module for Windows PowerShell.
    You can get access to the Active Directory Module for Windows PowerShell
    by downloading and installing the Remote Server Administrator tools from
    Microsoft or running this script on a Domain Controller

- PowerShell Remoting turned on on all clients.
    PowerShell remoting is turned on for all domain joined Windows 8 and
    Windows Server 2012 clients.

    You can enable PowerShell remoting for Windows 7 and Server 2008 R2
    using these instructions:
    http://mctexpert.blogspot.com/2011/03/enable-powershell-v2-remote-management.html

Object Properties Definitions
ComputerName:       The name of the client where contact is being attempted.
Online:             The client's online status  Offline clients will not be
                    contacted.
RegValueMatch:      If True, the a registry value that you have search for
                    was found.
FileValueMatch:     If True, the a file that you have search for was found.
PSSessionAvailable: True represents a successful PSSession establishment.
                    Unsuccessful sessions will not be tested for Reg and file
                    matches.

Only client that return a true value for both Online and PSSessionAvailable
have been tested.

===============================================================================
== Cmdlet: Search-VirusSignature                                             ==
== Module: PSV3                                                              ==
==---------------------------------------------------------------------------==
== Author: Jason A. Yoder                                                    ==
== Company: MCTExpert or Arizona, Inc.                                       ==
== Blog: MCTExpert.Blogspot.com                                              ==
== Twitter: @JasonYoder_MCT                                                  ==
==---------------------------------------------------------------------------==
== License Information:                                                      ==
== Copyright 2013 - MCTExpert, Inc.                                          ==
== This code is licensed for personal use only.  This code may not be        ==
== re published or distributed in whole or in part without the express       ==
== written consent of MCTExpert of Arizona, Inc.  All rights reserved.       ==
==---------------------------------------------------------------------------==
== Disclaimer: The user takes full responsibility for the execution of any   ==
== PowerShell code.  This code is provided without warranty or support.      ==
== As with all PowerShell code, review it and test it in a test environment  ==
== prior to using it in a production environment.  The user takes complete   ==
== responsibility for the results of executing this code.                    ==
===============================================================================


#>

} # End: Search-VirusSignature