#!/bin/bash #Checks for hackers trying to use different usernames and passwords "usually administrator", but they are getting smarter. #There are many different versions of this avaliable, but this worked great for my needs and might work for you. #Counts lines in the parsing file ftpcount=`cat /var/log/proftpd/proftpd.log |wc -l` #minimized the amount of variables declared. Just the 2 arrays and a flag declare -a badusers declare -a badusersip flagi=0 flagb=0 #Start Loop A for (( e = 0 ; e <= $ftpcount ; e++ )) do #This is admittedly not the best way, but search each line to see if it has no such user found. If so grab the username and track it. baduser=`head -n $e /var/log/proftpd/proftpd.log | tail -n 1 | grep "no such user found" | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d " " -f9 | cut -d ":" -f1` #if it has no such user found then also grab the IP to track. badip=`head -n $e /var/log/proftpd/proftpd.log | tail -n 1 | grep "no such user found" | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d "[" -f3 | cut -d "]" -f1` #If there was a bad username found then go further if [ ! -z "$baduser" ]; then #If there was a bad username found then what was that IP if [ ! -z "$badip" ]; then #If both were not blank meaning it found a bad attempt then search for how many times they tried. badusercount=`cat /var/log/proftpd/proftpd.log | grep $badip | grep "no such user found" | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d "[" -f3 | cut -d "]" -f1 | wc -l` echo $badusercount badusercount echo $baduser baduser echo $badip badip #If they tried more then 4 times continue if [ $badusercount -gt 4 ]; then #This is to help track if they tried sporatically or if multiple ppl were trying to hack at same time. #Loop through the bad IP array for (( d = 0 ; d <= ${#badusersip[*]} ; d++ )) do #If the ip is the same as the bad ip then set flagi if [ $badip = "${badusersip[$d]}" ]; then flagi=1 fi done #End that bad IP array loop #If the flag was not set then start the ban process. if [ ! $flagi = 1 ]; then #echo $badip #Debug #Make sure the IP is not blank which it shouldn't be at this point. Probably overkill if [ ! -z $badip ]; then #make sure they are not already banned x1=`/sbin/iptables -L -n| grep $badip | wc -m` #if it wasn't found as being already banned then ban them if [ $x1 -lt 2 ]; then /sbin/iptables -I INPUT -s $badip -j DROP #make baduserct a temp holder for amount of users banned this run. badusersct=${#badusersip[*]} #increment that temp holder ((badusersct++)) #At the new location in the array set the values to the newly banned user and ip badusersip["$badusersct"]=$badip badusers["$badusersct"]=$baduser #End all the ifs and clear all the flags for the next run #Complexity is an issue as it runs this entire process for each line in the file, which can get long fi fi flagi=0 fi flagi=0 fi flagi=0 fi fi done #END Loop A #Start Loop B for (( h = 0 ; h <= $ftpcount ; h++ )) do #This is admittedly not the best way, but search each line to see if it has no such user found. If so grab the username and track it. baduser=`head -n $h /var/log/proftpd/proftpd.log | tail -n 1 | grep "Login failed" | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d " " -f9 | cut -d ":" -f1` #if it has no such user found then also grab the IP to track. badip=`head -n $h /var/log/proftpd/proftpd.log | tail -n 1 | grep "Login failed" | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d "[" -f3 | cut -d "]" -f1` #If there was a bad username found then go further if [ ! -z "$baduser" ]; then #If there was a bad username found then what was that IP if [ ! -z "$badip" ]; then #If both were not blank meaning it found a bad attempt then search for how many times they tried. badusercount=`cat /var/log/proftpd/proftpd.log | grep $badip | grep "Login failed" | egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d "[" -f3 | cut -d "]" -f1 | wc -l` echo $badusercount badusercount echo $baduser baduser echo $badip badip #If they tried more than 5 bad passwords then continue if [ $badusercount -gt 5 ]; then #This is to help track if they tried sporatically or if multiple ppl were trying to hack at same time. #Loop through the bad IP array for (( d = 0 ; d <= ${#badusersip[*]} ; d++ )) do #If the ip is the same as the bad ip then set flagb if [ $badip = "${badusersip[$d]}" ]; then flagb=1 fi done #End that bad IP array loop #If the flag was not set then start the ban process. if [ ! $flagb = 1 ]; then echo $badip #Debug #Make sure the IP is not blank which it shouldn't be at this point. Probably overkill if [ ! -z $badip ]; then #make sure they are not already banned x1=`/sbin/iptables -L -n| grep $badip | wc -m` #if it wasn't found as being already banned then ban them if [ $x1 -lt 2 ]; then /sbin/iptables -I INPUT -s $badip -j DROP #make baduserct a temp holder for amount of users banned this run. badusersct=${#badusersip[*]} #increment that temp holder ((badusersct++)) #At the new location in the array set the values to the newly banned user and ip badusersip["$badusersct"]=$badip badusers["$badusersct"]=$baduser #End all the ifs and clear all the flags for the next run #Complexity is an issue as it runs this entire process for each line in the file, which can get long fi fi flagb=0 fi flagb=0 fi flagb=0 fi fi done #END Loop B #reset the count of users banned and initalize the new count. baduserct=0 badusersct="${#badusersip[*]}" badusernamect="${#badusers[*]}" #Ignore is debug to see how many bad users and ips echo $badusernamect badusernamect echo $badusersct badcount #If the count is not zero then start the process of sending me a message. if [ $badusersct -gt 0 ]; then echo 'Security Alert: There was an attempt to brute force the ftp server from the following address(es)' >> /home/ftpuser/mail.txt #making the email pretty or at least not ugly echo >> /home/ftpuser/mail.txt echo IP : USERNAME >> /home/ftpuser/mail.txt echo >> /home/ftpuser/mail.txt #loop through the users and ips you banned and tell me the ip and username they attempted. Will only show the first one they scored 3+ bad on. for (( i = 1 ; i <= "${#badusersip[*]}" ; i++ )) do echo badusername ${badusers[$i]} echo baduserip ${badusersip[$i]} echo ${badusersip[$i]} : ${badusers[$i]} >> /home/ftpuser/mail.txt done echo " " >> /home/ftpuser/mail.txt echo " " >> /home/ftpuser/mail.txt echo 'Here is a list of all the addresses I currently have blocked' >> /home/ftpuser/mail.txt #dumps what the current iptables list is /sbin/iptables -L -n >> /home/ftpuser/mail.txt mail -s "Security Alert" email@address.com < /home/ftpuser/mail.txt fi echo > /home/ftpuser/mail.txt unset badusersip unset badusers