Cryptolocker Honeypot FileSystemWatcher

Я новичок, когда дело доходит до написания сценариев, поэтому, пожалуйста, потерпите меня. Я пытаюсь создать сценарий, который будет отслеживать файл-приманку, который добавляется ко всем общим файловым ресурсам на сервере. Когда скрипт увидит, что файл был изменен, он заблокирует доступ пользователю, который внес изменения, и отправит электронное письмо. Сценарий работает нормально, кроме FileSystemWatcher. Он будет отслеживать только последний общий ресурс. Я видел здесь похожий пост, но запутался в ответе. Может ли кто-нибудь помочь мне с задачей создания FileSystemWatcher для каждого файла приманки? Я также хотел бы получить любую информацию о том, как я могу улучшить сценарий другими способами. Ваша помощь очень ценится.

$to = "[email protected]"
$File = "test.txt" 
$FilePath = "C:\temp"
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider

## SEND MAIL FUNCTION
function sendMail($s, $to) {
    $smtpServer = "mail.nowhere.com"
    $smtpFrom = "[email protected]"
    $smtpTo = $to

    $messageSubject = $s[0]
    $message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
    $message.Subject = $messageSubject
    $message.IsBodyHTML = $false
    $message.Body = $s[1]

    $smtp = New-Object Net.Mail.SmtpClient($smtpServer)
    $smtp.Send($message)
}

## Get a list of shares and Perform tasks on each location.
$cryptopaths = Get-WmiObject -Class win32_share -filter "Type=0 AND name like '%[^$]'" | ForEach ($_.Path) {
    $cryptopath = $_.Path

    ## Copy the bait file to the share location
    Copy $FilePath\$File $cryptopath\$File -Force

    ##Get files hash
    Try {
        $Origin = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$FilePath\$File")))
        $Copy = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$CryptoPath\$File")))

    }
     ##Error on reading hash
        Catch {
            echo "error reading $CryptoPath\$File" 
        }

    ## If files don't match, then Send messaged and quit
    if (Compare-Object $Origin $Copy){
        ## files don't match
        $subject = "Error logged on $CryptoPath\$File by $env:username on $env:computername"
        $body = "The original file does not match the witness file.  Aborting monitor script."
        $email =@($subject,$body)
        sendMail -s $email -to "[email protected]"
        Exit
        }




    ## CREATE WATCHER ON DIRECTORY
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = $CryptoPath
    $watcher.Filter = $File
    $watcher.IncludeSubdirectories = $false
    $watcher.EnableRaisingEvents = $false
    $watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
}


## Execute Watcher
while($TRUE){
    $result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::Changed `
        -bor [System.IO.WatcherChangeTypes]::Renamed `
        -bor [System.IO.WatcherChangeTypes]::Deleted `
        -bor [System.IO.WatcherChangeTypes]::Created, 1000);
    if ($result.TimedOut){
        continue;
    }

    if ($result.Name -eq $File) {
        ### Make sure the files do not match
        try {
            $FileCheck = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$CryptoPath\$File")))
            if (Compare-Object $Origin $FileCheck){
                ## files don't match
                $body = "Witness file $FilePath\$File on $env:computername has been modified."
                }
        }
        catch {
            ## file deleted
            $body = "Witness file $FilePath\$File on $env:computername has been deleted"
            }
        finally {
            ## Deny owner of changed file access to shares and disconnect their open sessions. Send email alert
            Get-Acl "$CryptoPath\$File" | foreach ($_.Owner) {
            Get-SmbShare | Block-SmbShareAccess –AccountName $_.Owner
            Close-SmbSession –ClientUserName $_.Owner
            }
            $subject = "EMERGENCY ON FILE SERVER -- $FilePath\$File by $env:username on $env:computername"
            $email =@($subject,$body)
            sendMail -s $email -to "[email protected]"
            sendMail -s $email -to "[email protected]"
            Exit

        }

    }

}

person taylor.itnow    schedule 17.07.2014    source источник


Ответы (1)


Проблема в том, что вы создаете экземпляры FileSystemWatcher в цикле (ForEach ($_.Path) {}), но присваиваете их одной и той же переменной $watcher, каждый раз перезаписывая предыдущую ссылку. Выйдя из цикла, вы работаете с переменной $watcher, которая ссылается на созданный вами последний экземпляр FileSystemWatcher, поэтому вы получаете уведомления только для последнего файла.

Чтобы это работало, вы должны использовать тип, который позволяет хранить несколько ссылок, то есть массив. Пример:

$watchers = @();
...
$watcher = New-Object System.IO.FileSystemWatcher;
...
$watchers += $watcher;

Кроме того, я бы предложил использовать подход на основе обработчика событий/обратного вызова/делегата вместо ожидания изменения с помощью WaitForChanged(), потому что ожидание нескольких наблюдателей за файловой системой потребует параллельного решения (ну, в идеале). Используйте Register-ObjectEvent, чтобы зарегистрировать обработчик событий и посмотреть этот пример, в частности : http://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b.

PowerShellPack также имеет командлет Start-FileSystemWatcher, который прекрасно все это завершает, но я не уверен в статусе PowerShellPack в целом. Однако он должен быть частью набора ресурсов Windows 7/8.

person PeterK    schedule 17.07.2014