Folder Tripwire Powershell

Discussion in 'Programming and Windows PowerShell' started by Ian, Sep 6, 2017.

  1. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,067
    Likes Received:
    336
    I'm working on creating a tripwire script, so that I'm alerted to certain filetypes being created in a folder. It works as expected for the most, although I had intended to receive an e-mail with ALL files changes occurring in a 5 minute period (to batch them, rather than an e-mail each time).

    However, it seems to e-mail be batches of 8 files at a time and spaces sending the e-mail every 5 minutes. For example, if I triggered 80 file alerts in 1 minute, it would alert me to 8 files changing each 5 minutes, taking 10 e-mails to notify me of all changes, rather than just 1.

    Can you see anything in this script that would cause this problem?

    Code (Text):
    ### SERVER NAME

    $serverName = "TestServer"

    ### SET PHP FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
        $phpwatcher = New-Object System.IO.FileSystemWatcher
        $phpwatcher.Path = "C:\www\vhosts"
        $phpwatcher.Filter = "*.php"
        $phpwatcher.IncludeSubdirectories = $true
        $phpwatcher.EnableRaisingEvents = $true

    ### SET SQL FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
        $sqlwatcher = New-Object System.IO.FileSystemWatcher
        $sqlwatcher.Path = "C:\www\vhosts"
        $sqlwatcher.Filter = "*.sql"
        $sqlwatcher.IncludeSubdirectories = $true
        $sqlwatcher.EnableRaisingEvents = $true

    ### SET ZIP FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
        $zipwatcher = New-Object System.IO.FileSystemWatcher
        $zipwatcher.Path = "C:\www\vhosts"
        $zipwatcher.Filter = "*.zip"
        $zipwatcher.IncludeSubdirectories = $true
        $zipwatcher.EnableRaisingEvents = $true

    ### SET RAR FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
        $rarwatcher = New-Object System.IO.FileSystemWatcher
        $rarwatcher.Path = "C:\www\vhosts"
        $rarwatcher.Filter = "*.rar"
        $rarwatcher.IncludeSubdirectories = $true
        $rarwatcher.EnableRaisingEvents = $true


    ### SET EMAIL SETTINGS

        $From = "notify@example.com"
        $To = "alert@example.com"
        $SMTPServer = "smtp.example.com"
        $SMTPPort = "587"
        $Username = "notify@example.com"
        $Password = "password"
        $subject = "File Change Log - $serverName"

    $global:body = @()


    ### DEFINE PHP ACTIONS AFTER A EVENT IS DETECTED
        $phpaction = { $path = $Event.SourceEventArgs.FullPath
                    $changeType = $Event.SourceEventArgs.ChangeType
                    $logline = "$(Get-Date), ${changeType}: $path"
                    Add-content "$PSScriptRoot\Logs\PHP\$(get-date -f yyyy-MM-dd).txt" -value $logline
                    Write-Output $logline

                    $global:changes = "true"
                    $global:body += $logline
                    $global:body += "`r`n"
                  }  

    ### DEFINE SQL ACTIONS AFTER A EVENT IS DETECTED
        $sqlaction = { $path = $Event.SourceEventArgs.FullPath
                    $changeType = $Event.SourceEventArgs.ChangeType
                    $logline = "$(Get-Date), ${changeType}: $path"
                    Add-content "$PSScriptRoot\Logs\SQL\$(get-date -f yyyy-MM-dd).txt" -value $logline
                    Write-Output $logline

                    $global:changes = "true"
                    $global:body += $logline
                    $global:body += "`r`n"
                  }  

    ### DEFINE ZIP ACTIONS AFTER A EVENT IS DETECTED
        $zipaction = {
       
                    if ($Event.SourceEventArgs.Name -notlike "*.log.zip") {
       
                    $path = $Event.SourceEventArgs.FullPath
                    $changeType = $Event.SourceEventArgs.ChangeType
                    $logline = "$(Get-Date), ${changeType}: $path"
                    Add-content "$PSScriptRoot\Logs\ZIP\$(get-date -f yyyy-MM-dd).txt" -value $logline
                    Write-Output $logline

                    $global:changes = "true"
                    $global:body += $logline
                    $global:body += "`r`n"
                    }
                  }  

    ### DEFINE RAR ACTIONS AFTER A EVENT IS DETECTED
        $raraction = { $path = $Event.SourceEventArgs.FullPath
                    $changeType = $Event.SourceEventArgs.ChangeType
                    $logline = "$(Get-Date), ${changeType}: $path"
                    Add-content "$PSScriptRoot\Logs\RAR\$(get-date -f yyyy-MM-dd).txt" -value $logline
                    Write-Output $logline

                    $global:changes = "true"
                    $global:body += $logline
                    $global:body += "`r`n"
                  }  

    ### DECIDE WHICH PHP EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY
        $phpcreated = Register-ObjectEvent $phpwatcher "Created" -Action $phpaction
        $phpchanged = Register-ObjectEvent $phpwatcher "Changed" -Action $phpaction
        $phpdeleted = Register-ObjectEvent $phpwatcher "Deleted" -Action $phpaction
        $phprenamed = Register-ObjectEvent $phpwatcher "Renamed" -Action $phpaction

    ### DECIDE WHICH SQL EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY
        $sqlcreated = Register-ObjectEvent $sqlwatcher "Created" -Action $sqlaction
        $sqlchanged = Register-ObjectEvent $sqlwatcher "Changed" -Action $sqlaction
        $sqldeleted = Register-ObjectEvent $sqlwatcher "Deleted" -Action $sqlaction
        $sqlrenamed = Register-ObjectEvent $sqlwatcher "Renamed" -Action $sqlaction

    ### DECIDE WHICH ZIP EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY
        $zipcreated = Register-ObjectEvent $zipwatcher "Created" -Action $zipaction
        $zipchanged = Register-ObjectEvent $zipwatcher "Changed" -Action $zipaction
        $zipdeleted = Register-ObjectEvent $zipwatcher "Deleted" -Action $zipaction
        $ziprenamed = Register-ObjectEvent $zipwatcher "Renamed" -Action $zipaction

    ### DECIDE WHICH RAR EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY
        $rarcreated = Register-ObjectEvent $rarwatcher "Created" -Action $raraction
        $rarchanged = Register-ObjectEvent $rarwatcher "Changed" -Action $raraction
        $rardeleted = Register-ObjectEvent $rarwatcher "Deleted" -Action $raraction
        $rarrenamed = Register-ObjectEvent $rarwatcher "Renamed" -Action $raraction

        while ($true) {
            sleep 300

            if ($global:changes -eq "true") {

                    $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
                    $smtp.EnableSSL = $true
                    $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
                    $smtp.Send($From, $To, $subject, $body);

                    Write-Output "E-Mail Sent"

                    $global:changes = "false"
                    $global:body = @()
                    $global:body += "PHP Change Log - $serverName"
                    $global:body += "`r`n"
            }

        }
     
    Ian, Sep 6, 2017
    #1
    1. Advertisements

  2. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,615
    Likes Received:
    766
    Ian's pop quiz for kindergarten class: The children must get both parts correct to move on to Primary School!

    Part 1.

    Circle the letter that is correct answer:
    1. 1 apple + 1 apple = A. 0 apples, B. 1 apple, C.11 Apples, D. 2 Apples

    Part 2.

    I'm going to need a good strong cup of coffee to wrap my head around your batch issue Ian and expect to graduate with O levels if I manage to work it out :D
     
    Regedit32, Sep 6, 2017
    #2
    1. Advertisements

  3. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,067
    Likes Received:
    336
    Haha, yes it is a bit of a brain twister! I'm still working on figuring it out, I'll try and simplify it down to see if I can get it to print batches of changed files every 5 mins to screen, then see if that still has the same problem. I'll keep you updated :D.
     
    Ian, Sep 7, 2017
    #3
  4. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,615
    Likes Received:
    766
    You know how each particular file type has checking for the event:

    "Changed" -Action $<some variable here>

    Have you tried pausing it there before it continues, e.g.:

    "Changed" -Action $<some variable>, 10000

    Where 10000 represents milliseconds and thus would be a 10 second pause

    Perhaps a pause here or on other events would allow the Batch time to create the message body before sending it?!


    Your idea here is interesting given normally a tripwire is comparing apples with apples, i.e. you set up a constant file or filehash to be used similar to a Antivirus definitions list, to compare the state of file at time tested with the constant, which is how you know whether its been altered in any way.

    But the problem in your case is if I understood correctly, you are not checking for alterations to file types, but rather, whether new files of X file type have been added to the server.


    If you get it working that would be a neat way to alert you to any potential malware attack with a few additional modifications to your current Script.
     
    Regedit32, Sep 7, 2017
    #4
    Ian likes this.
  5. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,067
    Likes Received:
    336
    Thanks, I'll give that a try this weekend :). Yup, I'm using it as part of a malware detection script - once it's working I'll modify it to notify via e-mail, windows alerts, logging, etc... the script needs a good clean up before it's ready :D.
     
    Ian, Sep 7, 2017
    #5
  6. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,615
    Likes Received:
    766
    You'll need to modify it to search for malware in humans too :D

    The virus I contracted pre surgery last December is still affecting me 9 months on lol


    stubborn bugs these days :mad:
     
    Regedit32, Sep 7, 2017
    #6
  7. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,067
    Likes Received:
    336
    I think I may need a few more lines of code for that ;).

    Ouch :( - I hope it's not troubling you too much!
     
    Ian, Sep 8, 2017
    #7
  8. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,067
    Likes Received:
    336
    I've simplified the script greatly (and fixed the previousl problem), but the last thing I'd like to do is to try and filter the monitored filetypes. By default, FileSystemWatcher can't handle multiple extensions - so I'm telling it to monitor "*.*". I'd like to filter the results to include "*.php, *.rar, *.zip" for example.

    Do you know how I might achieve that? I've had a search and found an example for C#, but I'm not sure how to translate that to PowerShell. Once I've got that solved, the script is pretty much ready to publish :).

    Here's the simplified code:

    Code (PowerShell):
    ### MONITORING SETTINGS

        $serverName = "Test Server"   #server name
        $emailFreq = "10"   #number of seconds between e-mail notification batches
        $monitorFolder = "c:\"   #folder to monitor (i.e. "C:\Monitor")
        $fileFilter = "*.*"   #filetypes to monitor (i.e. "*.php")

    ### EMAIL SETTINGS

        $From = "test@test.com"
        $To = "test@test.com"
        $SMTPServer = "smtp.test.com"
        $SMTPPort = "587"
        $Username = "test@test.com"
        $Password = "test"


    ### SET PHP FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
        $filewatcher = New-Object System.IO.FileSystemWatcher
        $filewatcher.Path = $monitorFolder
        $filewatcher.Filter = $fileFilter
        $filewatcher.IncludeSubdirectories = $true
        $filewatcher.EnableRaisingEvents = $true

    ### DEFINE PHP ACTIONS AFTER A EVENT IS DETECTED
        $fileaction = { $path = $Event.SourceEventArgs.FullPath
                    $changeType = $Event.SourceEventArgs.ChangeType
                    $logline = "$(Get-Date), ${changeType}: $path"
                    Write-Output $logline

                    $global:changes = "true"
                    $global:body += $logline
                    $global:body += "`r`n"
                  }  

    ### DECIDE WHICH PHP EVENTS SHOULD BE WATCHED + SET CHECK FREQUENCY
        $filecreated = Register-ObjectEvent $filewatcher "Created" -Action $fileaction
        $filechanged = Register-ObjectEvent $filewatcher "Changed" -Action $fileaction
        $filedeleted = Register-ObjectEvent $filewatcher "Deleted" -Action $fileaction
        $filerenamed = Register-ObjectEvent $filewatcher "Renamed" -Action $fileaction


        while ($true) {
            sleep $emailFreq

            if ($global:changes -eq "true") {

                    $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
                    $smtp.EnableSSL = $true
                    $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
                    $smtp.Send($From, $To, "File Change Log - $serverName", $global:body);

                    Write-Output "E-Mail Sent"

                    $global:changes = "false"

                 
            }

        }
     
    Last edited: Sep 23, 2017 at 3:49 PM
    Ian, Sep 23, 2017 at 3:43 PM
    #8
  9. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,615
    Likes Received:
    766
    Hi Ian

    I'm staring at this on my phone, so its a little tricky to read everything.

    I have an idea but can't test it till I get out of hospital and back to the Desktop. Failing that though I could convert the .php to .ps1 for you.

    The method you are trying to manipulate though normally only takes one argument, but you could create an Object and pass filters to it.

    You'll want to avoid .api and concentrate on .NET
     
    Regedit32, Sep 25, 2017 at 2:44 PM
    #9
  10. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,067
    Likes Received:
    336
    I hope everything is ok @Regedit32, I didn't realise you were in hospital at the moment. Don't worry about it for now, I'll keep plugging away at it and if I'm still stuck when you're recovered I'll be very grateful for your input :).

    As it happens, I'm working on the code at the moment, so I'll hopefully have made some progress soon.
     
    Ian, Sep 25, 2017 at 2:48 PM
    #10
  11. Ian

    Trouble Noob Whisperer Moderator

    Joined:
    Nov 19, 2013
    Messages:
    10,407
    Likes Received:
    1,564
    Location:
    Northwest Indiana U.S.A.
    What's up Timothy?
    Hope you're better soon and nothing too serious is going on.
    Please take care and get well and please keep us posted.
    In the mean time my thoughts and prayers are with you.
     
    Trouble, Sep 25, 2017 at 3:31 PM
    #11
    Ian likes this.
    1. Advertisements

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Similar Threads
  1. sbur87

    Where Is Powershell?

    sbur87, Jun 4, 2015, in forum: Programming and Windows PowerShell
    Replies:
    2
    Views:
    1,255
    davehc
    Jun 4, 2015
  2. rumour6
    Replies:
    1
    Views:
    1,737
    Regedit32
    Jul 28, 2017
  3. Lee W
    Replies:
    3
    Views:
    2,150
    davidhk129
    Oct 5, 2015
  4. 52Yankee

    Windows.old folder still has just one file. Folder can't be deleted

    52Yankee, Nov 4, 2015, in forum: Installation, Setup and Updates
    Replies:
    6
    Views:
    2,446
    Trouble
    Nov 5, 2015
  5. Tech Addict
    Replies:
    3
    Views:
    702
    Monafraj
    Mar 8, 2017
  6. gogreen
    Replies:
    5
    Views:
    499
    gogreen
    Aug 2, 2016
  7. Karen L
    Replies:
    4
    Views:
    308
    Karen L
    Apr 13, 2017
  8. Regedit32
    Replies:
    0
    Views:
    227
    Regedit32
    Aug 4, 2017
Loading...