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,118
    Likes Received:
    359
    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,719
    Likes Received:
    819
    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,118
    Likes Received:
    359
    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,719
    Likes Received:
    819
    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,118
    Likes Received:
    359
    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,719
    Likes Received:
    819
    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,118
    Likes Received:
    359
    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,118
    Likes Received:
    359
    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
    Ian, Sep 23, 2017
    #8
  9. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,719
    Likes Received:
    819
    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
    #9
  10. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,118
    Likes Received:
    359
    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
    #10
  11. Ian

    Trouble Noob Whisperer Moderator

    Joined:
    Nov 19, 2013
    Messages:
    10,602
    Likes Received:
    1,622
    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
    #11
    Ian likes this.
  12. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,719
    Likes Received:
    819
    Just a bug I contracted late last year during my operation which is stubbornly persisting.

    I'll be right.
     
    Regedit32, Sep 25, 2017
    #12
    Ian and Trouble like this.
  13. Ian

    Trouble Noob Whisperer Moderator

    Joined:
    Nov 19, 2013
    Messages:
    10,602
    Likes Received:
    1,622
    Location:
    Northwest Indiana U.S.A.
    Good to hear.
    Be well and take care of yourself.
     
    Trouble, Sep 25, 2017
    #13
  14. Ian

    Ian Administrator

    Joined:
    Oct 27, 2013
    Messages:
    1,118
    Likes Received:
    359
    I've made some good progress, so should hopefully have it fixed soon. I keep lapsing in to bad habits and mixing my coding languages.

    I forgot that "true" and "false" values should be $true and $false in powershell.
     
    Ian, Sep 27, 2017
    #14
  15. Ian

    davehc

    Joined:
    Nov 19, 2013
    Messages:
    2,881
    Likes Received:
    588
    Location:
    Denmark
    Gosh. I wasnt following this thread. A little over my head.
    I wondered what had happened to regedit and went into the profile and, subsequently, to here

    Get well soon Pal.
     
    davehc, Sep 29, 2017
    #15
    Ian and Trouble like this.
  16. Ian

    Regedit32 Moderator

    Joined:
    Mar 4, 2016
    Messages:
    2,719
    Likes Received:
    819
    Thanks Dave

    Hoping to get back home next weekend. The medications they have been giving me appear to finally be winning the battle.
     
    Regedit32, Sep 30, 2017
    #16
    Ian likes this.
  17. Ian

    davehc

    Joined:
    Nov 19, 2013
    Messages:
    2,881
    Likes Received:
    588
    Location:
    Denmark
    Good show !
     
    davehc, Sep 30, 2017
    #17
    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,436
    davehc
    Jun 4, 2015
  2. rumour6
    Replies:
    1
    Views:
    1,905
    Regedit32
    Jul 28, 2017
  3. Lee W
    Replies:
    3
    Views:
    2,279
    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,543
    Trouble
    Nov 5, 2015
  5. Tech Addict
    Replies:
    3
    Views:
    743
    Monafraj
    Mar 8, 2017
  6. gogreen
    Replies:
    5
    Views:
    557
    gogreen
    Aug 2, 2016
  7. Karen L
    Replies:
    4
    Views:
    339
    Karen L
    Apr 13, 2017
  8. Regedit32
    Replies:
    0
    Views:
    404
    Regedit32
    Aug 4, 2017
Loading...