Skip to main content

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


Comments

Popular posts from this blog

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.

How to run GPResult on a remote client with PowerShell

In the past, to run the GPResult command, you would need to either physically visit this client, have the user do it, or use and RDP connection.  In all cases, this will disrupt the user.  First, you need PowerShell remoting enabled on the target machine.  You can do this via Group Policy . Open PowerShell and type this command. Invoke-Command –ScriptBlock {GPResult /r} –ComputerName <ComputerName> Replace <ComputerName> with the name of the target.  Remember, the target needs to be online and accessible to you.

Error icon when creating a GPO Preference drive map

You may not have an error at all.  Take a look at the drive mapping below. The red triangle is what threw us off.  It is not an error.  It is simply a color representation of the Replace option of the Action field in the properties of the drive mappings. Create action This give you a green triangle. The Create action creates a new mapped drive for users. Replace Action The Replace action gives you a red triangle.  This action will delete and recreate mapped drives for users. The net result of the Replace action is to overwrite all existing settings associated with the mapped drive. If the drive mapping does not exist, then the Replace action creates a new drive mapping. Update Action The Update action will have a yellow triangle. Update will modify settings of an existing mapped drive for users. This action differs from Replace in that it only updates settings defined within the preference item. All other settings remain as configured on the ma...