Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 23rd, 2006, 5:54 PM   #1
Pizentios
Programming Guru
 
Pizentios's Avatar
 
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 Pizentios is on a distinguished road
Send a message via ICQ to Pizentios Send a message via MSN to Pizentios
IP blocker

Hey,

for the past few months, i have noticed a increase of invalid login attempts on my webserver (that has ssh running on it). Bascially these are attempts at brute forcing a username and password set....which as many of you know (or at least the ones that hang around on irc or talk to me on MSN) pisses me off. They have never gotten into ssh, but why leave that chance open?

I got talking with IR (Infinite Recursion) about this problem...i soon found out that he also had a problem with these things. Then i found out that he had a script to add these ip's to his host.deny file (sorry windows users, this is a linux/unix only thing). Long story short, i decided to code my own script.

Here it is:

#!/usr/bin/env perl
use Net::SMTP::TLS;
use Switch;
use POSIX;
use Pg;
#use strict;

#Search Patterns:
my @patterns = ("Did not receive identification string","Invalid user","POSSIBLE BREAKIN ATTEMPT");
#db stuff:
#$con_val[0] == the database name.
#$con_val[1] == the host.
#$con_val[2] == the port.
#$con_val[3] == the username for the database.
#$con_val[4] == the password for the database.
my @conn_val = ("sentinel", "localhost", "5432", "sentinel", "fuck_china");

my $ip;
my $date;
my @months;
$months["Jan"] = 0;
$months["Feb"] = 1;
$months["Mar"] = 2;
$months["Apr"] = 3;
$months["May"] = 4;
$months["Jun"] = 5;
$months["Jul"] = 6;
$months["Aug"] = 7;
$months["Sep"] = 8;
$months["Oct"] = 9;
$months["Nov"] = 10;
$months["Dec"] = 11;
my $time = localtime time;
$time =~ m/\b[0-9][0-9][0-9][0-9]\b/;
my $year = $&;
$year -= 2000;
$year += 100;


#connect up to the db.
$conn = Pg::connectdb("host=" . $conn_val[1] . " port=" . $conn_val[2] . " dbname=" . $conn_val[0] . " user=" . $conn_val[3] . " password=" . $conn_val[4]);
#check connection.
if ($conn->status != PGRES_CONNECTION_OK)
{
		die "Failed to connect: ".-$conn->errorMessage."\n";
}
open (TAIL, "tail -f auth.log 2>&1 |") or die "can't open pipe:$!"; 
while (<TAIL>)
{
	switch ($_)
	{
		case m/$patterns[2]/ { next }
		case m/$patterns[0]/
		{
			#log ip, then block and sms details to admin.
			#grab ip addy
			$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
			$ip = $&;
			#grab date
			$_ =~ m/\b[A-z]{3} [0-9]{2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}\b/;
			$date = $&;
			#now, chunk date out into, $month, day, hours, minutes, seconds. 
			my ($month, $day, $time) = split(/ /, $date);
			my ($hour, $min, $sec) = split(/:/, $time);
			my $full_date = mktime($sec, $min, $hour, $day, $months[$month], $year);
			my $sql = "INSERT INTO log (ip, date) VALUES ('$ip', $full_date)";
			my $result = $conn->exec($sql);
			open (DENY, ">>", "host.deny") or die "Can't open host.deny!";
			print DENY $ip . "\n";
			close DENY;
		}
		case m/$patterns[1]/
		{
			#get the fucker's ip address.
			$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
			$ip = $&;			
			open (CHECK, "tail -n6 auth.log 2>&1 |") or die "can't open pipe:$!";
			my $count = 0;
			while (<CHECK>)
			{
		 	$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
				$log_ip = $&;
				if ($log_ip == $ip)
				{
					$count += 1;
				}
			}
			close CHECK;
			if ($count >= 3)
			{
				#we have an attempt.
				#log and ban.
		 	$_ =~ m/\b[A-z]{3} [0-9]{2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}\b/;
				$date = $&;
				my ($month, $day, $time) = split(/ /, $date);
				my ($hour, $min, $sec) = split(/:/, $time);
		 	my $full_date = mktime($sec, $min, $hour, $day, $months[$month], $year);
		 	my $sql = "INSERT INTO log (ip, date) VALUES ('$ip', $full_date)";
				$conn->exec($sql);
				#append to host.deny
		 	open (DENY, ">>", "host.deny") or die "Can't open host.deny!";
				print DENY $ip . "\n";
				close DENY;
			}
		}
	}
} #end of while loop.

