Close, but need assistance configuring IPS/IDS

Ubuntu 14
Mikrotik CCR1036
6.24

I am not sure if this is the best way to go, regarding an IPS/IDF solution, but I have been following this wiki:
http://wiki.mikrotik.com/wiki/Mikrotik_IPS_IDS

Traffic from the CCR is sent by snort via the following command and works fine:

sudo ./trafr -s | snort -r -


I’m getting lost with the remaining instructions for scripting an rules that block offenders, having not done any scripting before.

Does anyone have time to post the scripts as they understand them to be? Not quite sure what should be taken literally, or is just informational.


Open to other IPS/IDF ideas, if effective.

Here is an example of my what I am attempting to do: According to the wiki, I would create a scipt via the following:

:global ip

local time ([/system clock get time]+(“00:05:00”))
if ($time > “23:59:59”) do={

:local time “00:05:00”

}

/ip firewall address-list add list=blacklist address=$ip comment=$time


However, I get the following error when I run the command:

value of address expects range of ip addresses

That script expects an environment variable called ‘ip’ to be set already, and will use the contents of that variable to specify the IP to block, so basically, the script logging into the Mikrotik to execute the block will set :global ip → “190.0.2.251” and then run the block script.

This Wiki is at least slightly outdated now, because it shows an example of a script to search the address list for “expiration” of older entries. This functionality is now native to Mikrotik - you can specify a timeout when you create the entry, and it will delete itself automatically.

I understand that $ip is a variable. However, it is not populated until a php script is run on the snort box and populates the black list with potential offenders. I just don’t have enough knowledge yet on how to add the provided scripts from the wiki to the Mikrotik side correctly without getting errors.


php script:

sendMikrotik($mt,$user,$pass,$filter) { $connection = ssh2_connect($mt); ssh2_auth_password($connection,$user,$pass); sleep(1); $stream = ssh2_exec($connection, ':global ip '.$filter); $stream = ssh2_exec($connection, ‘/system script run filter’); $stream = ssh2_exec($connection, ‘quit’); }

Roger that.

Go into system > scripts.
You can add a script there, give it a name, and then copy/paste your script into the “Source” block. Set the permissions, etc. Any time you want to run it, you can click the Run button in Winbox, or from the command line I think it will be
/system scripts run 0
(or whatever the index of the correct script ends up being)

There may be a better shortcut to execute these scripts - I only rarely run scripts, and always from winbox.

You can also manually define variables in the Environment tab, too… while testing scripts, it’s kind of handy.

Thank you! I is this a single script, or two different scripts and would it be created in system/scripts?

:global ip

local time ([/system clock get time]+(“00:05:00”))
if ($time > “23:59:59”) do={

:local time “00:05:00”

}

/ip firewall address-list add list=blacklist address=$ip comment=$time

This is one script. Basically, it imports the environment variable ip, and then makes a variable called time, sets it to now+5 minutes, and if that rolls over midnight, it sets the time variable (not system time) to 12:05am.

It uses the time variable to set a comment on the blacklisted IP address.
I assume that he has another script which checks for blacklist entries whose time is earlier than now, and then removes them. This is all unnecessary now, since you can specify auto-timeout on address list entries.

(of course, the script has academic / learning value, but its operational usefulness is done)

Thank you! I’m continuing to work on the project, but am stuck on the ssh variable from the php script on the server. Trying to figure out how to change the connection variable to use:

ssh -i /home/raymond/.ssh/id_dsa raymond@10.10.1.1


<?php

$blocked=array();

exec('cat /var/log/suricata/fast.log | grep "`date -d "-1 minute" "+%b %e %H:%M"`"',$lastMin); foreach($lastMin as $line) {

       if (strpos($line,"Priority: 1")!==FALSE || strpos($line,"Misc Attack")!==FALSE)
       {
                       preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $line, $matches);
                       $filter=$matches[0];
                       if (!in_array($filter, $blocked))
                       {
                               $blocked[]=$filter;
                               if (strpos($filter,"10.10.")!==FALSE) continue; //Protected space
			       if (strpos($filter,"64.8.")!==FALSE) continue; //Protected space
                               sendMikrotik('10.10.1.1', 'raymond', 'password',$filter);   // Mikrotik 1
                               
                       }
       }


} function sendMikrotik($mt,$user,$pass,$filter) { $connection = ssh2_connect($mt); ssh2_auth_password($connection,$user,$pass); sleep(1); $stream = ssh2_exec($connection, ':global ip '.$filter); $stream = ssh2_exec($connection, '/system script run filter'); $stream = ssh2_exec($connection, 'quit'); }

