Blocking the scanner or worm protects our network from further attack. We'd also like to be good network citizens and make the scanner's life hard, to take some of the load off other admins who might be the attacker's next target.
The tool for doing this is called LaBrea. Basically it plays tricks with the TCP flow control settings to tell the scanning computer “Yes, I'm here, but I can only accept one byte per packet,” and then doesn't acknowlege packets so the sender sits in a timeout-and-retransmit loop for long periods of time. Ideally the scanner will hit the tarpit and become stuck for hours on end, trying vainly to see whether we're running a vulnerable version of IIS and leaving some other unprotected network alone.
This response is effective where the scanner is checking for version banners or other indications of a specific vulnerability, or is a worm trying to propagate itself. On scans that are only looking for running servers (e.g. “half-open” or “stealth” scans) this won't slow the scanner, but has the benefit of polluting the scanner's database of “hits” - most of the hosts on the boundary network will be reported as running the service that the scanner is looking for. Even if the host does not really exist.
LaBrea is designed to be installed as the only service running on a dedicated “tarpit host” that is sitting on the boundary network. However, the fact that we are using transparent proxy and Portsentry to detect and block scans of the boundary network means that this model won't work. Instead, we'll run LaBrea on the outer firewall itself.
(NOTE: a new LaBrea is currently in beta release, and some changes are needed for it to run on a T1 vs. on a standard Ethernet interface, and to improve its behavior in the application described here. See the patch file for the needed changes. They may already be in the beta when you read this.)
LaBrea has sophisticated facilities for acting as if it were all of the
nonexistent hosts on the boundary network in a dynamic manner. Since we're
running it on the outer firewall, and we only want to tarpit hosts after a
scan is detected, we need to turn off some of the smarts in LaBrea, and
tell it explicitly which hosts we want it to tarpit. Fortunately, LaBrea
supports a packet filtering mechanism via libpcap
. Make sure you
have a recent version of libpcap
- older versions have a bug that
prevents proper operation when the filter passes a certain size.
To generate the packet filter we need to capture the attacking IP addresses in a file, which the Portsentry blacklist script is doing. This file is then used to generate the packet filter file for LaBrea.
/usr/local/sbin/tarpit
:
#!/bin/bash
INET_IF=wp1_chdlc # the T1 - may be eth1 for non-T1 firewalls
NETWORK=' -n 192.168.0.0 -m 255.255.255.0 '
EVIL=/etc/IP-BlackList
BPF=/usr/local/etc/LaBrea-filter
# don't run this script in parallel
# this could definitely use some improvement
while [ -s $BPF.lock ]
do
if ps -p `cat $BPF.lock` >/dev/null 2>&1
then
# lock is valid
if [ -s $BPF.lock.2 ]
then
# another rebuild already queued
exit
else
echo $$ > $BPF.lock.2
sleep 5
rm -f $BPF.lock.2
fi
else
rm -f $BPF.lock $BPF.lock.2
fi
done
echo $$ > $BPF.lock
if [ -s $EVIL ]
then
rm -f $BPF
echo 'tcp and src host ( ' > $BPF
/usr/bin/perl -n -e 's/#.*//;
if (
/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+/
) {print "$1\n";}' $EVIL |\
uniq | tail -200 | sort | uniq | sed -e 's|/.*||' \
while read IP_TO_BLOCK
do
echo "$IP_TO_BLOCK or " >> $BPF
done
echo '127.0.0.1 )' >> $BPF
fi
rm -f $BPF.lock $BPF.lock.2
if ps -ef | grep -v grep | grep -q Labrea
then
# re-read packet filter file
killall -HUP LaBrea
else
# start LaBrea
exec /usr/local/sbin/LaBrea -z -i $INET_IF -l -v -j -x $NETWORK -F $BPF
fi
To manage LaBrea automatically, we make a “respawn” entry in
/etc/inittab
:
# run the tarpit daemon
tp:345:respawn:/usr/local/sbin/tarpit
And in the /etc/portsentry/portsentry.blacklist
script that
Portsentry runs to blackhole a new scanning host, we append a command to
run the tarpit script to update the packet filter:
nice /usr/local/sbin/tarpit