The code scans your auth.log file, for attempts, adds em to hosts.deny and logs them to a db for furture use. I am now working on making a php script to output a graph based on ip and country code. I have a feeling most attempts will come from china, or atleast a ip that's spoofed to look like china.

I plan on expanding this script's features in the future, so any suggestions would be great. One of the ideas for future features that IR and i were talking about is: adding the ip to a .htaccess file to block the ip from accessing web resources. More programs/log files will be supported in the future.

It should be noted, you'll have to change some of the stuff in the script for it to work on your box (ie: location of auth.log and hosts.deny). Also, i designed this script so that you can (and should) start it from a script at startup.
__________________
Profanity is the one language that all programmers understand.

Check out my Blog <---updated Nov 30 2007!
Pizentios is offline   Reply With Quote
Old May 23rd, 2006, 5:59 PM   #2
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,467
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
looks good man, let me know the results
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old May 23rd, 2006, 6:29 PM   #3
zorin
Hobbyist Programmer
 
Join Date: Apr 2005
Posts: 218
Rep Power: 4 zorin is on a distinguished road
Nice work Piz, I thought I was the only one with this problem. To be honest, within the first 10mins of starting SSH the log files are filled with invalid passwords too. Im no unix or perl guru so ill have a look at this later.
zorin is offline   Reply With Quote
Old May 23rd, 2006, 6:29 PM   #4
Ooble
I eat cake for breakfast.
 
Ooble's Avatar
 
Join Date: Jul 2004
Location: In my box.
Posts: 4,434
Rep Power: 9 Ooble is on a distinguished road
Bad moderator!

* points to the Finished Projects section *

:p
__________________
Me :: You :: Them
Ooble is offline   Reply With Quote
Old May 23rd, 2006, 11:29 PM   #5
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,467
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
Technically, it may not be "finished" yet
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old May 23rd, 2006, 11:35 PM   #6
mrynit
Hobbyist Programmer
 
mrynit's Avatar
 
Join Date: Mar 2006
Location: WA, USA
Posts: 340
Rep Power: 3 mrynit is on a distinguished road
Send a message via AIM to mrynit Send a message via MSN to mrynit Send a message via Yahoo to mrynit Send a message via Skype™ to mrynit
WOW, very good. port??
__________________
i dont know much about programming but i try to help
mrynit is offline   Reply With Quote
Old May 24th, 2006, 9:09 AM   #7
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,467
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
Port to what OS?
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old May 24th, 2006, 9:58 AM   #8
Pizentios
Programming Guru
 
Pizentios's Avatar
 
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 Pizentios is on a distinguished road
Send a message via ICQ to Pizentios Send a message via MSN to Pizentios
Quote:
Originally Posted by mrynit
WOW, very good. port??
no, it's not a port. This code is all me man. IR helped with some of the ideas and regular expressions.

@Ooble
yeah, i know i could have put it into the finished projects, but as IR said, this thing isn't quite finished yet.
__________________
Profanity is the one language that all programmers understand.

Check out my Blog <---updated Nov 30 2007!
Pizentios is offline   Reply With Quote
Old May 24th, 2006, 11:39 AM   #9
Pizentios
Programming Guru
 
Pizentios's Avatar
 
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 Pizentios is on a distinguished road
Send a message via ICQ to Pizentios Send a message via MSN to Pizentios
hey,

just made a rc script for gentoo to run the perl script:

#!/sbin/runscript
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

depend() {
        before sshd
}

start() {
        start-stop-daemon --start --background --pidfile /var/run/monitor.pid --make-pidfile --exec /usr/scripts/monitor.pl
        eend $?
}

stop() {
        ebegin "Stopping IP Blocker"
        start-stop-daemon --stop --pidfile /var/run/monitor.pid --name /usr/scripts/monitor.pl
        eend $?
}

It should be noted, that this rc script will probably only work on gentoo systems. i still haven't got the stop feature working corectly, but it does start the script at boot once you've added the rc script to a run level (you should add it to the default run level).
__________________
Profanity is the one language that all programmers understand.

Check out my Blog <---updated Nov 30 2007!
Pizentios is offline   Reply With Quote
Old May 24th, 2006, 3:07 PM   #10
Pizentios
Programming Guru
 
Pizentios's Avatar
 
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 Pizentios is on a distinguished road
Send a message via ICQ to Pizentios Send a message via MSN to Pizentios
Hey,

