Scaring Crackers Away with TCP Wrapper
Adam Olson
Would it not be great if computers could be connected to a
network without any regard for malicious users and other security
threats? In this fairy tale world, you could focus solely on tuning
your systems to function as smoothly as possible. You wouldn't have
to worry about a thing while implementing that intricate backup
system you conjured up in your head. It is too bad this isn't the
case, but there are tools out there to increase the security of
these networked computer systems.
One of these tools is called TCP Wrapper. This article will cover
how to configure TCP Wrapper in such a way that crackers probing
your network will be afraid to investigate any further.
TCP Wrapper can also be used to verify a client's identity,
control which clients can access certain services, and display
custom banners. The last item will play a large part in telling the
cracker you know what they are up to.
Where is it located?
TCP Wrapper is available via ftp at:
ftp://ftp.porcupine.org/pub/security/ \
tcp_wrappers_7.6.tar.gz
For a list of other security tools written by Wietse Venema,
check out:
ftp://ftp.porcupine.org/pub/security/ \
index.html
The above link also includes a version of TCP Wrapper that
supports IPv6.
Building and Installing TCP Wrapper
I performed the following steps on a system running Solaris
2.7. The steps will be very similar on most other platforms. Place
the source in your favorite directory (/var/tmp, for
example):
# cd /var/tmp
Unpack the source:
# gzip -d tcp_wrappers_7.6.tar.gz
Untar the source:
# tar xvf tcp_wrappers_7.6.tar
Change directories:
# cd tcp_wrappers_7.6
Before running make, you must first uncomment the
appropriate line in the Makefile that designates the standard
location of the daemon software. On Solaris 2.7, it is line 47 of
the Makefile and it reads: REAL_DAEMON_DIR=/usr/sbin.
Run make and include the correct system type (type
make for a listing of system types):
# make sunos5 CC=gcc
If you run into any compile time errors, refer to the
README located in the tcp_wrappers_7.6 directory. The
README is also an excellent source for any questions you may
have about how TCP Wrapper functions and how it can be used. The
tcp_wrappers_7.6 directory will now include five additional
binaries: tcpdchk, tcpdmatch, safe_finger,
try-from, and tcpd.
The following is an excerpt from the README that provides
a brief description of each binary:
You can use the tcpdchk program to identify the most
common problems in your wrapper and inetd configuration
files.
With the tcpdmatch program you can examine how the wrapper
would react to specific requests for service.
The safe_finger command should be used when you implement
booby traps: it gives better protection against nasty stuff that
remote hosts may do in response to your finger probes.
The try-from program tests the host and username lookup
code. Run it from a remote shell command (rsh host
/some/where/try-from) and it should be able to figure out from
what system it is being called.
The tcpd program can be used to monitor the telnet,
finger, ftp, exec, rsh, rlogin,
tftp, talk, comsat and other TCP or UDP
services that have a one-to-one mapping onto executable files.
Finally, copy the newly compiled binaries to the following
directories:
# cp tcpd /usr/sbin
# cp safe_finger tcpdchk tcpdmatch try-from \
/usr/local/bin
Moving On to the Configuration
There are two ways to continue with the configuration. One
way involves moving daemon binaries around on your system. The other
leaves them alone, and all changes are made in the configuration
file of inetd. I recommend the latter, because I think it is
easier to manage all changes in one central place. Moving around
multiple files can become messy and is more prone to error. So, fire
up your favorite editor and modify inetd.conf. In this
example, I will be filtering connections to the telnet
daemon.
A typical telnet entry in inetd.conf will look
this:
telnet stream tcp nowait root \
/usr/sbin/in.telnetd in.telnetd
As far as running new connections through TCP Wrapper, we are
primarily concerned with the last two fields. The first defines the
location of the server program to start when the new connection
request arrives. The second is for including any arguments that
should be passed along to the server program.
Modify the telnet entry above to look like the following:
telnet stream tcp nowait root \
/usr/sbin/tcpd in.telnetd
Note that these are the steps to follow when using Solaris.
Other platforms will be similar or identical. If the location of
in.telnetd is different from what you specified as the
REAL_DAEMON_DIR in the Makefile, you must specify the
full path. For example:
telnet stream tcp nowait root \
/usr/sbin/tcpd /usr/local/sbin/in.telnetd
Save your changes to inetd.conf and send a HUP
signal to inetd.
# kill -HUP pid_of_inetd
Any requests to the telnet service should now be logged
and by default, if reverse and forward lookups on the client's
address don't match, the connection will be refused. If this isn't
kosher with your security policy, comment out the PARANOID=
-DPARANOID entry in the Makefile and recompile.
Try opening a telnet session to the host from both a
client whose reverse and forward name lookups match and from a
client who does not have matching name lookups. After doing this,
check out the log files. Logging information is by default sent to
the same location as Sendmail transactions. To change this, check
out the Makefile and README.
Your log file will look something like this:
# tail /var/log/syslog
Jun 4 19:08:28 kt in.telnetd[20483]: \
connect from ny.sparc5.com
Jun 4 19:09:05 kt in.telnetd[20493]: \
warning: can't verify hostname: getho
stbyname(bd.sparc5.com) failed
Jun 4 19:09:05 kt in.telnetd[20493]: \
refused connect from 206.13.45.90
The first connect from ny.sparc5.com was successful
because both name lookups returned the same value. There was a
discrepancy in the values returned for the second host, so the
connection was refused.
Access Control
Now that we have connections running through tcpd,
let's start restricting access to specific client IP addresses only.
This is accomplished by creating a /etc/hosts.allow file and
a /etc/hosts.deny file.
Before creating the files though, let's first go over how the
access control mechanism works. After receiving the connection
request, tcpd first examines /etc/hosts.allow for a
line that matches the requested daemon and client address. If one is
found, the client is permitted. If one is not found, the
/etc/hosts.deny file is opened and a daemon/client match is
sought. If a match is found, the client is rejected. If a match is
not found, the client is permitted. Thus, if there isn't a specific
rule denying the client or a catch-all rule denying anyone who isn't
permitted in /etc/hosts.allow, the client is allowed to
connect to the daemon. Make careful note of this, as you don't want
to leave a service open to any untrusted hosts.
You can approach access control in two ways. Permit certain hosts
and deny the rest, or deny certain hosts and permit the rest. The
deciding factor really depends on the environment in which the host
resides. Whenever possible, I prefer to permit a group of hosts I
have a trust relationship with and deny all others.
Create a /etc/hosts.allow and a /etc/hosts.deny
file identical to the following. (Substitute the allowed addresses
with trusted addresses of your own.):
/etc/hosts.allow:
in.telnetd: 10.1.2.3 10.4.5.6
/etc/hosts.deny:
in.telnetd: ALL
Now try it out! You should connect successfully from any IP
address in /etc/hosts.allow and be denied from any IP address
not in /etc/hosts.allow. Check out the log file as well to
make sure everything looks good.
The files above are an example of permitting specific trusted
hosts and denying everyone else. If you wanted to do the opposite,
the access files would look like:
/etc/hosts.allow - empty
/etc/hosts.deny:
in.telnetd: bad_user's_address problem_host
This configuration would permit any host not listed in
/etc/hosts.deny.
Custom Banners
Before I can discuss a design of how to fool a cracker into
telling you what they are up to, I must address how to create custom
banners.
Creating custom banners provides a way to personalize a service
or provide more information, such as the administrative contact, to
the client. We will be using custom banners to display a message to
the intruder that should deter them from pursuing the target host
any further. As long as the service being requested is using TCP,
this is easily accomplished with TCP Wrapper.
We need to first recompile the package to add support for the
extended options required to display banners. In addition to custom
banners, these extended options can perform a number of other tasks,
such as changing the security level of an event being logged,
providing additional access control syntax to consolidate rules into
one file, and enabling the execution of external scripts.
To recompile with support for extended options type:
# make clean
# make STYLE=-DPROCESS_OPTIONS sunos5 CC=gcc
# cp tcpd /usr/sbin
# cp safe_finger tcpdchk tcpdmatch try-from \
/usr/local/bin
The rest is straightforward. We want to display a banner to
anyone who is refused a connection to the telnet service.
This example is using the “permit some, deny the rest” mentality.
/etc/hosts.allow:
in.telnetd: 10.1.2.3 10.4.5.6
/etc/hosts.deny:
in.telnetd: ALL: banners /usr/local/banners
We just need to do one small thing before this will work --
create the banner! The “banners” in the above line tells tcpd
to issue a banner to the client. The path that follows is the
location where the banners live. So, /usr/local/banners needs
to be created, and a banner file with the same name as the requested
daemon will hold our banner text.
Using your favorite editor again, create a
/usr/local/banners/in.telnetd file that looks like:
Connection from unknown system refused!
Test this by opening a telnet session to the host from
an IP address that will fall under the ALL rule in
/etc/hosts.deny. You should be greeted with the custom
banner, and then your connection will be closed.
For information on how to configure other extended options, type:
# nroff -man hosts_options.5 |more -s
Scaring the Cracker Away
Perhaps by now you're saying, “I want to start scaring people
away!” After going over the above material, we are now ready to
implement the required measures. Let's first start off with how a
cracker will probe your network. A common way to gather information
about an unknown network is to use a tool called nmap or
something similar. For detailed information on nmap and to
download a copy, visit:
http://www.insecure.org/nmap
Upon execution, nmap will send a number of different
types of packets to a target host or network and will return a list
of active port numbers (provided they are not blocked by a firewall,
router ACL, etc). Because many services have a default port that
they listen on, it is fairly easy to determine which services are
active and to which exploits the host or network may be vulnerable.
The cracker will then attempt to connect to one of these ports to
obtain additional information, such as the server program name and
version.
We want to configure TCP Wrapper to listen on multiple unused
ports. Choose ports normally used for common network services that
the host is not providing. This would include services like smtp
(port 25), http (port 80), and pop3 (110).
Let's say we have a host that should only be providing ssh and
http services. We will modify /etc/inetd.conf to include
others services that tcpd will be responsible for. TCP
Wrapper will listen on unused ports that crackers commonly attempt
to contact (such as the ftp and telnet ports) and will
send a blistering message to any intruder who attempts to contact
the port. If these ports are ever contacted, there is a very high
chance someone is poking around.
An example copy of /etc/inetd.conf on Solaris is:
ftp stream tcp nowait root \
/usr/sbin/tcpd in.ftpd
telnet stream tcp nowait root \
/usr/sbin/tcpd in.telnetd
/etc/hosts.allow would be empty. /etc/hosts.deny
would look like this: ALL: ALL: banners /usr/local/banners : spawn \
(/usr/bin/mailx -s "tcpd violation from %h \
- possible cracker!" [email protected]) &
Note that %h is expanded to include the address of the
source host. For a list of other variables you might want to use,
type:
nroff -man hosts_access.5 |more -s
Send a HUP signal to inetd, and you are set:
# kill -HUP pid_of_inetd
TCP Wrapper should now be listening for incoming connections
on port 21 and port 23. The connection will be refused and a custom
banner will be displayed to the cracker. Make sure that the correct
files exist in /usr/local/banners, as they must match the
name of the daemon.
An example custom banner for the ftp daemon would be
located at /usr/local/banners/in.ftpd and would look
something like:
This service is not provided by this host!
An administrator has been notified of this
connection attempt and your IP address has
been logged for our records!
All traffic to this host is now being captured
and logged!
That last line is an extra incentive for the cracker to run
away. If you dont currently capture traffic that strays from your
normal traffic trends, I suggest checking out:
http://www.snort.org
Snort is an excellent lightweight network intrusion detection
program that I use to capture all “interesting” traffic 24x7. There
is also an article on Snort in the September issue of Sys
Admin.
From the Crackers Point of View
To test this setup, pretend you are probing your own network.
You will see something like the following:
# ./nmap hostname
Starting nmap V. 2.3BETA14 by [email protected] \
( www.insecure.org/nmap/ )
Unable to find nmap-services! Resorting
to /etc/services
Interesting ports on host (10.1.1.1):
Port State Protocol Service
21 open tcp ftp
22 open tcp unknown
23 open tcp telnet
80 open tcp unknown
Nmap run completed -- 1 IP address (1 host up) \
scanned in 0 seconds
# telnet hostname 21
Trying 10.1.1.1...
Connected to host.domain.com.
Escape character is '^]'.
This service is not provided by this host!
An administrator has been notified of this
connection attempt and your IP address has
been logged for our records!
All traffic to this host is now being captured
and logged.
Connection closed by foreign host.
Also, verify that an alert was received at the email address
defined earlier.
Conclusion
TCP Wrapper is an excellent tool to use for early
notification of a crackers attempt to probe your network, as well as
scaring them away. If this doesnt deter crackers, the administrator
is still alerted to whats going on and can immediately either watch
them or block them from entering the network with ingress filtering.
TCP Wrapper has other uses that were not covered in this article, so
please check out the README file to see if those interest
you.
About the Author
Adam Olson has helped build a successful ISP
(http://www.humboldt1.com), designed and configured portions of the
California Power Network while working at MCI WorldCom, and is
currently working for a company targeting the e-commerce and time
management industries (http://www.quaartz.com). Adam hopes to be
sailing a lot soon. He can be reached at: [email protected]
|