Pfsense: Difference between revisions
No edit summary |
|||
(24 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
* some | * just some things to remember... | ||
== Install Emacs == | == Install Emacs == | ||
<source> | <source> | ||
pkg_add -r | pkg_add -r emacs-nox11 | ||
</source> | </source> | ||
=== PHP Mode === | |||
<source> | <source> | ||
cat ~/.emacs | |||
; make sure the target directory is on your load-path | |||
(add-to-list 'load-path (expand-file-name "~/.emacs.d/lisp")) | |||
(require 'php-mode) | |||
</source> | </source> | ||
<source> | <source> | ||
cd ~/.emacs.d | |||
--- / | wget http://php-mode.svn.sourceforge.net/svnroot/php-mode/tags/php-mode-1.5.0/php-mode.el | ||
+++ / | </source> | ||
/ | == Snort Auto Block Email == | ||
; this has been tested on pfsense 2.1-BETA1 | |||
- | |||
* SNORT does not have any way to notify (as I know of) when it blocks/unblocks an IP automatically. Below is a PHP script that will. | |||
* It will notify email/growl -- using the default notification list from pfsense (i.e. system / advanced / notifications ) | |||
* It will log to syslog '''snort2c''' on Blocked/Unblocked events | |||
; Install | |||
* copy code below into: '''/usr/local/bin/snort_autoblock_notify.php''' | |||
* chmod +x /usr/local/bin/snort_autoblock_notify.php | |||
* Install CRON from the GUI Package Manger | |||
* setup CRON to execute '''/usr/local/bin/snort_autoblock_notify.php''' every 5 minutes as '''root''' | |||
<source lang=text> | |||
min: */5 | |||
hour: * | |||
mday: * | |||
month: * | |||
wday: * | |||
who: root | |||
command: /usr/local/bin/snort_autoblock_notify.php &> /dev/null | |||
</source> | |||
=== snort_autoblock_notify.php === | |||
<source lang=php> | |||
#!/usr/local/bin/php -f | |||
<?php | |||
require_once("functions.inc"); | |||
require_once("config.inc"); | |||
require_once("notices.inc"); | |||
/* Rob Reed | |||
* | |||
* Created: 2013-05-01 | |||
* Modified: 2013-06-18 | |||
* | |||
* Version: 0.0.6 | |||
* | |||
* Notify when snort autoblocks - run this on a cron. Every 5 minutes should be fine. | |||
* | |||
* .0.0.6 - added $exclude_country -- will not notify if country is in the list | |||
* .0.0.5 - whois function will check Parent block if reassigned | |||
*/ | |||
define(DEBUG, 0); // ghetto debugging... not really useful | |||
$exclude_country = array('CN','UA',); | |||
// body header | |||
$header = ''; | |||
$footer = __FILE__ . ' SNORT Auto Block Notifcation'; | |||
//$footer .= "\n-----------------------------------------------------------------------------------------------------------------------------------\n"; | |||
// get snort alert logs | |||
$alert_logs = GetLogs(); | |||
// date stuff | |||
$log_date = `date "+%m/%d/%y"`; | |||
$log_date = preg_replace( "/\r|\n/", "", $log_date ); | |||
$today = date("F j, Y H:i:s"); | |||
// sadly th built in pfsense notification do not allow for a custom subject.. maybe later | |||
$subject = "Snort Autoblock: $today"; | |||
// status file of current blocks | |||
$statusfile = '/tmp/blocked.status'; | |||
// read in current blocks | |||
if (file_exists($statusfile) && filesize($statusfile) > 0) { | |||
$read = fopen($statusfile, "r"); | |||
$contents = fread($read, filesize($statusfile)); | |||
fclose($read); | |||
} | |||
$is_blocked = array(); | |||
$is_blocked = explode("\n",trim($contents)); | |||
// Liste currently blocked IP's from snort - from the pf table (snort2c) | |||
$out = shell_exec("/sbin/pfctl -t snort2c -T show | sed -e 's/^[[:space:]]*//'"); | |||
//$out = shell_exec("/sbin/pfctl -t snort2c -T show |"); | |||
$ips = explode("\n",trim($out)); | |||
$message_body; | |||
// notify on unblocked | |||
foreach ($is_blocked as $ib) { | |||
if (!in_array($ib, $ips) && !empty($ib)) { | |||
$log = "* Unblocked: $ib"; | |||
$actions .= " $log\n"; | |||
// log to syslog | |||
$log_cmd = "echo \"$log\" | logger -P local0 -t snort2c"; | |||
shell_exec($log_cmd); | |||
} | |||
} | |||
// iterate through IP blocks | |||
if (is_array($ips)) { | |||
global $header; | |||
$fp = fopen($statusfile, 'w'); | |||
foreach ($ips as $ip) { | |||
$ip= ltrim(rtrim($ip)); | |||
if (preg_match("/\d+\./",$ip)) { | |||
// CheckIP - return info about IP if this is not currently blocked | |||
if (DEBUG) { print "Check Blocked IP: $ip \n"; } | |||
list ($action,$tmp_body,$country,$netname,$inc_host) = CheckIP($ip,$fp); | |||
if (in_array(strtoupper($country),$exclude_country)) { | |||
if (DEBUG) { print "Skipping notify on $ip -- $country is in the exclude_country list\n"; } | |||
continue; | |||
} | |||
if ($action) { | |||
$format = "%-26s [%-2s] %-15.15s [%s] \n"; | |||
$actions .= sprintf($format, $action, $country, $netname, $inc_host); | |||
$message_body .= $tmp_body; | |||
if (DEBUG && !$message_body) { print " no message_body for $ip \n"; } | |||
} | |||
} | |||
} | |||
fclose($fp); | |||
// Notify if we had any results | |||
if (!empty($message_body)) { | |||
$notify = $header; | |||
$notify .= "------- Actions -------\n\n"; | |||
$notify .= $actions . "\n"; | |||
$notify .= "-----------------------\n\n\n"; | |||
$notify .= "------- Deatailed Info -------\n\n"; | |||
$notify .= $message_body . "\n"; | |||
$notify .= $footer; | |||
if (DEBUG) { print $notify . "\n"; } | |||
notify_via_smtp($notify); | |||
notify_via_growl($notify); | |||
} | |||
} | |||
/************* FUNCTIONS **************************/ | |||
function CheckIP($ip,$fp) { | |||
global $is_blocked; | |||
fwrite($fp, $ip . "\n"); | |||
// debug mode - send notifies even if old | |||
if (DEBUG) { | |||
list ($action,$body,$country,$netname,$inc_host) = NotifyNewBlock($ip); | |||
return array ($action,$body,$country,$netname,$inc_host); | |||
} | |||
else { | |||
if (is_array($is_blocked)) { | |||
if (!in_array($ip,$is_blocked)) { | |||
// not in current block list - obtain IP info - whois/alert logs | |||
list ($action,$body,$country,$netname,$inc_host) = NotifyNewBlock($ip,$body); | |||
return array ($action,$body,$country,$netname,$inc_host); | |||
} | |||
} | |||
} | |||
} | |||
// generate the data for the notification - whois info, alert log info, etc.. | |||
function NotifyNewBlock($ip) { | |||
global $alert_logs,$log_date; | |||
// reverse dns for ip | |||
$host = gethostbyaddr($ip); | |||
if ($host != $ip) { $inc_host = "$host"; } | |||
// start of body | |||
//$body = "\n\n-----------------------------------------------------------------------------------------------------------------------------------\n"; | |||
$action = "* Blocked: $ip"; | |||
$body .= "\n$action [$inc_host]\n"; | |||
// iterate through snort logs to find reason for block | |||
$body .= "\n ------------------ LOGS for $ip $log_date -----------------------\n"; | |||
foreach ($alert_logs as $log) { | |||
$cmd = 'grep ' . "$ip $log | grep $log_date " . | |||
' | awk -F, \'{ print "SID="$2":"$3":"$4" PRI="$13" CLASS="$12" DESC="$5" SRC_IP="$7" SRC_PORT="$8" DST_IP="$9" DST_PORT="$10" PROTO="$6}\' ' . | |||
' | sort | uniq '; | |||
if (DEBUG) { print "\tDEBUG: " . $cmd . "\n\n";} | |||
$result .= shell_exec ($cmd); | |||
if ($result) { | |||
$body .= "LogFile: $log\n\n"; | |||
$tmp_log = explode("\n",trim($result)); | |||
if ($tmp_log[0]) { | |||
$log_body = $tmp_log[0]; // only get on for logger - last one | |||
} | |||
$body .= $result; | |||
} | |||
} | |||
$body .= "\n ---------------- END LOGS for $ip $log_date ---------------------\n"; | |||
// try to get whois info | |||
if ( list ($whois,$country,$netname) = get_whois($ip) ) { $body .= "\n" . $whois . "\n"; } | |||
// log to syslog | |||
if ($log_body) { | |||
$log_body = str_replace('"', "'", $log_body ); | |||
$log_cmd = "echo \"Blocked=$ip $log_body\" | logger -P local0 -t snort2c"; | |||
} | |||
shell_exec($log_cmd); | |||
return array ($action,$body,$country,$netname,$inc_host); | |||
} | |||
// whois function - work in progress | |||
function get_whois($ip) { | |||
$w = get_whois_from_server('whois.iana.org' , $ip); | |||
preg_match('/whois:\s+([\w\.\-]+)/' , $w , $data); | |||
$whois_server = $data[1]; | |||
//now get actual whois data | |||
$whois_data = get_whois_from_server($whois_server , $ip); | |||
// if there is now Country info -- lets get the Parent Block info (hack - works for comcast.. not sure of others) | |||
if (!preg_match("/Country/",$whois_data) && preg_match("/NET-([\d\-]+)/",$whois_data, $matches) ) { | |||
$whois_old = $whois_data; | |||
$whois_data = get_whois_from_server($whois_server , $matches[0]); | |||
} | |||
$a = explode("\n",trim($whois_data)); | |||
/* wanted info | |||
NetRange: 50.16.0.0 - 50.19.255.255 | |||
CIDR: 50.16.0.0/14 | |||
OriginAS: | |||
NetName: AMAZON-EC2-8 | |||
NetHandle: NET-50-16-0-0-1 | |||
Parent: NET-50-0-0-0-0 | |||
NetType: Direct Assignment | |||
Ref: http://whois.arin.net/rest/net/NET-50-16-0-0-1 | |||
OrgName: Amazon.com, Inc. | |||
OrgId: AMAZO-4 | |||
Address: Amazon Web Services, Elastic Compute Cloud, EC2 | |||
Address: 1200 12th Avenue South | |||
City: Seattle | |||
StateProv: WA | |||
PostalCode: 98144 | |||
inetnum: 111.72.0.0 - 111.79.255.255 | |||
netname: CHINANET-JX | |||
descr: CHINANET JIANGXI PROVINCE NETWORK | |||
descr: China Telecom | |||
descr: No.31,jingrong street | |||
descr: Beijing 100032 | |||
country: CN | |||
*/ | |||
$wanted = array('NetRange', | |||
'CIDR', | |||
'OriginAS', | |||
'NetName', | |||
'NetHandle', | |||
'Parent', | |||
'NetType', | |||
'Ref', | |||
'OrgName', | |||
'OrgId', | |||
'Address', | |||
'Address', | |||
'City', | |||
'StateProv', | |||
'PostalCode', | |||
'inetnum', | |||
'descr', | |||
'country' | |||
); | |||
$whois .= " ------------------------ WHOIS -----------------------------\n"; | |||
$whois .= " whois server: $whois_server\n\n"; | |||
$seen = array(); | |||
$netname = ''; | |||
foreach ($wanted as $w) { | |||
$p = preg_grep( "/^$w/i" , $a ); | |||
foreach ($p as $l) { | |||
$tmp = "\t" . $l . "\n"; | |||
if (!in_array($tmp,$seen)) { | |||
$whois .= $tmp; | |||
} | |||
$seen[] = $tmp; | |||
} | |||
} | |||
// get netnamt for action line | |||
$p = preg_grep( "/^NetName/i" , $a ); | |||
foreach ($p as $l) { | |||
if (preg_match('/netname:\s+(.*)/i' , $l , $m)) { $netname = $m[1]; } | |||
} | |||
// get country too | |||
$p = preg_grep( "/^country/i" , $a ); | |||
foreach ($p as $l) { | |||
if (preg_match('/country:\s+(.*)/i' , $l , $m)) { $country = $m[1]; } | |||
} | |||
$netname = ltrim(rtrim($netname)); | |||
$country = ltrim(rtrim($country)); | |||
if (empty($seen)) { | |||
foreach ($a as $l) { | |||
if (!preg_match("/^#/",$l) && preg_match("/\w/",$l)) { | |||
$whois .= $l . "\n"; | |||
} | |||
} | |||
} | |||
// show the original info if it exist.. | |||
if ($whois_old) { | |||
$o = explode("\n",trim($whois_old)); | |||
foreach ($o as $l) { | |||
if (!preg_match("/^#/",$l) && preg_match("/\w/",$l)) { | |||
$whois .= "\t" . $l . "\n"; | |||
} | |||
} | |||
} | |||
$whois .= " ---------------------- END WHOIS ---------------------------\n"; | |||
return array ($whois,$country,$netname); | |||
} | |||
// whois server loookup | |||
function get_whois_from_server($server , $ip) { | |||
$fp = fsockopen("tcp://$server", 43, $errno, $errstr); | |||
if (!$fp) { | |||
echo "ERROR: $errno - $errstr<br />\n"; | |||
} else { | |||
fwrite($fp, "$ip\n"); | |||
while (!feof($fp)) $result .= fread($fp,32000); | |||
fclose($fp); | |||
return $result; | |||
} | |||
} | |||
// lists all sensors - return array of sensor alert files | |||
function GetLogs() { | |||
$alert_logs = array(); | |||
$logs = `/usr/bin/find /var/log/snort/ -name alert`; | |||
$alert_logs = explode("\n",trim($logs)); | |||
if (!empty($alert_logs)) { | |||
return $alert_logs; | |||
} else { | |||
$notificationmsg = "failed to locate alert logs - is snort installed?\n"; | |||
print $notificationmsg; | |||
notify_via_smtp($notificationmsg); | |||
notify_via_growl($notificationmsg); | |||
exit; | |||
} | |||
} | |||
?> | |||
</source> | </source> | ||
=== Example Output === | |||
* Email on Unblocked and/or Blocked | |||
<source lang=text> | |||
Unblocked: 8.8.8.8 | |||
Unblocked: 4.4.4.2 | |||
----------------------------------------------------------------------------------------------------------------------------------- | |||
* Blocked: 61.156.238.56 | |||
------------------------ WHOIS ----------------------------- | |||
whois server: whois.apnic.net | |||
netname: UNICOM-SD | |||
address: No.21,Jin-Rong Street | |||
address: Beijing,100033 | |||
address: P.R.China | |||
address: Jinan,Shandong P.R China | |||
inetnum: 61.156.0.0 - 61.156.255.255 | |||
descr: China Unicom Shandong province network | |||
descr: China Unicom | |||
descr: CNC Group CHINA169 Shandong Province Network | |||
country: CN | |||
---------------------- END WHOIS --------------------------- | |||
------------------ LOGS for 61.156.238.56 05/01/13 ----------------------- | |||
SID=1:2001219:18 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Potential SSH Scan" SRC_IP=61.156.238.56 SRC_PORT=5920 DST_IP={hidden} DST_PORT=22 PROTO=TCP | |||
SID=1:2500088:2849 PRI=2 CLASS=Misc Attack DESC="ET COMPROMISED Known Compromised or Hostile Host Traffic TCP (45)" SRC_IP=61.156.238.56 SRC_PORT=5920 DST_IP={hidden} DST_PORT=22 PROTO=TCP | |||
---------------- END LOGS for 61.156.238.56 05/01/13 --------------------- | |||
----------------------------------------------------------------------------------------------------------------------------------- | |||
* Blocked: 111.74.238.58 | |||
------------------------ WHOIS ----------------------------- | |||
whois server: whois.apnic.net | |||
netname: CHINANET-JX | |||
address: Jiangxi telecom network operation support department | |||
address: No.2009, Beijing East Road , nanchang,jiangxi province | |||
inetnum: 111.72.0.0 - 111.79.255.255 | |||
descr: CHINANET JIANGXI PROVINCE NETWORK | |||
descr: China Telecom | |||
descr: No.31,jingrong street | |||
descr: Beijing 100032 | |||
country: CN | |||
---------------------- END WHOIS --------------------------- | |||
------------------ LOGS for 111.74.238.58 05/01/13 ----------------------- | |||
SID=1:2001219:18 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Potential SSH Scan" SRC_IP=111.74.238.58 SRC_PORT=31091 DST_IP={hidden} DST_PORT=22 PROTO=TCP | |||
---------------- END LOGS for 111.74.238.58 05/01/13 --------------------- | |||
----------------------------------------------------------------------------------------------------------------------------------- | |||
* Blocked: 173.167.52.169 [173-167-52-169-ip-static.hfc.comcastbusiness.net] | |||
------------------------ WHOIS ----------------------------- | |||
whois server: whois.arin.net | |||
Comcast Business Communications, LLC CBC-CM-4 (NET-173-160-0-0-1) 173.160.0.0 - 173.167.255.255 | |||
CONCEPT MINING INC CONCEPTMININGINC (NET-173-167-52-168-1) 173.167.52.168 - 173.167.52.175 | |||
Comcast Business Communications, LLC CBC-RICHMOND-17 (NET-173-167-52-0-1) 173.167.52.0 - 173.167.55.255 | |||
---------------------- END WHOIS --------------------------- | |||
------------------ LOGS for 173.167.52.169 05/01/13 ----------------------- | |||
SID=1:2008578:6 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious Scan" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP | |||
SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP | |||
SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP | |||
SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP | |||
SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP | |||
SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP | |||
---------------- END LOGS for 173.167.52.169 05/01/13 --------------------- | |||
----------------------------------------------------------------------------------------------------------------------------------- | |||
</source> | |||
[[Category:How-to]] | |||
[[Category:Networking]] |
Latest revision as of 18:43, 2 July 2015
- just some things to remember...
Install Emacs[edit]
<source> pkg_add -r emacs-nox11 </source>
PHP Mode[edit]
<source> cat ~/.emacs
- make sure the target directory is on your load-path
(add-to-list 'load-path (expand-file-name "~/.emacs.d/lisp")) (require 'php-mode) </source> <source> cd ~/.emacs.d wget http://php-mode.svn.sourceforge.net/svnroot/php-mode/tags/php-mode-1.5.0/php-mode.el </source>
Snort Auto Block Email[edit]
- this has been tested on pfsense 2.1-BETA1
- SNORT does not have any way to notify (as I know of) when it blocks/unblocks an IP automatically. Below is a PHP script that will.
- It will notify email/growl -- using the default notification list from pfsense (i.e. system / advanced / notifications )
- It will log to syslog snort2c on Blocked/Unblocked events
- Install
- copy code below into: /usr/local/bin/snort_autoblock_notify.php
- chmod +x /usr/local/bin/snort_autoblock_notify.php
- Install CRON from the GUI Package Manger
- setup CRON to execute /usr/local/bin/snort_autoblock_notify.php every 5 minutes as root
<source lang=text>
min: */5 hour: * mday: * month: * wday: * who: root
command: /usr/local/bin/snort_autoblock_notify.php &> /dev/null </source>
snort_autoblock_notify.php[edit]
<source lang=php>
- !/usr/local/bin/php -f
<?php
require_once("functions.inc"); require_once("config.inc"); require_once("notices.inc");
/* Rob Reed
* * Created: 2013-05-01 * Modified: 2013-06-18 * * Version: 0.0.6 * * Notify when snort autoblocks - run this on a cron. Every 5 minutes should be fine. * * .0.0.6 - added $exclude_country -- will not notify if country is in the list * .0.0.5 - whois function will check Parent block if reassigned */
define(DEBUG, 0); // ghetto debugging... not really useful
$exclude_country = array('CN','UA',);
// body header $header = ; $footer = __FILE__ . ' SNORT Auto Block Notifcation'; //$footer .= "\n-----------------------------------------------------------------------------------------------------------------------------------\n";
// get snort alert logs $alert_logs = GetLogs();
// date stuff $log_date = `date "+%m/%d/%y"`; $log_date = preg_replace( "/\r|\n/", "", $log_date ); $today = date("F j, Y H:i:s");
// sadly th built in pfsense notification do not allow for a custom subject.. maybe later $subject = "Snort Autoblock: $today";
// status file of current blocks $statusfile = '/tmp/blocked.status';
// read in current blocks if (file_exists($statusfile) && filesize($statusfile) > 0) {
$read = fopen($statusfile, "r"); $contents = fread($read, filesize($statusfile)); fclose($read);
} $is_blocked = array(); $is_blocked = explode("\n",trim($contents));
// Liste currently blocked IP's from snort - from the pf table (snort2c) $out = shell_exec("/sbin/pfctl -t snort2c -T show | sed -e 's/^space:*//'"); //$out = shell_exec("/sbin/pfctl -t snort2c -T show |"); $ips = explode("\n",trim($out));
$message_body;
// notify on unblocked foreach ($is_blocked as $ib) {
if (!in_array($ib, $ips) && !empty($ib)) { $log = "* Unblocked: $ib"; $actions .= " $log\n"; // log to syslog $log_cmd = "echo \"$log\" | logger -P local0 -t snort2c"; shell_exec($log_cmd); }
}
// iterate through IP blocks if (is_array($ips)) {
global $header; $fp = fopen($statusfile, 'w'); foreach ($ips as $ip) { $ip= ltrim(rtrim($ip)); if (preg_match("/\d+\./",$ip)) { // CheckIP - return info about IP if this is not currently blocked if (DEBUG) { print "Check Blocked IP: $ip \n"; } list ($action,$tmp_body,$country,$netname,$inc_host) = CheckIP($ip,$fp); if (in_array(strtoupper($country),$exclude_country)) { if (DEBUG) { print "Skipping notify on $ip -- $country is in the exclude_country list\n"; } continue; } if ($action) { $format = "%-26s [%-2s] %-15.15s [%s] \n"; $actions .= sprintf($format, $action, $country, $netname, $inc_host); $message_body .= $tmp_body; if (DEBUG && !$message_body) { print " no message_body for $ip \n"; } } } } fclose($fp); // Notify if we had any results if (!empty($message_body)) { $notify = $header; $notify .= "------- Actions -------\n\n"; $notify .= $actions . "\n"; $notify .= "-----------------------\n\n\n"; $notify .= "------- Deatailed Info -------\n\n"; $notify .= $message_body . "\n"; $notify .= $footer; if (DEBUG) { print $notify . "\n"; } notify_via_smtp($notify); notify_via_growl($notify); }
}
/************* FUNCTIONS **************************/
function CheckIP($ip,$fp) {
global $is_blocked; fwrite($fp, $ip . "\n"); // debug mode - send notifies even if old if (DEBUG) { list ($action,$body,$country,$netname,$inc_host) = NotifyNewBlock($ip); return array ($action,$body,$country,$netname,$inc_host); } else { if (is_array($is_blocked)) { if (!in_array($ip,$is_blocked)) { // not in current block list - obtain IP info - whois/alert logs list ($action,$body,$country,$netname,$inc_host) = NotifyNewBlock($ip,$body); return array ($action,$body,$country,$netname,$inc_host); } } }
}
// generate the data for the notification - whois info, alert log info, etc..
function NotifyNewBlock($ip) {
global $alert_logs,$log_date; // reverse dns for ip $host = gethostbyaddr($ip); if ($host != $ip) { $inc_host = "$host"; } // start of body //$body = "\n\n-----------------------------------------------------------------------------------------------------------------------------------\n"; $action = "* Blocked: $ip"; $body .= "\n$action [$inc_host]\n"; // iterate through snort logs to find reason for block $body .= "\n ------------------ LOGS for $ip $log_date -----------------------\n"; foreach ($alert_logs as $log) { $cmd = 'grep ' . "$ip $log | grep $log_date " . ' | awk -F, \'{ print "SID="$2":"$3":"$4" PRI="$13" CLASS="$12" DESC="$5" SRC_IP="$7" SRC_PORT="$8" DST_IP="$9" DST_PORT="$10" PROTO="$6}\' ' . ' | sort | uniq '; if (DEBUG) { print "\tDEBUG: " . $cmd . "\n\n";} $result .= shell_exec ($cmd); if ($result) { $body .= "LogFile: $log\n\n"; $tmp_log = explode("\n",trim($result)); if ($tmp_log[0]) { $log_body = $tmp_log[0]; // only get on for logger - last one } $body .= $result; } } $body .= "\n ---------------- END LOGS for $ip $log_date ---------------------\n"; // try to get whois info if ( list ($whois,$country,$netname) = get_whois($ip) ) { $body .= "\n" . $whois . "\n"; } // log to syslog if ($log_body) { $log_body = str_replace('"', "'", $log_body ); $log_cmd = "echo \"Blocked=$ip $log_body\" | logger -P local0 -t snort2c"; } shell_exec($log_cmd); return array ($action,$body,$country,$netname,$inc_host);
}
// whois function - work in progress
function get_whois($ip) {
$w = get_whois_from_server('whois.iana.org' , $ip); preg_match('/whois:\s+([\w\.\-]+)/' , $w , $data); $whois_server = $data[1]; //now get actual whois data $whois_data = get_whois_from_server($whois_server , $ip);
// if there is now Country info -- lets get the Parent Block info (hack - works for comcast.. not sure of others) if (!preg_match("/Country/",$whois_data) && preg_match("/NET-([\d\-]+)/",$whois_data, $matches) ) { $whois_old = $whois_data; $whois_data = get_whois_from_server($whois_server , $matches[0]); }
$a = explode("\n",trim($whois_data)); /* wanted info NetRange: 50.16.0.0 - 50.19.255.255 CIDR: 50.16.0.0/14 OriginAS: NetName: AMAZON-EC2-8 NetHandle: NET-50-16-0-0-1 Parent: NET-50-0-0-0-0 NetType: Direct Assignment Ref: http://whois.arin.net/rest/net/NET-50-16-0-0-1 OrgName: Amazon.com, Inc. OrgId: AMAZO-4 Address: Amazon Web Services, Elastic Compute Cloud, EC2 Address: 1200 12th Avenue South City: Seattle StateProv: WA PostalCode: 98144 inetnum: 111.72.0.0 - 111.79.255.255 netname: CHINANET-JX descr: CHINANET JIANGXI PROVINCE NETWORK descr: China Telecom descr: No.31,jingrong street descr: Beijing 100032 country: CN */ $wanted = array('NetRange', 'CIDR', 'OriginAS', 'NetName', 'NetHandle', 'Parent', 'NetType', 'Ref', 'OrgName', 'OrgId', 'Address', 'Address', 'City', 'StateProv', 'PostalCode', 'inetnum', 'descr', 'country' ); $whois .= " ------------------------ WHOIS -----------------------------\n"; $whois .= " whois server: $whois_server\n\n"; $seen = array(); $netname = ; foreach ($wanted as $w) { $p = preg_grep( "/^$w/i" , $a ); foreach ($p as $l) { $tmp = "\t" . $l . "\n"; if (!in_array($tmp,$seen)) { $whois .= $tmp; } $seen[] = $tmp; } } // get netnamt for action line $p = preg_grep( "/^NetName/i" , $a ); foreach ($p as $l) { if (preg_match('/netname:\s+(.*)/i' , $l , $m)) { $netname = $m[1]; } } // get country too $p = preg_grep( "/^country/i" , $a ); foreach ($p as $l) { if (preg_match('/country:\s+(.*)/i' , $l , $m)) { $country = $m[1]; } } $netname = ltrim(rtrim($netname)); $country = ltrim(rtrim($country)); if (empty($seen)) { foreach ($a as $l) { if (!preg_match("/^#/",$l) && preg_match("/\w/",$l)) { $whois .= $l . "\n"; } } }
// show the original info if it exist.. if ($whois_old) { $o = explode("\n",trim($whois_old)); foreach ($o as $l) { if (!preg_match("/^#/",$l) && preg_match("/\w/",$l)) { $whois .= "\t" . $l . "\n"; } } }
$whois .= " ---------------------- END WHOIS ---------------------------\n"; return array ($whois,$country,$netname);
}
// whois server loookup
function get_whois_from_server($server , $ip) {
$fp = fsockopen("tcp://$server", 43, $errno, $errstr); if (!$fp) { echo "ERROR: $errno - $errstr
\n"; } else { fwrite($fp, "$ip\n"); while (!feof($fp)) $result .= fread($fp,32000); fclose($fp); return $result; }
}
// lists all sensors - return array of sensor alert files function GetLogs() {
$alert_logs = array(); $logs = `/usr/bin/find /var/log/snort/ -name alert`; $alert_logs = explode("\n",trim($logs)); if (!empty($alert_logs)) { return $alert_logs; } else { $notificationmsg = "failed to locate alert logs - is snort installed?\n"; print $notificationmsg; notify_via_smtp($notificationmsg); notify_via_growl($notificationmsg); exit; }
}
?>
</source>
Example Output[edit]
- Email on Unblocked and/or Blocked
<source lang=text>
Unblocked: 8.8.8.8 Unblocked: 4.4.4.2
- Blocked: 61.156.238.56
------------------------ WHOIS ----------------------------- whois server: whois.apnic.net
netname: UNICOM-SD address: No.21,Jin-Rong Street address: Beijing,100033 address: P.R.China address: Jinan,Shandong P.R China inetnum: 61.156.0.0 - 61.156.255.255 descr: China Unicom Shandong province network descr: China Unicom descr: CNC Group CHINA169 Shandong Province Network country: CN
---------------------- END WHOIS ---------------------------
------------------ LOGS for 61.156.238.56 05/01/13 -----------------------
SID=1:2001219:18 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Potential SSH Scan" SRC_IP=61.156.238.56 SRC_PORT=5920 DST_IP={hidden} DST_PORT=22 PROTO=TCP SID=1:2500088:2849 PRI=2 CLASS=Misc Attack DESC="ET COMPROMISED Known Compromised or Hostile Host Traffic TCP (45)" SRC_IP=61.156.238.56 SRC_PORT=5920 DST_IP={hidden} DST_PORT=22 PROTO=TCP
---------------- END LOGS for 61.156.238.56 05/01/13 ---------------------
- Blocked: 111.74.238.58
------------------------ WHOIS ----------------------------- whois server: whois.apnic.net
netname: CHINANET-JX address: Jiangxi telecom network operation support department address: No.2009, Beijing East Road , nanchang,jiangxi province inetnum: 111.72.0.0 - 111.79.255.255 descr: CHINANET JIANGXI PROVINCE NETWORK descr: China Telecom descr: No.31,jingrong street descr: Beijing 100032 country: CN
---------------------- END WHOIS ---------------------------
------------------ LOGS for 111.74.238.58 05/01/13 -----------------------
SID=1:2001219:18 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Potential SSH Scan" SRC_IP=111.74.238.58 SRC_PORT=31091 DST_IP={hidden} DST_PORT=22 PROTO=TCP
---------------- END LOGS for 111.74.238.58 05/01/13 ---------------------
- Blocked: 173.167.52.169 [173-167-52-169-ip-static.hfc.comcastbusiness.net]
------------------------ WHOIS ----------------------------- whois server: whois.arin.net
Comcast Business Communications, LLC CBC-CM-4 (NET-173-160-0-0-1) 173.160.0.0 - 173.167.255.255 CONCEPT MINING INC CONCEPTMININGINC (NET-173-167-52-168-1) 173.167.52.168 - 173.167.52.175 Comcast Business Communications, LLC CBC-RICHMOND-17 (NET-173-167-52-0-1) 173.167.52.0 - 173.167.55.255
---------------------- END WHOIS ---------------------------
------------------ LOGS for 173.167.52.169 05/01/13 -----------------------
SID=1:2008578:6 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious Scan" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP SID=1:2011716:4 PRI=2 CLASS=Attempted Information Leak DESC="ET SCAN Sipvicious User-Agent Detected (friendly-scanner)" SRC_IP=173.167.52.169 SRC_PORT=5067 DST_IP={hidden} DST_PORT=5060 PROTO=UDP
---------------- END LOGS for 173.167.52.169 05/01/13 ---------------------
</source>