Could be there is also a new and better way to do this too.

Use the API protocol for the PHP part. It’s much easier, and far less error prone than SSH.
(I suggest the API client from my signature in particular)

On a related note, it would be better if you do all date and time calculations in PHP, and just feed RouterOS a duration when adding address list items. RouterOS scripting with dates can be extremely error prone.



I wonder if Snort can be made to feed its output to stdout. If it can, instead of checking the syslog regularly, you could make a continuously running PHP process that takes Snort’s output (the same way Snort takes the trafr output) and adds the item to RouterOS as soon as snort detects it. If it can’t, you could still make a script that uses Libevent to monitor the log file, and call RouterOS as soon as the file reports a match… Though that second approach is a little more difficult to implement.

If you could make a log target in snort that can be sent to a specific file, then you could actually use fail2ban to monitor the log file for events and call the “block” scripts when it sees something in the log.

Isn’t fail2ban essentially an alternative to snort?
(i.e. another intrusion detection system)

Well, they’re similar but different.
Snort inspects packets on the wire for security threat signatures.
Fail2ban scans log files for target text.

So if httpd logs have 404 for /forum/admin.php?exploit=exploit2=explot3… in them, then fail2ban can see that and launch a script that adds the requester’s IP to iptables blacklists, etc.

So if snort logs things it finds, then fail2ban can watch those logs and do the blacklisting.
It’s just one way to accomplish the intended results.

fail2ban (and similar technology) must be handled with some care though - as automatic blacklisting opens a denial of service vector if you’re not careful (spoofed dns queries from your NOC’s public IP to get it banned, for instance?)

Hello,

I recently posted a questions about Snort and MikroTik:
http://forum.mikrotik.com/t/snort-ids-on-ubuntu-with-packet-sniffer-mikrotik/98046/1

And my system is almost running except the PHP/API script part, where the script searches priority 1 alerts in syslog and connects to MikroTik via SSH and puts the attackers IP address to a blacklist.

This is the script modified for my network (I am not sure if I modified it correctly):

<?php

$blocked=array();

exec('cat /var/log/syslog | grep "`date -d "-1 minute" "+%b %e %H:%M"`"',$lastMin); foreach($lastMin as $line) {

       if (strpos($line,"Priority: 1")!==FALSE || strpos($line,"portscan")!==FALSE)
       {
                       preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $line, $matches);
                       $filter=$matches[0];
                       if (!in_array($filter, $blocked))
                       {
                               $blocked[]=$filter;
                                if (strpos($filter,"192.168.80.")!==FALSE) continue; //Protected space
                               sendMikrotik('192.168.80.50', 'ips', 'snort',$filter);   // Mikrotik 1
                       }
       }

}



function sendMikrotik($mt,$user,$pass,$filter) { $connection = ssh2_connect($mt); ssh2_auth_password($connection,$user,$pass); sleep(1); $stream = ssh2_exec($connection, ':global ip '.$filter); $stream = ssh2_exec($connection, '/system script run filter'); $stream = ssh2_exec($connection, 'quit'); } ?>

Do I have a mistake in this PHP script? I am new to programming and scripting and kind of lost in this script.


Attacking PC and the one who is being attacked are in different network than 192.168.80.X. Now, when i produce a priority 1 alert, and run the php script, I get an error about “ssh2_connect();” and being something wrong with it. I made a new MikroTik user for this named “ips” with password “snort”. I have the scripts from this post made in MikroTik:
http://wiki.mikrotik.com/wiki/Mikrotik_IPS_IDS
Do they have to have a specific name? Do I have to name the first script on MikroTiks side “filter”?


boen_robot said:

Use the API protocol for the PHP part. It’s much easier, and far less error prone than SSH.
(I suggest the API client from my signature in particular)

I have no clue on how to use this protocol. Do you have any advice?

Best regards,
Filip

Ok, the script is fine, I needed to install this package:

sudo apt-get install libssh2-php

And MikroTik now succesfully put attackers into a blacklist.

Regarging my second question:

boen_robot said:
Use the API protocol for the PHP part. It’s much easier, and far less error prone than SSH.
(I suggest the API client from my signature in particular)


I have no clue on how to use this protocol. Do you have any advice?

How can I make it easier with API?

Best regards,
Filip