Saturday, February 14, 2009

Parse Linux Logs to ID Hackers

If you run a GNU Linux box with sshd running then there's about 100% chance that you've been getting failed login attempts since you turned it on. If you fall a little toward the newb end of the scale, as we all have at some point, you may be interested in how to tell if someone's trying to login to your box. Let's walk through creating a command to parse up our logs. If you don't care how it works then skip to the end.

First we need to find the log file where all the failed authentication attempts are saved. I mainly use Fedora/RH so for me it's in /var/log/secure. In Debian-based distros you can usually find it in /var/log/auth.log. If you have some other distro then Google is your friend. Oh yeah, you'll need root/sudo for this. I'm going to assume you're logged in as root for the rest of this post.

[root@lord flakblas]# cat /var/log/secure
...snippet...
Feb 14 11:59:19 lord sshd[20713]: Failed password for invalid user bed from 193.231.39.65 port 49737 ssh2
Feb 14 11:59:19 lord sshd[20714]: Received disconnect from 193.231.39.65: 11: Bye Bye
Feb 14 11:59:20 lord sshd[20717]: Invalid user yahoo from 193.231.39.65
Feb 14 11:59:20 lord sshd[20718]: input_userauth_request: invalid user yahoo
Feb 14 11:59:20 lord sshd[20717]: pam_unix(sshd:auth): check pass; user unknown
Feb 14 11:59:20 lord sshd[20717]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=automation.ucv.ro
Feb 14 11:59:20 lord sshd[20717]: pam_succeed_if(sshd:auth): error retrieving information about user yahoo
...end snippet...

You'll most likely get thousands of lines of logs. Mine currently has 9091 lines. Anyway, we obviously need to parse this up to get any useful information. Enter grep.

[root@lord flakblas]# cat /var/log/secure | grep Failed
...snippet...
Feb 14 11:21:11 lord sshd[16906]: Failed password for invalid user spider from 193.231.39.65 port 42465 ssh2
Feb 14 11:21:15 lord sshd[16908]: Failed password for invalid user card from 193.231.39.65 port 42738 ssh2
Feb 14 11:21:18 lord sshd[16910]: Failed password for invalid user index from 193.231.39.65 port 43004 ssh2
Feb 14 11:21:22 lord sshd[16912]: Failed password for invalid user html from 193.231.39.65 port 43252 ssh2
Feb 14 11:21:25 lord sshd[16914]: Failed password for invalid user php from 193.231.39.65 port 43519 ssh2
Feb 14 11:21:28 lord sshd[16916]: Failed password for invalid user sendmail from 193.231.39.65 port 43765 ssh2
Feb 14 11:21:31 lord sshd[16918]: Failed password for invalid user dream from 193.231.39.65 port 44012 ssh2
Feb 14 11:21:35 lord sshd[16920]: Failed password for invalid user vis from 193.231.39.65 port 44249 ssh2
Feb 14 11:21:38 lord sshd[16922]: Failed password for invalid user geo from 193.231.39.65 port 44541 ssh2
Feb 14 11:21:41 lord sshd[16924]: Failed password for invalid user georgiana from 193.231.39.65 port 44794 ssh2
...end snippet...

And once again we still have tons of lines but if you bother to check, you'll see we've cut the list down by about 90% or so. At this point we have pretty much one line per failed attempt. So let's strip the IPs out. Regex time. The regex below filters for 0.0.0.0, 999.999.999.999 and everything in between (I know 999 is invalid.)

[root@lord flakblas]# cat /var/log/secure | grep Failed | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
...snippet...
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
193.231.39.65
...end snippet...

Now we have tons of IPs. The last thing we need to do is sort them. The sort and uniq commands will reound this out to give us some good information. Now, sort will put the entire list in a descending order and uniq -c will essentially show each IP and how many times it's tried to login. Normally if you run uniq without -c it will just print each unique IP but not the number of occurrences.

[root@lord flakblas]# cat /var/log/secure | grep Failed | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | sort | uniq -c
943 193.231.39.65
18 210.82.89.139
60 58.196.29.33
29 58.222.11.2
133 62.133.160.131
238 66.212.18.86

Now as with everything else in Linux, there are probably at least 10 better ways to do this but this is a good place to start. There's obviously more information to be had from this log file. A good command to look at is awk. Also, this is a good start to a script that runs periodically and emails a security report to the admin. Have fun.




1 comments:

PatrickMc said...

Have you tried the log parsing script posted at http://www.biterscripting.com/SS_WebLogParser.html ? It seems to do the trick for me. It is open source, you one can modify it to make it report very specific things you are looking for.

Patrick

Post a Comment