Saturday 24 November 2018

Sigcheck a user profile

The following PowerShell code was built for a malware scanning module. It uses the Microsoft tool Sigcheck to scan for .exe files in a users profile, checks the results with VirusTotal and logs them. It utilises a .csv file as a whitelist of trusted Publishers that I created for omission to reduce the number of results. The code implements a Try/Catch protocol to test certain parameters before proceeding, aiding in error logging should any issues occur prior to scanning. The tool can ultimately be incorporated as a module so you can call it straight from a PowerShell console.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
function Get-SigcheckUserProfile {
<#
.SYNOPSIS
Performs a Sysinternals Sigcheck scan on a user profile.
.DESCRIPTION
Get-SigcheckUserProfile uses the Sysinternals tool 'Sigcheck' on
a username to scan their profile and filter out results
from known-Publishers regarded as safe.
.PARAMETER User
Username of the profile to scan.
.PARAMETER PublisherCSV
Path of the 'Valid Sigcheck Publishers.csv' file to filter out known-Signers.
Defaults to current Powershell directory.

.PARAMETER LogErrors
Specify this switch to create a text log file of usernames
that could not be queried.
.PARAMETER ErrorLog
When used with -LogErrors, specifies the file path and name
to which failed usernames will be written. Defaults to
current Powershell directory.
.EXAMPLE
Get-SigcheckUserProfile -User abc123
.EXAMPLE
Get-SigcheckUserProfile -User abc123 -PublishersCSV 'C:\Valid Sigcheck Publishers.csv'
.EXAMPLE
Get-SigcheckUserProfile -User abc123 | Export-Csv 'C:\Results.csv' -NoTypeInformation
#>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True,
                   ValueFromPipeline=$True,
                   HelpMessage="Username of account")]
        [Alias('Username')]
        [string[]]$User,

        #'Leaf' specifies provided path must be to a file
        [ValidateScript({Test-Path $_ -PathType 'Leaf'})]
        #Gets current working location and looks for specific file
        [string]$PublisherCSV = ((Get-Location).Path + '\Valid Sigcheck Publishers.csv'),

       
[string]$ErrorLog = (Get-Location).Path,
       
[string]$LogErrors
    )

    BEGIN {
        Write-Verbose "Error log will be $ErrorLog"
    }

    PROCESS {
        Write-Verbose 'Beginning PROCESS block'

        Try {
            #Variable set to true for 'ok'
            $everything_ok = $true

            #Check user profile exists
            If (Test-Path ($UserProfile = "\\userfs1\profiles\$User")) {
                #Check 'Valid Sigcheck Publishers.csv' file exists, otherwise set variable to false
                If (!($Publisher = Get-Content "$PublisherCSV")) {
                    $everything_ok = $false
                }
            }
            Else {
                #If user profile does not exist display warning, and set variable to false
                Write-Warning "$user not found"
                $everything_ok = $false
            }

            #Check Sigcheck.exe tool exists as remote PC will be initiating scan
            If (!(Test-Path 'C:\Program Files (x86)\IT Services\Tools\Sigcheck.exe')) {
                Write-Warning 'Sigcheck.exe not found'
                $everything_ok = $false
            }

        } Catch {
            #If the above fails then log captured errors and end script
            $everything_ok = $false
            If ($LogErrors) {
                $User | Out-File $ErrorLog -Append
                Write-Warning $_.Exception.Message
            }
        }

        #If the above has passed then proceed with initiating scan
        If ($everything_ok) {

            Write-Verbose "Scanning $UserProfile"

            #Run specific Sigcheck commands to determine scan-type. Removes some unnecessary data from results and accepts automatic prompt
            $sig = sigcheck.exe -e -s -c -v -vt -nobanner -accepteula $UserProfile | ConvertFrom-Csv
           
            #Take each returned item and check against list of trusted Publishers so they can be omitted
            $sig | ForEach-Object {
                #Only performs Publisher check if there's an entry in it
                If ($_.Publisher -ne $NULL) {
                    #Replaces commas in Publisher field with nothing, so that accepted Publishers.csv can be used, otherwise commas do not filter
                    $_.Publisher = $_.Publisher.replace(",","")
                    #Only log those results not on whitelist
                    $sig = $sig | Where-Object {$_.Publisher -NotIn $Publisher}
                }   
            }

            Write-Verbose 'Scan complete'
            Write-Output $sig

        }
    }
   
    END {}
}

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Get-SigcheckUserProfile.ps1
Valid Sigcheck Publishers.csv

No comments:

Post a Comment