Section 14.2 Adaptive Firewalls: Raising the Drawbridge with the Cracker Trap

   


14.2 Adaptive Firewalls: Raising the Drawbridge with the Cracker Trap

graphics/fourdangerlevel.gif

Years ago, my network was the target of yet another attempted intrusion. Within a second, this obviously automated attack tried to break into my network via FTP, sockd, and telnet. At this point, the intruder went away, but what if he then had tried other services? What if he then tried brute force password cracking of my SSH server? What if one of my systems offered anonymous FTP and he then tried to FTP my /etc/passwd file up to his system for password cracking at his leisure?

Well, he "blew" his chance in a fraction of that first second because I had created what I call my Cracker Trap™, a very effective Adaptive Firewall technique. With this technique, once my system detected an attempt to crack it, automatically and within a fraction of a second the Cracker Trap locked the cracker's system out of all services on my system regardless of whether they normally are available to any system or if I forgot to block their access from my external (Internet-connected) interface. It used IP Chains (but supports IP Tables as well) to drop any more packets from his system, updated the system's configuration files to ensure that after a reboot or system upgrade it would continue to block him, and then notified me via e-mail, pager, flashing the office lights, and generating distinctive sound effects on my desktop system's speakers. Welcome to the world of Adaptive Firewalls.

As you can see, an Adaptive Firewall changes (adapts) its rules as needed to protect against attacks and to anticipate attack types that it has not yet seen. A standard nonadaptive firewall may prevent the attacker from getting to certain services that are specifically blocked from the Internet, but still allow him to attack other services that are open to anyone and which may have vulnerabilities that we do not yet defend against. Such a standard firewall must be perfect and any server behind it also must be perfect or a security breach easily can happen. However, an Adaptive Firewall does not need this impossible-to-achieve perfection for good security because the attacker has to choose among only a few "real" services and a lot of traps. Once he touched a trap he was caught.

In the two years since I invented the Cracker Trap, I have deployed it at numerous client sites and it has proven to be very effective at locking out crackers while allowing honest people to use the offered services unimpeded. It is effective both against scans for multiple services on a system and against searches for the same service (or multiple services) on multiple systems. It also is effective when a cracker attempts to access a supported service from a system other than one the clients are allowed to connect from. This is excellent protection for SSH access, for example. One heavily attacked system whose Cracker Trap-protected firewall (with an 800MHz Pentium III processor) has accumulated 4,000 IP Chains entries, yet packets still get through in less than a millisecond.

Thus, if someone accesses the mail (SMTP) port of the Web server (or the http port of the mail server), they get completely locked out of the entire network. Even if, say, all of these systems allow SSH access from each SysAdmin's home system's IP, the Cracker Trap can be configured so that if any other system tries to access SSH, it is identified and locked out of the entire network.

One client had such high-security requirements (due to his working with a billion-dollar company), that he first hired me to harden his Linux/Apache Web server and then he had a separate company that does Penetration Testing try to break in. While these guys were better than most crackers, they had only five IPs, and I had trapped about 20 ports. They were sadly outnumbered and used up all of those five IPs in about 30 minutes. Their contracted "eight-hour penetration test" had failed in half an hour, because all of their systems were completely locked out, and they were unable to probe the network's Web server, DNS server, mail server, etc. for vulnerabilities.

Then they managed to convince our mutual client that my technique was "unfair," until I asked the client two questions:

  1. Were the "crackers" (i.e., the penetration team) locked out quickly? Well, yes.

  2. Were honest clients able to continue to use the network unimpeded? Well, yes. Uh, thanks. Mission accomplished.

I could have outnumbered them even more. Instead of having the Cracker Trap lock out just the attacking IP, I could have added /24 to the IP Tables or IP Chains rule created. In other words, if the attacking IP was 207.46.197.113, the Cracker Trap could generate the IP Tables command

 
 /sbin/iptables -I FORWARD 1 -s 207.46.197.113/24 -j DROP /sbin/iptables -I FORWARD 1 -d 207.46.197.113/24 -j REJECT /sbin/iptables -I INPUT   1 -s 207.46.197.113/24 -j DROP /sbin/iptables -I OUTPUT  1 -d 207.46.197.113/24 -j REJECT 

or the IP Chains command

 
 /sbin/ipchains -I input  1 -s 207.46.197.113/24 -j DENY   -l /sbin/ipchains -I output 1 -d 207.46.197.113/24 -j REJECT -l 

This would lock out the entire class-C network (or nearest 256 addresses from a class-B or -A network) and would have locked out the entire penetration team's company on the first attacking packet. It is possible even to have specified /16 instead. You may ask, "Why block out the whole 256 or 16,384 block of addresses?" Well, if they were lax or unlucky enough to suffer one system having been compromised, there is a chance that other of their systems have suffered a similar fate and other crackers will be visiting soon.

How to install shell scripts

For installing shell scripts that have an extension of .sh or .csh, use a procedure that is similar to that of C programs. The difference is that instead of doing make blockip or cc -o blockip blockip.c, issue the following commands to copy the script to the name under which it will be invoked, add execute permission, and install in an appropriate directory such as /usr/sbin or /usr/local/bin by doing

 
 cp blockip.csh blockip chmod 755 blockip cp blockip /usr/sbin/blockip ls -l /usr/sbin/blockip 

The Cracker Trap is available on the CD-ROM.


Keep in mind that you will be paged with the host name of the system that attacked your network, so if it shows as a dynamic address on a well-known ISP, or ebay.com, you always can edit the entry in /etc/rc.d/fw.trouble to remove the /24 or /16 from the IP or remove the entry entirely after a while. While some SysAdmins have questioned my locking out a dynamically assigned IP, my response is, "what percentage of all likely legitimate visitors to your site does it represent?" Most SysAdmins agree that this is a very small percentage of innocent IPs (after the dynamically assigned IP gets assigned to someone else), as opposed to there being a 100 percent chance of there being an attacker on it now and for an unknown amount of time to come.

