Port Knocking
Problem
You have a service and it has failed. You need to restart it without logging in.
Solution
Use port knocking. Use the unixsock output plug-in to send alerts to a small program that keeps track of the ports accessed. If the "knock" is successful, the program will run the command required to reset the service.
|
Discussion
Port knocking takes the concept of a "secret knock" into the computer age. You select a certain range of ports to be accessed in a certain order, perhaps even with certain flags set on the packets sent. Snort detects each packet and then, using the unixsock output plug-in, logs the order that they come in and, if correct, runs a command of your choice to restart your service.
This need not be used only for restarting services. You could use port knocking to further secure your computer, by having no services running at all until the combination of ports is sent, and then start an SSH daemon on an unusual port.
You should ensure that you create a selection of ports that are sufficiently random that they are unlikely to be activated by accident by a randomized port scanner; for this example, we are going to use only four to simplify the program.
First, you need to set up an instance of Snort to recognize your knocking. A simple snort.conf file that includes the unixsock plug-in and one rule file is more than enough. The example rule file is as follows:
# Snort Portknocking Rules alert tcp any any -> 192.168.0.8 4 (msg: "Port Knock 1";) alert tcp any any -> 192.168.0.8 8 (msg: "Port Knock 2";) alert tcp any any -> 192.168.0.8 13 (msg: "Port Knock 3";) alert tcp any any -> 192.168.0.8 24 (msg: "Port Knock 4";)
At this point if you wanted to make this more secure still, you should add other criteria, such as a specific source IP, specific source port, or flags. When we get to the knocking program, we will be using hping which can spoof all these details, so don't feel that the IP will restrict you to doing this only from a single machine; look at it more as another level of secret knowledge that would pose more of a problem to someone seeking to hijack your connection.
The unixsock alerting program from Recipe 2.n has been modified to count the knocks and ensure that they come in the correct order. There are probably a million and one ways of programming this; the example is simple, but it works.
#!/usr/bin/perl use IO::Socket; $TEMPLATE = "A256 A*"; unlink "/var/log/snort/snort_alert"; $SIG{TERM} = $SIG{INT} = sub { exit 0 }; my $data; my $client = IO::Socket::UNIX->new(Type => SOCK_DGRAM, Local => "/var/log/snort/snort_alert") or die "Socket: $@"; print STDOUT "Socket Open ... "; while ( true ) { recv($client,$data,1024,0); @FIELDS = unpack($TEMPLATE, $data); # The Knocking Code starts here... if (@FIELDS[0] =~ /^Port Knock 1/){ $flag_one = 1; $flag_two = $flag_three = 0; } elsif ($flag_one = = 1 && @FIELDS[0] =~ /^Port Knock 2/){ $flag_two = 1; $flag_one = $flag_three = 0; } elsif ($flag_two = = 1 && @FIELDS[0] =~ /^Port Knock 3/){ $flag_three = 1; $flag_one = $flag_two = 0; } elsif ($flag_three = = 1 && @FIELDS[0] =~ /^Port Knock 4/){ $flag_one = $flag_two = $flag_three = 0; # Enter the Knock action here. print "Who's there ? "; } # and ends here ... else { $flag_one = $flag_two = $flag_three = 0; } } END {unlink "/var/log/snort/snort_alert";}
The code simply loops until the alerts come in the right order (resetting if the order is wrong at any point ), and then, in this case, responds by asking "Who's there ?" At this point, you would enter the code you wish to execute.
The knocker itself is quite easy: you could either write your own program that sends a single packet to a specified port, or you could use one of the hundreds of packet creation tools available on the Web. Using other programs such as Telnet to access a port won't work well, since more than one packet often is sent, so the port knock criteria will fail.
For this example, we are going to use hping. Hping is available for download from http://www.hping.org; installation is easy and is just a matter of decompressing the source by typing:
tar xvZf hping2-rc3.tar.gz
Changing into the hping directory, running the configure program, and then making as root, install the source:
cd hping2-rc3 ./configure make su make install
Hping is hugely powerful and can create packets to pretty much any criteria, but in this case, we are simply going to send a single packet to the specified port on the destination IP.
hping 192.168.0.8 -p 4 -c 1
This will send one packet (-c 1) to port 4 (-p 4) on IP 192.168.0.8. This is our first knock. There is no time criteria set in the listening program, so you could enter each line by hand each time if you wish, but it makes much more sense to create a shell script to run it. The following basic script will send a single packet to the right ports in the right order.
#!/bin/sh hping 192.168.0.8 -p 4 -c 1 hping 192.168.0.8 -p 8 -c 1 hping 192.168.0.8 -p 13 -c 1 hping 192.168.0.8 -p 24 -c 1
There are a number of ways you could elaborate on this simple mechanism. You could add a time element so that all ports are required within a certain time frame; you could use the listening script to restart Snort as well with a new set of rules, so that the port sequence changes each time; or you could include requirements as to the contents of the packets. You can make this as simple or as complex as you need, and it can be used to call any external script that you care to create.
See Also
Christiansen, Tom and Nathan Torkington. Perl Cookbook. Sebastopol, CA: O'Reilly, 2003.
hping user manual (http://www.hping.org/)
Obfuscating IP Addresses
|