Cryptolocker Honeypot FileSystemWatcher

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

$to = "joe@blow.com"
$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 = "alert@nowhere.com"
    $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 "ben22@nowhere.com"
        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 "ben22@nowhere.com"
            sendMail -s $email -to "5555555555@txt.bell.ca"
            Exit

        }

    }

}

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 Resource Kit.

Другие вопросы по тегам