Use good judgment when restoring access from locked out IP addresses. Some Adaptive-Firewall and security experts advocate unblocking an IP that has attacked a short time after the attack, sometimes as soon as an hour later. Their worry is that a legitimate user or system might be denied access.

Again, the odds are against this being a problem. I have had to unlock an IP less than a dozen times out of the thousands of IPs that my Cracker Trap and PortSentry have blocked intruders from accessing the networks I manage.


Additionally, the log-monitoring scripts, discussed in "Paging the SysAdmin: Cracking in Progress!" on page 620, easily could be enhanced to interface with the Cracker Trap by invoking its blockip program. The blockip program then would lock the intruder out of everything, addressing stealth scans and similar protocol-level attacks. The log-monitoring scripts are not limited to the log files in /var/log; they can be used to monitor Apache's log files and those of other subsystems. Further, other tools such as PortSentry can be configured to trigger the Cracker Trap, because the Cracker Trap has more advanced response to attacks than does PortSentry.

My Cracker Trap technique is based on Adaptive Firewalls, an idea that started becoming popular around 1999. With a standard firewall, the rules specifying which systems (or domains) have access to particular services (TCP or UDP ports or ICMP services) are unchanging, unless changed manually by a SysAdmin or network administrator.

Assume that some service, such as FTP, is offered to all systems (because you offer anonymous FTP to the world). If a cracker is unable to get in with, say, telnet, portmap, or sockd because you deny these services, then he can try FTP, hoping your version has some recently discovered security bug. He then may compromise your system.

An Adaptive Firewall, on the other hand, detects that a particular IP has tried a service denied to it (such as telnet) or has tried something else prohibited and then adapts to the attacker by altering the rules to lock this IP or network out of all services, not just the one being attacked. Thus, even if there is a bug in your WU-FTPD, Sendmail, or Named daemon or if the cracker is planning a brute-force cracking of passwords next, it is likely that he will be locked out of your system before he can try any of these attacks.


I designed the Cracker Trap for those with only a single system on the Internet or just a few Linux and UNIX boxes where a firewall may be more trouble than simply hardening these individual systems. However, it has worked extremely well as an add-on to an IP Tables or IP Chains based firewall that is in front of networks with hundreds of systems. In fact, it becomes more effective, because the ratio of traps to real services can be increased. One configures the Cracker Trap to set the traps by configuring TCP Wrappers' /etc/hosts.allow configuration file to allow or deny various services to specified hosts, IPs, or domains. The Cracker Trap relies on TCP Wrappers' capability that allows a system administrator to specify one or more shell commands when denying a given service.

The Cracker Trap takes advantage of this latter feature to invoke a shell script that I have written, called blockip, which is provided on the CD-ROM. It will adapt the firewall in real time to stop a cracker's IP from accessing any service, will send e-mail to the SysAdmins, and will page them as well, if desired. It sends different e-mail depending on whether the attacker is new or a return visitor (and still being blocked). It can adapt rules based on IP Tables, IP Chains, or TCP Wrappers. It has several "bells and whistles." When under attack, it can deliver a sound file of your choice both to the system being attacked and to an alternate system, such as your desktop system. Lastly, it can drive an X10 FireCracker[1] to flash lights or ring bells so that even if you are away someone will notice.

[1] X10 is the brand name of a popular, inexpensive remote control device that can control almost any home or business electrical device. A computer with a serial connection can control them. There is Linux software available. A command line interface software program is supplied on the CD-ROM and is used by blockip, the heart of the Cracker Trap.

The blockip program uses a locking mechanism so that if two or more cracker attempts happen at the same time (which would be expected from an automated attack), the subsequent instantiations will wait for the previous ones to complete before adding its entry. This second entry will be redundant unless there is a coordinated attack from different systems (in which case all of them will be locked out), or the low probability of unrelated attacks occurring at the same time.

When and if you install blockip, note that tcpd, ipchains, iptables, and other secure versions of programs are located in /usr/sbin, /sbin, or /bin. You will want to verify the location of each program used by blockip and change blockip as necessary, so it will work correctly on your system. Your version of these programs may be located in /usr/local/bin, /usr/local/secbin, or another place, depending on your distribution and the mood of your SysAdmin. You probably will want to install the blockip script in the same directory as tcpd for consistency, though its location only need be coordinated with /etc/hosts.allow.

It also is suggested that you keep a copy of blockip, /etc/hosts.allow, /etc/hosts.deny (as well as other configuration files) in a subdirectory of either ~root or of one of the SysAdmin's accounts so that when you upgrade to a new version of Linux, these files will not be lost. This can be an issue because some installation programs do not take proper care of existing configuration files.

It is important to note that when someone requests a service that is disallowed, tcpd invokes

 
 (sleep 3;tail -10 /var/log/messages) 

The blockip script design required careful consideration of race conditions. It first issues an mkdir /etc/blockip.lock command. Creating a directory has worked as a Mutex Semaphore (lock) since at least UNIX Version 6. It then renames /etc/hosts.allow to a temporary name leaving only /etc/hosts.deny. It is critical to add the line

 
 rmdir /etc/blockip.lock 

to the /etc/rc.d/rc.local file, so that if the system crashes while the lock is held, it will be freed on reboot.

Note that this inclusion of the last 10 lines of the messages file in the Cracker Trap e-mail is an enhancement for the second edition. It allows you to see easily if the attacker has been scanning other ports or systems. If port redirection (transparent proxying) is used to trap ports on other systems that we route for, this also will show what system he tried to attack.

In the first edition, we instead included the output of safe_finger in the e-mail. We no longer do this. In todays darker world, the attacking system usually is compromised at the root level, so the account used is meaningless. Further, so few attacking systems support the finger protocol that the risk of the attacker seeing our finger exceeds the likely knowledge to be obtained.

Further, using the IP Tables or IP Chains version of the Cracker Trap would require special dynamic rules to allow outbound finger traffic to the attacking system. While this could be done in the immediately executed rules and not the ones stored in fw.trouble, I do not consider it worth the trouble for most installations.


Note that the Cracker Trap will not detect certain "Stealth Port Scanners" that do not use the proper three-way TCP open, nor will it detect some packet spoofing attempts. Rather than following the TCP protocol specification, these crackers send only, say, the initial TCP packet or a Reset (RST) packet, or otherwise violate the protocol and look for a response.

Since they fail to complete the open-packet exchange sequence, the program waiting for a client on this port (xinetd or inetd for many ports) never will see a client connection request. This is not a limitation of TCP Wrappers but rather of xinetd (or inetd), as they are not designed for this; it requires kernel support or the use of a raw socket to detect in any case.

PortSentry, however, may be configured to detect and lock out these Stealth scanners, either on its own or by interfacing to the Cracker Trap. Its capabilities, installation, and use are covered in "Using PortSentry to Lock Out Hackers" on page 613.


The hosts.deny file absolutely must have a line that denies all services to all hosts (except possibly where there is a line allowing certain critical services to certain hosts duplicating lines in the /etc/hosts.allow file). The reason for this is that there is an interval (of less than a second) while the /etc/hosts.allow file has been moved elsewhere for update when another request for a service may come in. It is imperative that this request be denied in case it is a cracker trying to get in. (I realize that a legitimate request may not get in during this time; he will just have to try again. If there are critical operations that you do not want to fail, simply have lines in the /etc/hosts.deny file that allow them.) We are "failing safe" here.

So, what are the disadvantages of the Cracker Trap? It has been in operation now for several years at a number of closely watched sites, so we have gained considerable operational experience. First, there is the case of a very intense attack where the intruder sends many requests in a few seconds. There will be about four processes forked for each request until the IP Tables or IP Chains rule that will block the attacker is inserted into kernel space, costing your system process table slots, computrons (CPU cycles), and disk usage. Realistically, at T1 or E1 speeds, a modern system should have even the most intense attack locked out within a few seconds.

The system is vulnerable to a more sustained but much less likely DoS attack if the Cracker Trap is protecting any UDP ports. This is because if the cracker knows the IP address of a client system that you want to allow in, he can spoof that source address and cause that IP address to be locked out. While many people have pointed out this weakness, it never has happened on any of the many systems that I monitor. Since the Cracker Trap sends e-mail with the attacking system's IP and host name, the SysAdmin should recognize the system, verify that it has not been compromised, and then recover.

The recovery from a spoofed UDP attack is to edit the /etc/rc.d/fw.trouble file, remove the erroneous rules,[2] and restart the IP Tables or IP Chains rules. See ""Firewall Tricks and Techniques" on page 472 for details on how to build firewall rules to allow safe and easy restarting without rebooting or having a few seconds of vulnerability. There is a sub-second window during the time the /etc/hosts.allow file is being updated when all services are denied to all systems; this represents a DoS possibility. This can be prevented by adding appropriate lines for those "must have" services in the /etc/hosts.deny file.

[2] There actually are three versions of the Cracker Trap, one for IP Tables (blockip.tables.csh), one for IP Chains (blockip.chains.csh), and the granddaddy, the one for TCP Wrappers (blockip.wrappers.csh). All are on the CD-ROM in the book/crackertrap directory. The correct one should be copied to /usr/sbin/blockip. For those few that use the TCP Wrappers version, one simply edits the /etc/hosts.allow file.

There is an important feature in the Cracker Traps blockip script that can be used to list systems that should not be locked out of all services even if they "do something wrong." Some would call this a white list. Specify, you can "white list" host names by setting the hostok variable appropriately in the blockip script. List other white-list systems with their numeric IP, by setting the ipok variable. Use of the ipok variable is preferred, as it is faster and much harder for a cracker to spoof because there is not the possibility of a DNS server to compromise.


The following catchall line should be at the bottom of the /etc/hosts.allow file to activate the blockip script if no previous entry allows the request.

 
 # Our default ALL: ALL that will cause that system to be # permanently blocked from all services. # # NOTE: this entry must be in hosts.allow (not hosts.deny) and # there also must be a "ALL: ALL: deny" in hosts.deny for this # script to work correctly and not have a momentary security hole; # blockip might be located in elsewhere. ALL: ALL: \    spawn=((sleep 3;tail -10 /var/log/messages) | \    /usr/sbin/blockip "%h" "%a" "%d" "%c" "%u") &: deny # End of hosts.allow. 

The following generally should be the only line in one's /etc/hosts.deny file when setting up the Cracker Trap with the blockip script:

 
 # The "DENIEDdefault" means denied by default. # This is very important as the auto-add (blockip) feature will # cause the /etc/hosts.allow file to vanish for sub-second windows # of time if the TCP Wrappers version of lockout is used. # # If you have critical services that you cannot allow being # disabled even for less than a second then add an entry before # here specifying ":allow" # NOTE that on some systems the mail program is /bin/mailx ALL: ALL: spawn=((sleep 3;tail -10 /var/log/messages) | \   /bin/Mail -s DENIEDdefault_%h/%d/%a/U=%u \   joe@homesys.com joe@pentacorp.com \   ) &:deny # End of hosts.deny. 

Please change the e-mail addresses for Joe to be your own.