couple fixes. First off, thanks to IR, the stop fuction of the rc script now works. Here's the changes.
stop() {
        ebegin "Stopping IP Blocker"
        kill $(cat /var/run/monitor.pid)
        eend $? "Failed to stop IP Blocker"
}

also, i noticed that there is a chance that the ip could be added to hosts.deny more than once. So i added a if statment to grep hosts.deny for the ip. Here's the new version of the ip blocker.

#!/usr/bin/env perl
use Net::SMTP::TLS;
use Switch;
use POSIX;
use Pg;
#use strict;

#Search Patterns:
my @patterns = ("Did not receive identification string","Invalid user","POSSIBLE BREAKIN ATTEMPT");
#db stuff:
#$con_val[0] == the database name.
#$con_val[1] == the host.
#$con_val[2] == the port.
#$con_val[3] == the username for the database.
#$con_val[4] == the password for the database.
my @conn_val = ("sentinel", "localhost", "5432", "sentinel", "fuck_china*");

my $ip;
my $date;
my @months;
$months["Jan"] = 0;
$months["Feb"] = 1;
$months["Mar"] = 2;
$months["Apr"] = 3;
$months["May"] = 4;
$months["Jun"] = 5;
$months["Jul"] = 6;
$months["Aug"] = 7;
$months["Sep"] = 8;
$months["Oct"] = 9;
$months["Nov"] = 10;
$months["Dec"] = 11;
my $time = localtime time;
$time =~ m/\b[0-9][0-9][0-9][0-9]\b/;
my $year = $&;
$year -= 2000;
$year += 100;


#connect up to the db.
$conn = Pg::connectdb("host=" . $conn_val[1] . " port=" . $conn_val[2] . " dbname=" . $conn_val[0] . " user=" . $conn_val[3] . " password=" . $conn_val[4]);
#check connection.
if ($conn->status != PGRES_CONNECTION_OK)
{
        die "Failed to connect: ".-$conn->errorMessage."\n";
}
open (TAIL, "tail -f /var/log/auth.log 2>&1 |") or die "can't open pipe:$!"; 
while (<TAIL>)
{
	switch ($_)
	{
		case m/$patterns[2]/ { next }
		case m/$patterns[0]/
		{
			#log ip, then block and sms details to admin.
			#grab ip addy
			$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
			$ip = $&;
			#grab date
			$_ =~ m/\b[A-z]{3} [0-9]{2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}\b/;
			$date = $&;
			#now, chunk date out into, $month, day, hours, minutes, seconds. 
			my ($month, $day, $time) = split(/ /, $date);
			my ($hour, $min, $sec) = split(/:/, $time);
			my $full_date = mktime($sec, $min, $hour, $day, $months[$month], $year);
			my $sql = "INSERT INTO log (ip, date) VALUES ('$ip', $full_date)";
			my $result = $conn->exec($sql);
			if (system("grep $ip /etc/hosts.deny") != 0)
			{
				open (DENY, ">>", "/etc/hosts.deny") or die "Can't open host.deny!";
				print DENY "ALL: " . $ip . "\n";
				close DENY;
			}
		}
		case m/$patterns[1]/
		{
			#get the fucker's ip address.
			$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
			$ip = $&;			
			open (CHECK, "tail -n6 /var/log/auth.log 2>&1 |") or die "can't open pipe:$!";
			my $count = 0;
			while (<CHECK>)
			{
				$_ =~ m/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
				$log_ip = $&;
				if ($log_ip == $ip)
				{
					$count += 1;
				}
			}
			close CHECK;
			if ($count >= 3)
			{
				#we have an attempt.
				#log and ban.
				$_ =~ m/\b[A-z]{3} [0-9]{2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}\b/;
				$date = $&;
				my ($month, $day, $time) = split(/ /, $date);
				my ($hour, $min, $sec) = split(/:/, $time);
				my $full_date = mktime($sec, $min, $hour, $day, $months[$month], $year);
				my $sql = "INSERT INTO log (ip, date) VALUES ('$ip', $full_date)";
				$conn->exec($sql);
				#append to host.deny
				if (system("grep $ip /etc/hosts.deny") != 0)
				{
					open (DENY, ">>", "/etc/hosts.deny") or die "Can't open host.deny!";
					print DENY "ALL: " . $ip . "\n";
					close DENY;
				}
			}
		}
	}
} #end of while loop.
__________________
Profanity is the one language that all programmers understand.

Check out my Blog <---updated Nov 30 2007!

Last edited by Pizentios; May 24th, 2006 at 3:57 PM.
Pizentios is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 9:29 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC