[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <A54C844ED592544A8AA8EF69AAB04018034882@sbswin001>
Date: Fri Sep 2 08:37:28 2005
From: mike.benjamin at clarinet.com.au (Michael L Benjamin)
Subject: SSH Bruteforce blocking script
Hi there,
Here is a simple script I've coded up that I use on 3 of my RedHat
Enterprise Linux 3 (RHEL3) servers. I decided to do this after seeing
the
amount of activity from places like China/Korea/Taiwan in relation to
SSH brute force probes. I'll throw it open here for
analysis/suggestions. It
leverages off the TCPWrappers /etc/hosts.deny /etc/hosts.allow
functionality.
Naturally I could implement SSH port-knocking or something similar or
move the SSH port, but I feel that I'm pretty well off blocking the
sorts
of hosts that would attempt this in the first place, as they seem to
mainly be compromised unix boxen and are persistent, and why should I
change on their behalf?
It may have a bugs related to counting the attacks, but otherwise it is
solid. The thing you want to keep in mind is that you should add
friendly
hosts to /etc/hosts.allow lest they get blocked by accident.
/etc/hosts.allow will override /etc/hosts.deny always, even if a host is
accidentally
added there. I have yet to code up an exclusions list technique that
would achieve a similar effect.
I don't want to debate the goodness or badness of the strategy of
blocking hosts like this in /etc/hosts.deny. It works perfectly for me,
and most
likely would for you, so no religious debates thanks. It's effective at
blocking bruteforce attacks. If a host EXCEEDS a specified number of
guesses
during the (configurable) 30 seconds it takes the script to cycle, the
host is blacklisted.
The script is simple, and it is one script, it doesn't require gobs of
documentation, CPU, or ancillary files as some methods appear to. It
uses Korn
shell simply because that's my preferred shell, it could be easily
ported to other shells as it lacks any complexity.
I have left in some of the original lines of code during development,
but they can be safely removed.
I hope it proves of some use to you.
-------------------------------8<-------------------------------8<------
-------------------------8<-------------------------------8<------------
-------------------8<-------------------------------8<
#!/bin/ksh
#
# ssh_brute_blocker
#
# 05/07/2004 15:05 - Michael L. Benjamin
#
SCRIPT_NAME=$(basename $0)
LOG_FILE="/var/log/secure"
DENY_FILE="/etc/hosts.deny"
TMP_FILE="/tmp/${SCRIPT_NAME}.$$"
INBOUND_IP=""
INLINE=""
GUESS_COUNT=0
PERMIT_GUESS=4
touch ${TMP_FILE}
while :
do
tail -10000 ${LOG_FILE} | grep "Failed password for illegal user" | awk
-F"from" {'print $2'} | awk {'print $1'} | uniq > ${TMP_FILE}
while read -r INBOUND_IP
do
GUESS_COUNT=0
# GUESS_COUNT=$(grep ${INBOUND_IP} ${LOG_FILE} | wc -l)
GUESS_COUNT=$(grep "from ${INBOUND_IP}" /var/log/secure | grep "Failed
password for" | wc -l | awk {'print $1'})
# echo IP: ${INBOUND_IP} made ${GUESS_COUNT} guesses against our server
if [ ${GUESS_COUNT} -ge ${PERMIT_GUESS} ]
then
if grep ${INBOUND_IP} ${DENY_FILE} > /dev/null
then
# echo ${INBOUND_IP} is already listed in ${DENY_FILE} ; echo
echo > /dev/null
else
# echo ${INBOUND_IP} is not listed. Adding host ${INBOUND_IP}
to ${DENY_FILE} ; echo
echo "ALL: ${INBOUND_IP}" >> ${DENY_FILE}
/usr/bin/logger -t ssh_brute_blocker -is Added SSH attacking
host ${INBOUND_IP} to ${DENY_FILE} [${GUESS_COUNT} attempts].
fi
else
# echo Ignoring host ${INBOUND_IP} less than ${PERMIT_GUESS} wrong
guesses.
echo > /dev/null
fi
done < ${TMP_FILE}
sleep 30
rm -f ${TMP_FILE}
done
exit 0
-------------------------------8<-------------------------------8<------
-------------------------8<-------------------------------8<------------
-------------------8<-------------------------------8<
I call it as follows in /etc/rc.local, and runs completely silently in
the background blocking bad hosts:
# Fire up ssh_brute_blocker security script
/usr/local/scripts/ssh_brute_blocker &
-------------------------------8<-------------------------------8<------
-------------------------8<-------------------------------8<------------
-------------------8<-------------------------------8<
I also have some webpages that I generate to show me /etc/hosts.deny,
count blocked hosts and report on blocked hosts from /var/log/messages
eg:
Aug 29 03:05:57 XXXXXXXXXXXX ssh_brute_blocker[20644]: Added SSH
attacking host 83.133.125.4 to /etc/hosts.deny [4 attempts].
Aug 29 13:18:33 XXXXXXXXXXXX ssh_brute_blocker[15590]: Added SSH
attacking host 220.82.197.48 to /etc/hosts.deny [4 attempts].
Aug 30 04:24:39 XXXXXXXXXXXX ssh_brute_blocker[20637]: Added SSH
attacking host 203.98.150.6 to /etc/hosts.deny [9 attempts].
Aug 30 19:24:08 XXXXXXXXXXXX ssh_brute_blocker[10139]: Added SSH
attacking host 62.61.140.116 to /etc/hosts.deny [8 attempts].
Sep 1 03:49:01 XXXXXXXXXXXX ssh_brute_blocker[4104]: Added SSH
attacking host 83.16.116.110 to /etc/hosts.deny [5 attempts].
Sep 2 02:48:22 XXXXXXXXXXXX ssh_brute_blocker[1633]: Added SSH
attacking host 60.248.154.162 to /etc/hosts.deny [8 attempts].
IP's have been left in place to un-protect the guilty...
Here are some typical attacks logged to /var/log/secure:
Aug 30 04:24:02 XXXXXXXXXXXX sshd[20561]: Illegal user patrick from
203.98.150.6
Aug 30 04:24:06 XXXXXXXXXXXX sshd[20563]: Illegal user patrick from
203.98.150.6
Aug 30 04:24:32 XXXXXXXXXXXX sshd[20604]: Illegal user rolo from
203.98.150.6
Aug 30 04:24:37 XXXXXXXXXXXX sshd[20606]: Illegal user iceuser from
203.98.150.6
Aug 30 05:48:43 XXXXXXXXXXXX sshd[31199]: Illegal user test from
218.69.8.78
Aug 30 19:23:15 XXXXXXXXXXXX sshd[10045]: Illegal user test from
62.61.140.116
Aug 30 19:23:23 XXXXXXXXXXXX sshd[10047]: Illegal user guest from
62.61.140.116
Aug 30 19:23:29 XXXXXXXXXXXX sshd[10049]: Illegal user admin from
62.61.140.116
Aug 30 19:23:36 XXXXXXXXXXXX sshd[10051]: Illegal user admin from
62.61.140.116
Aug 30 19:23:42 XXXXXXXXXXXX sshd[10091]: Illegal user user from
62.61.140.116
Aug 30 19:24:06 XXXXXXXXXXXX sshd[10099]: Illegal user test from
62.61.140.116
Aug 31 09:52:59 XXXXXXXXXXXX sshd[4375]: Illegal user test from
211.147.5.54
Sep 1 03:48:34 XXXXXXXXXXXX sshd[4000]: Illegal user fluffy from
83.16.116.110
Sep 1 03:48:41 XXXXXXXXXXXX sshd[4049]: Illegal user admin from
83.16.116.110
Sep 1 03:48:49 XXXXXXXXXXXX sshd[4051]: Illegal user test from
83.16.116.110
Sep 1 03:48:56 XXXXXXXXXXXX sshd[4053]: Illegal user guest from
83.16.116.110
Sep 1 03:49:04 XXXXXXXXXXXX sshd[4055]: Illegal user webmaster from
83.16.116.110
Sep 1 21:17:35 XXXXXXXXXXXX sshd[11002]: Illegal user admin from
202.129.34.101
Sep 2 02:47:27 XXXXXXXXXXXX sshd[1505]: Illegal user alin from
60.248.154.162
Sep 2 02:47:41 XXXXXXXXXXXX sshd[1507]: Illegal user alin from
60.248.154.162
Sep 2 02:47:46 XXXXXXXXXXXX sshd[1509]: Illegal user theo from
60.248.154.162
Sep 2 02:47:51 XXXXXXXXXXXX sshd[1511]: Illegal user theo from
60.248.154.162
Sep 2 02:48:00 XXXXXXXXXXXX sshd[1569]: Illegal user theo from
60.248.154.162
Sep 2 02:48:10 XXXXXXXXXXXX sshd[1571]: Illegal user damian from
60.248.154.162
Sep 2 02:48:15 XXXXXXXXXXXX sshd[1573]: Illegal user damian from
60.248.154.162
Sep 2 02:48:20 XXXXXXXXXXXX sshd[1575]: Illegal user comun from
60.248.154.162
Cheers, Mike.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.grok.org.uk/pipermail/full-disclosure/attachments/20050902/381760b6/attachment.html
Powered by blists - more mailing lists