Any of the three versions of the blockip script may be copied from the CD-ROM. You will most likely want to use the blockip.tables.csh version that dynamically alters an IP Tables based firewall. Alternatively, there is the blockip.chains.csh version for use with IP Chains based firewalls. Lastly, there is the blockip.wrappers.csh version for use with TCP Wrappers based firewalls that do not use IP Tables or IP Chains; it is there mostly for historical reasons and for anyone who might still be using a 2.0 kernel-based system (which is not recommended). Note that while blockip is written in csh script, it can be invoked from any shell or executed directly from an exec family system call. Also on the CD-ROM are the snippits of /etc/hosts.allow and /etc/hosts.deny that appear above.

Note that this script even offers warning bells and lights by driving an X10 FireCracker (www.x10.com) via the Linux freeware BottleRocket! The FireCracker triggers an X10 wireless interface transmitter. The transmitter then drives an appliance module that drives a lamp. The example flashes the lamp a few times and then leaves it on. To get fancier, use a lamp with a bare red lightbulb through a blinker plugged into the X10 appliance module. Note that you should plug the blinker into the X10, not the other way round. X10 also offers audible alarms and dry contacts that you can connect to alarms of your own design.

The X10 Firecracker is a wonderful and inexpensive transmitter that you can plug into a serial jack. You can even plug your normal serial device into the other end, in most cases. A simple C program for Linux called BottleRocket is available. It is GPL'ed Open Source and may be downloaded from

www.mlug.missouri.edu/~tymm

or

www.debian.org/Packages/unstable/electronics/bottlerocket.html

The following script, called blockiptest, may be used to test the blockip script prior to deployment without blocking any real systems. Typically, it is installed in /usr/local/bin mode 755. It is helpful to verify that blockip has been installed correctly and is able to add rules to IP Tables or IP Chains. After running this test, then use telnet to a trapped port and see if blockip is invoked. It is on the CD-ROM.

 
 echo "Test email input to blockip" | \ /usr/sbin/blockip "cracker.com" \    "111.222.333.444" "Zservice" \    "joe@cracker.com" "joe" 

If you are blocking some ports with IP Tables or IP Chains, the ones on which the Cracker Trap has traps must not be blocked in order for the Cracker Trap to work. There is no security risk here so long as the Cracker Trap (and not the real service) is listening on the port. If you want to be extra careful, you can take the additional precaution of having IP Tables or IP Chains rules that block these services from accessing your internal or DMZ networks while still allowing them from the Internet to the Cracker Trap running on the firewall.


14.2.1 Configuration

To set up the Cracker Trap, you need to update these configuration files in /etc, well-known to most SysAdmins, to know about the desired ports.

 
 /etc/services /etc/hosts.allow /etc/hosts.deny   (only if blocking with TCP Wrappers) /etc/xinetd.d/*   (most recent versions of Linux) /etc/inetd.conf   (older versions of Linux and some distributions) 

We may add a few services to the /etc/services file, such as the cracker Trojan Back Orifice. We may alter some "oldies but baddies" such as imap3, echo, and time, so that the UDP version of the service has a "u" appended to the name. In this way, we can tell whether the TCP or UDP service was attacked. The /etc/hosts.allow file is set up similarly to any normal Linux system, except that the server must be tcpd (usually /usr/sbin/tcpd) and its argument is a special safe program to identify the service for reports and which offers no attack point to crackers. In /etc/hosts.allow, you need to set up a line to specify the unconditionally forbidden services that will cause the Cracker Trap to spring, therefore invoking the /usr/sbin/blockip program. This line should be near the top of the hosts.allow file to reduce the likelihood of enabling one of these services accidentally, because this file is scanned for the first match by TCP Wrappers (tcpd).

Near the bottom of the hosts.allow file, have a line to trigger the Cracker Trap for all services from all systems. This will spring the trap for any combination of service and system not explicitly allowed. Certainly, you must be very careful not to make errors here, or you might be enabling a service that you do not intend to enable, thus inadvertently creating a vulnerability. To reduce the likelihood of this (as part of our Rings of Security), configure a special program to be invoked if you accidentally allow a forbidden service.

A major advantage of the Cracker Trap over PortSentry even more important than its more powerful notification features is that a particular service such as SSH can be allowed from some systems or networks while also being a trap for everyone else. Many SysAdmins want to be able to SSH into their servers and firewalls from their home systems for off-hours maintenance, and yet want to lock out crackers trying the same thing. This is trivial to do with the Cracker Trap; merely have the entry in the hosts.allow file that lists which systems may use the SSH port sshd, sshd2, and sshdfwd-X11) prior to the catch-all entry at the end which triggers the Cracker Trap.


Now we examine these configuration files in detail.

14.2.2 The /etc/services File

In the /etc/services file, you need to ensure that there is a mapping from numeric port numbers to service names. Most of these will be present already. Some of these will be commented out, especially if you followed the recommendations of earlier chapters in the book. Rather than simply uncommenting them, the existing ones need to be altered substantially. I suggest leaving the existing entries commented out and adding the trap entries, possibly at the end of the file. My entire production /etc/services file is on the CD-ROM.

In the case of services that are supported for both TCP and UDP, I append a "u" to the end of the name for the name corresponding to UDP. While this is not necessary, it allows the server program argument to have the same name (except that I prepend a "Z" to each server program argument in the /etc/xinetd.d/* or inetd.conf file to denote a forbidden service). The trap entries in /etc/services follow.

 
 # # Cracker traps # echo          7/tcp echou         7/udp time          37/tcp    timeserver timeu         37/udp    timeserver timed         525/udp   timeserver imap2         143/tcp               # Interim Mail Access Proto v2 imap2         143/udp imap3         220/tcp               # Interactive Mail Access mount         635/udp               # NFS Mount Service nfs           2049/udp              # NFS File Service wraptroj      421/tcp               # TCP Wrappers Trojan wraptroju     421/udp               # TCP Wrappers Trojan pop3          110/tcp               # POP version 3 pop3          110/udp snmp          161/udp               # Simple Net Management Proto snmp-trap     162/udp   snmptrap    # Traps for SNMP irc           194/tcp               # Internet Relay Chat irc           194/udp at-rtmp       201/tcp               # AppleTalk routing at-rtmp       201/udp at-nbp        202/tcp               # AppleTalk name binding at-nbp        202/udp at-echo       204/tcp               # AppleTalk echo at-echo       204/udp at-zis        206/tcp               # AppleTalk zone information at-zis        206/udp ipx           213/tcp ipx           213/udp biff          512/udp   comsat who           513/udp   whod talk          517/udp ntalk         518/udp whois         43/tcp    nicname ftp           21/t                  # ftp trap telnet        23/tcp                # telnet trap smtp          25/tcp                # smtp trap http          80/tcp                # http trap httpsec       443/tcp               # secure http trap squid         3128/tcp              # squid trap socks         1080/tcp              # socks trap kazaa         1214/tcp              # kazaa trap kazaa         1214/udp              # kazaa trap microsoft-ds  445/tcp               # w2k trap microsoft-ds  445/udp               # w2k trap netbios-ns    137/tcp               # netbios-ns trap netbios-dgm   138/tcp               # netbios-dgm trap netbios-ssn   139/tcp               # netbios-ssn trap netbios-ns    137/udp               # netbios-ns trap netbios-dgm   138/udp               # netbios-dgm trap netbios-ssn   139/udp               # netbios-ssn trap socdimi       31337/tcp             # Cracker's socdimi back_or       31337/udp             # Cracker's Back Orifice mstreamm1     6838/udp              # Cracker's mstream master 1 mstreamm2     9325/udp              # Cracker's mstream master 2 mstreamz1     10498/udp             # Cracker's mstream zombie 1 mstreamz2     7983/udp              # Cracker's mstream zombie 2 trin00        27444/udp             # Cracker's Trin00 (trinoo) wtrin00       34555/udp             # Cracker's Windows Trin00 wtrin00c      35555/udp             # Cracker's Windows Trin00 client barbed1       16660/tcp             # Cracker's Stacheldraht/Barbed Wire 1 barbed1u      16660/udp             # Cracker's Stacheldraht/Barbed Wire 1 barbed2       60001/tcp             # Cracker's Stacheldraht/Barbed Wire 2 barbed2u      60001/udp             # Cracker's Stacheldraht/Barbed Wire 2 b_agent       65000/tcp             # Cracker's Stacheldraht/BW agent b_agentu      65000/udp             # Cracker's Stacheldraht/BW agent 

Note that the port numbers listed for the various Trojan horses are only the default port numbers. Still, scans for these make up a majority of cracker attacks on systems that I monitor, so it is an effective detection technique. Certainly, it is trivial for a cracker to tweak trin00 or Barbed Wire or Tribe Flood Network (TFN) or TFN2000 to use a different port number. Also, there are versions of some of these that are able to listen without having any UDP or TCP port open. See "Stealth Trojan Horses" on page 400 for the scary details.


14.2.3 The /etc/xinetd.d/* Files

The xinetd.d/* files are in recent versions of most Linux distributions, having replaced the inetd.conf file of yore. The intent seems to have been to make writing installation scripts easier while making life more difficult for most SysAdmins. This configuration file specifies which ports xinetd, the Internet super-server, should listen on. Services that have a separate daemon running, such as smtp, better known as Sendmail, Postfix, or Qmail, should not be listed in this file unless we want a trap on the port instead of the real standalone service. It is important to note that for some of the password-protected services, crackers frequently try a large number of passwords very rapidly, under program control.

Each of these connection attempts normally will result in about four processes being forked. The simple solution is to use a little-known feature of xinetd, the instance feature. This feature can be used to specify how many instances of a given service may be running simultaneously. The default is unlimited. Since you do not want the cracker in, except for a single instance to record his presence and lock him out, a small number is suggested. The value 2 or 3 is suggested. You also may use the per_source feature to limit forked processes to one per source IP.

The trap entries in each /etc/xinetd.d/* file look similar to the following one for rsh (the shell service). A representative set suitable for the xinetd version of the Cracker Trap may be copied from the CD-ROM.

 
 service shell {         socket_type       = stream         wait              = no         user              = root         log_on_success    += HOST         log_on_failure    += HOST         server            = /dev/Zshell[3]         disable           = no } 

[3] I have the program name begin with Z because it is this name, rather than the port name, that TCP Wrappers uses when checking the access rights in /etc/hosts.allow and what it passes to the Cracker Trap. Names beginning with Z are noticeable and unlikely to be mistaken for a real service.

I picked the /dev directory somewhat arbitrarily. Any directory that only root has write access to will work, but it should not be a directory where programs normally live. Creating, say, the /trap directory would work fine. Issue the following command to create Zshell.

ln /bin/pwd /dev/Zshell

14.2.4 The /etc/inetd.conf File

The inetd.conf file has been replaced by the xinetd.d/* files in recent versions of most Linux distributions, but some readers will be using inetd. The inetd.conf configuration file specifies which ports inetd, the Internet super-server, should listen on. Services that have a separate daemon running, such as smtp, better known as sendmail, should not be listed in this file unless we want a trap on the port instead of the real standalone service. It is important to note that for some of the password-protected services, crackers frequently try a large number of passwords very rapidly, under program control. Each of these connection attempts normally will result in about four processes being forked. The simple solution is to use a little-known feature of inetd, the max feature. This feature can be used to specify how many instances of a given service may be started within one minute.

The default number is quoted as being 40. Since you do not want the cracker in, except for a single instance to record his presence and lock him out, a small number is suggested. Since inetd seems to have an off-by-one bug, the value 2 or 3 is suggested. Note that the documentation and source code suggests that if one reaches this limit, it should be possible to initiate new instances of a service after a minute. Instead, I found that a longer time seemed to be necessary, perhaps two minutes. When testing this capability with telnet, I found that if a particular telnet exceeded the limit, it hung up until killed. While this is a feature of a Cracker Trap, it can be annoying during testing. This value is added after the wait or nowait values, separated from either of them with a period (.).

It is important to note that after an intense attack (under either xinetd or inetd), sometimes there will be hung tcpd processes. The solution is to issue the following command.

 
 killall tcpd 

There is the possibility of a DoS attack, due to a cracker creating enough hung tcpd processes to fill up the process table. Limiting the rate of process creation per minute will limit this problem. An additional solution might be to add the following lines to the blockip script, near the end, to kill any hung tcpd processes.

 
 (sleep 300;killall tcpd)& (sleep 1400;killall tcpd)& 

An improvement is to include the following lines instead that will invoke a Perl script that is more selective.

 
 (sleep 300;kill_tcpdz)& (sleep 1400;kill_tcpdz)& 

The Perl script, called kill_tcpdz, is shown below and is available on the CD-ROM.

 
 #!/usr/bin/perl # Copyright 2001 Mike O'Shaughnessy. All rights reserved. # Unlimited use of this script may be made on the condition # that this copyright remains and that the user accepts full # liability for any problems and it is accepted "as is". $pscmd = "ps auxww"; if (! open(PS, "$pscmd|") ) {   print "kill_tcpdz: could not open ps\n"; } @stuff = <PS>; foreach (@stuff) {   @line = split(' ');   $pid = $line[1];   $what = $line[10];   if ($what =~ /\/dev\/Z/) {     print "kill_tcpdz: killing $pid $what\n";     kill 'INT', $pid;   } } exit 0; 

The trap entries in /etc/inetd.conf follow.

 
 #echo        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zecho .htm#echou       dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zechou #time        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Ztime #timeu       dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Ztimeu #timed       dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Ztimed imap2        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zimap2 imap3        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zimap3 mount        dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zmount nfs          dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Znfs wraptroj     stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zwraptroj wraptroju    dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zwraptroju biff         dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zbiff who          dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zwho whois        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zwhois pop3         stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zpop3 snmp         dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zsnmp irc          stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zirc talk         dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Ztalk ntalk        dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zntalk ftp          stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zftp telnet       stream tcp nowait.2 root /usr/sbin/tcpd /dev/Ztelnet smtp         stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zsmtp http         stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zhttp httpsec      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zhttpsec sunrpc       stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zsunrpc squid        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zsquid socks        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zsocks kazaa        stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zkazaa kazaa        dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zkazaau microsoft-ds stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zmicrosoft-ds microsoft-ds dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zmicrosoft-ds at-rtmp      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zat-rtmp at-nbp       stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zat-nbp at-echo      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zat-echo at-zis       stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zat-zis ipx          stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zipx netbios-ns   stream tcp nowait.2 root /usr/sbin/tcpd /dev/Znetbios-ns netbios-dgm  stream tcp nowait.2 root /usr/sbin/tcpd /dev/Znetbios-dgm netbios-ssn  stream tcp nowait.2 root /usr/sbin/tcpd /dev/Znetbios-ssn netbios-ns   dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Znetbios-ns netbios-dgm  dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Znetbios-dgm netbios-ssn  dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Znetbios-ssn socdimi      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zsocdimi back_or      dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zback_or mstreamm1    dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zmstreamm1 mstreamm2    dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zmstreamm2 mstreamz1    dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zmstreamz1 mstreamz2    dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zmstreamz2 trin00       dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Ztrin00 wtrin00      dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zwtrin00 wtrin00c     dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zwtrin00c barbed1      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zbarbed1 barbed1u     dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zbarbed1u barbed2      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zbarbed2 barbed2u     dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zbarbed2u b_agent      stream tcp nowait.2 root /usr/sbin/tcpd /dev/Zb_agent b_agentu     dgram  udp nowait.2 root /usr/sbin/tcpd /dev/Zb_agentu 

14.2.5 The /etc/hosts.allow File

In the /etc/hosts.allow file we have a catchall entry to both deny and invoke the Cracker Trap (blockip) for any combination of host and service that is not allowed specifically. Assume that you allow a certain service, such as SSH, from a few systems, such as the SysAdmins' home systems and the Albany office. If anyone else tries to access SSH, the default Cracker Trap entry still will trigger and lock them out. Thus, any given service (that is supported by TCP Wrappers, which is most of them) can both be offered to legitimate systems and be a trap used to lock crackers out. Since SSH is one of the most frequently attacked services due to the possibility of brute-force cracking of passwords, this is a valuable feature. Most other Adaptive Firewalls, such as PortSentry, cannot do this.

A question that you do need to answer is whether or not you want some of your own systems to be locked out of all services automatically if an attempt to access a forbidden port is made. Recall that if you do not want some of these systems locked out automatically, they need to be listed in the hostok or ipok variables in /usr/sbin/blockip.

This "magic" entry below simply matches all of the forbidden services for any system, spawns blockip, and then denies access.

 
 # Our default "ALL: ALL" which will cause that system to be blocked # permanently from all services (unless the start of this file later # is edited) # # NOTE: this entry must be in hosts.allow (not hosts.deny) and there also # must be a "ALL: ALL: deny" in hosts.deny for this script to work # and not have a momentary security hole; # blockip might be located elsewhere. ALL: ALL: \   spawn=((sleep 3;tail -10 /var/log/messages) | \   /usr/sbin/blockip "%h" "%a" "%d" "%c" "%u") &: deny 

14.2.6 The /etc/hosts.deny File

If you are using the version of the Cracker Trap that adds entries to the /etc/hosts.allow file to block future access, that file will not exist briefly while it is being updated. In this case, it is mandatory to have a rule in the /etc/hosts.deny file to block all services. The following is recommended.

 
 # If you have critical services that you cannot allow being disabled even # for less than a second then add an entry before here with ":allow" # NOTE that on some systems the mail program is /bin/mailx ALL: ALL: spawn=((sleep 3;tail -10 /var/log/messages) | \    /bin/Mail -s 'DENIEDdefault_%h/%d/%a/U=%u' \    bob@homesys.com bob@pentacorp.com) &:deny 

14.2.7 Trapping Server Attacks with Port Redirection

graphics/fourdangerlevel.gif

The Cracker Trap, as described just previously, will lock an attacker out of one's entire network if the Cracker Trap is running on the firewall rather than on an individual server or workstation. However, the attacker first must attack a port on the firewall itself to be trapped. A cracker may attack other systems first, depending on your IP address assignments and whether the cracker is attacking systems at ascending IP addresses or randomized addresses. A partial solution is to have the firewall be at the lowest available IP address. Still, that solution would not protect against crackers randomizing the attacked IP addresses.

The full solution is to combine port redirection with the Cracker Trap to allow it to be triggered even if the destination IP is a system behind the firewall. This is quite easy to do by using IP Chains' REDIRECT target. REDIRECT allows you to specify that incoming packets with a destination of other systems behind the firewall instead be redirected to a port on the firewall itself. Any reply packets from the firewall will be altered to appear to have come from the original destination IP. The hard part is deciding which ports to trap on each system. A balance must be struck between trapping as many crackers as possible and having a low rate of false positives due to innocent people making mistakes.

An example of a false positive trap you want to avoid is trapping https on a regular web server or trapping http on a secure-http-only server. If you trap attacks coming from inside your organization, you may not want to trap DNS requests sent to the firewall itself from your internal networks, as some people get confused when configuring their desktop systems between which IP is the router and which is the DNS server. Keep in mind that accidentally trapping someone is not the end of the world. If a user or someone else complains of being locked out and their trigger appears to be accidental, simply edit the /etc/rc.d/fw.trouble file and restart the firewall rules via the following or similar.

Note that we REDIRECT our entire externally visible IP address range. If we have a DMZ, its addresses will be covered as a subset of the externally visible range. The internal network's address range needs to be included with separate REDIRECTs only if it is IP Masqueraded (NAT'ed) as this would be a different range. This is true also for any other internal networks, such as any internal-only DMZ.

bash:

 
 cd /etc/rc.d ./rc.fw > foo 2>&1 more foo /bin/rm foo 

tcsh:

 
 cd /etc/rc.d ./rc.fw >&! foo more foo /bin/rm foo 

The bash shell script that follows, called redir_pre, will set up a few variables for either the IP Tables or IP Chains port redirection scripts. If you are using the techniques described in "Firewalls with IP Tables and DMZ" on page 446 or "Firewalls with IP Chains and DMZ" on page 514, these variables already will have been set up by the rc.vars or rc.fw scripts. For experimenting with the Cracker Trap's redirection you could skip the step of setting up the rc.fw script. Even if your firewall is wide open, when the Cracker Trap detects an attack, the interloper will be locked out. To activate port redirection from bash, use the dot command to source redir_pre with the invocation

 
 cd /etc/rc.d . ./redir_pre 

and then source either redir_iptables or redir_ipchains. These scripts are listed in the next two examples. The first is Cracker Trap variable setup, the second is the Cracker Trap redirection (DNAT) with IP Tables.

 
 #!/bin/sh # File is book/crackertrap/redir_pre # The following variables already should be defined in rc.vars or rc.fw #   (suggested values below listed) IFC=/sbin/ifconfig EXTIF="eth0" EXTIP="`$IFC $EXTIF|grep addr:|sed 's/.*addr:\([^ ]*\) .*/\1/'`" EXTMSK="`$IFC $EXTIF|grep Mask:|sed 's/.*Mask:\([^ ]*\) *.*/\1/'`" EXTNET=$EXTIP/$EXTMSK # Set DOMSK to "yes" if IP Masquerading INTNET else "no" DOMSK="yes" INTIF="eth1" INTIP="`$IFC $INTIF|grep addr:|sed 's/.*addr:\([^ ]*\) .*/\1/'`" INTMSK="`$IFC $INTIF|grep Mask:|sed 's/.*Mask:\([^ ]*\) *.*/\1/'`" INTNET=$INTIP/$INTMSK # Do not include services you offer on any system e.g., #   http, smtp, DNS in the following # squid, socks, kazaa, back_or, back_oru, trin00 defined in services on CD-ROM CRACKER_PORTS_TCP="22 ftp telnet sunrpc 137:139 445 squid socks kazaa back_or" CRACKER_PORTS_UDP="137:139 445 back_oru trin00" # End of items that should already have been defined # We can trap web attacks on the mail server, etc. MAILIP=198.4.155.7       # Set for your network HTTPIP=198.4.155.8       # Set for your network 

The redir_iptables bash shell script is given in the next example. It will activate IP Tables port redirection for the Cracker Trap. It can be sourced from the rc.fw script that was discussed in "Firewalls with IP Tables and DMZ" on page 446 by including the line

 
 . /etc/rc.d/redir_iptables 

near the end of the rc.fw script. It does no harm to redirect a port from the local system to itself. This conveniently allows us to route, say, the Kazaa port on our entire network to the Kazaa port on the firewall. If the Kazaa port on the firewall itself is attacked, the DNAT rule will have no effect, and the packet will be delivered directly to the Cracker Trap for processing.

To use the Cracker Trap redirection (DNAT) with IP Tables, use this script.

 
 #!/bin/sh # File is book/crackertrap/redir_iptables # May be in a different directory IPT=/sbin/iptables # Create a chain to log before redirecting #   since Tables is lacking a -l flag to log #   (CTR means Cracker Trap Redirection with logging) $IPT -t nat -X CTRl 2> /dev/null $IPT -t nat -N CTRl $IPT -t nat -A CTRl -j LOG --log-prefix "R:" --log-level err $IPT -t nat -A CTRl -j REDIRECT echo "Enabling Cracker Trap REDIRECT (DNAT) for IP Tables" echo -n "TCP port " for i in $CRACKER_PORTS_TCP; do         echo -n "$i "         $IPT -t nat -A PREROUTING -p TCP -d $EXTNET --dport $i -j CTRl         if [ "$DOMSK" = "yes" ] ; then                 $IPT -t nat -A PREROUTING -p TCP -d $INTNET --dport $i -j CTRl         fi done echo "" echo -n "UDP port " for i in $CRACKER_PORTS_UDP; do         echo -n "$i "         $IPT -t nat -A PREROUTING -p UDP -d $EXTNET --dport $i -j CTRl         if [ "$DOMSK" = "yes" ] ; then                 $IPT -t nat -A PREROUTING -p UDP -d $INTNET --dport $i -j CTRl         fi done echo "" echo "HTTP and SMTP IPs" if [ "$MAILIP" != "" -a "$MAILIP" != "$HTTPIP" ] ; then             # Trap attacks on the mail server's http port.         $IPT -t nat -A PREROUTING -p TCP -d $MAILIP --dport http -j CTRl fi if [ "$HTTPIP" != "" -a "$HTTPIP" != "$MAILIP" ] ; then             # Trap attacks on the web server's smtp port         $IPT -t nat -A PREROUTING -p TCP -d $HTTPIP --dport smtp -j CTRl fi 

The redir_ipchains bash shell script given in the next example will activate IP Chains port redirection for the Cracker Trap. It can be sourced from the rc.fw script that was discussed in "Firewalls with IP Chains and DMZ" on page 514 by including the line

 
 . /etc/rc.d/redir_ipchains 

near the end of the rc.fw script. It does no harm to redirect a port from the local system to itself.

Cracker Trap redirection with IP Chains should look like the following.

 
 #!/bin/sh # File is book/crackertrap/redir_ipchains # # Kernel needs CONFIG_IP_TRANSPARENT_PROXY for redirection # End of items that should already have been defined IPC=/sbin/ipchains echo "Enabling Cracker Trap REDIR for IP Chains" echo -n "TCP port " for i in $CRACKER_PORTS_TCP; do         echo -n "$i "         $IPC -A input -p TCP -d $EXTNET $i -j REDIRECT -l         $IPC -A input -p TCP -d $INTNET $i -j REDIRECT -l done echo "" echo -n "UDP port " for i in $CRACKER_PORTS_UDP; do         echo -n "$i "         $IPC -A input -p UDP -d $EXTNET $i -j REDIRECT -l         $IPC -A input -p UDP -d $INTNET $i -j REDIRECT -l done echo "" echo "HTTP and SMTP IPs" if [ "$MAILIP" != "" -a "$MAILIP" != "$HTTPIP" ] ; then                 # Trap attacks on the mail server's http port         $IPC -A input -p TCP -d $MAILIP http -j REDIRECT -l fi if [ "$HTTPIP" != "" -a "$HTTPIP" != "$MAILIP" ] ; then                 # Trap attacks on the web server's smtp port         $IPC -A input -p TCP -d $HTTPIP smtp -j REDIRECT -l fi 

14.2.8 Using PortSentry with the Cracker Trap

graphics/threedangerlevel.gif

The Cracker Trap and PortSentry will work independently on the same system just fine. However, with a one-line change to PortSentry's configuration file, it can be interfaced with the Cracker Trap for the following advantages:

  1. The Cracker Trap offers superior notification.

  2. Only one set of configuration files needs to be maintained for changing e-mail addresses, unblocking IPs, etc.

  3. The Cracker Trap will generate warning e-mail if a trusted system attacks a monitored port without blocking it; PortSentry does not offer this capability.

To integrate PortSentry with the Cracker Trap, edit the

 
 /usr/local/psionic/portsentry/portsentry.conf 

file. Because we will have the Cracker Trap do the blocking, we will have PortSentry run the external command but not generate IP Tables or IP Chains rules itself to block the attacker. We indicate this by setting the BLOCK_* variables thusly, where they appear in this configuration file:

 
 BLOCK_UDP="2" BLOCK_TCP="2" 

Then we specify the KILL_RUN_CMD, that portsentry will invoke when an attack is detected, to start blockip, the Cracker Trap script:

 
 KILL_RUN_CMD="(sleep 3;echo Portsentry $MODE$; \    tail -10 /var/log/messages)|/usr/sbin/blockip \    $TARGET$ $TARGET$ $PORT$ no_email Portsentry" 

Then, if PortSentry already is running it must be terminated and then restarted.


       
    Top


    Real World Linux Security Prentice Hall Ptr Open Source Technology Series
    Real World Linux Security Prentice Hall Ptr Open Source Technology Series
    ISBN: N/A
    EAN: N/A
    Year: 2002
    Pages: 260

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net