cipherdyne.org

Michael Rash, Security Researcher



Analyzing a Trac SPAM Attempt

Spam Attempts Through Trac One of the best web interfaces for visualizing Subversion repositories (as well as providing integrated project management and ticketing functionality) is the Trac Project, and all Cipherdyne software projects use it. With Trac's success, it also becomes a target for those that would try to subvert it for purposes such as creating spam. Because I deploy Trac with the Roadmap, Tickets, and Wiki features disabled, my deployment essentially does not accept user-generated content (like comments in tickets for example) for display. This minimizes my exposure to Trac spam, which has become a problem significant enough for various spam-fighting strategies to be developed such as configuring mod-security and plugin from the Trac project itself.

Even though my Trac deployment does not display user-generated content, there are still places where Trac accepts query strings from users, and spammers seem to try and use these fields for their own ends. Let's see if we can find a few examples. Trac web logs are informative, but sifting through huge logfiles can be tedious. Fortunately, simply sorting the logfiles by line length (and therefore by web request length) allows many suspicious web requests to bubble up to the top. Below is a simple perl script line_len.pl that sorts any ascii text file by line length, and precedes each printed line with the line length followed by the number of lines equal to that length. That is, not all lines are printed since the script is designed to handle large files - we want the unusually long lines to be printed but the many shorter lines (which represent the vast majority of legitimate web requests) to be summarized. This is an important feature considering that at this point there is over 2.5GB of log data specifically from my Trac server.

$ cat line_len.pl
#!/usr/bin/perl -w
#
# prints out a file sorted by longest lines
#
# $Id: index.html 1741 2008-07-05 15:30:00Z mbr $
#

use strict;

my %url       = ();
my %len_stats = ();
my $mlen = 0;
my $mnum = 0;

open F, "< $ARGV[0]" or die $!;
while (<F>) {
    my $len = length $_;
    $url{$len} = $_;
    $len_stats{$len}++;
    $mlen = $len if $mlen < $len;
    $mnum = $len_stats{$len}
        if $mnum < $len_stats{$len};
}
close F;

$mlen = length $mlen;
$mnum = length $mnum;

for my $len (sort {$b <=> $a} keys %url) {
    printf "[len: %${mlen}d, tot: %${mnum}d] %s",
            $len, $len_stats{$len}, $url{$len};
}

exit 0;
To illustrate how it works, below is the output of the line_len.pl script used against itself. Note that at the top of the output the more interesting code appears whereas the most uninteresting code (such as blank lines and lines that contain closing "}" characters) are summarized away at the bottom:
$ ./line_len.pl line_len.pl
[len: 51, tot: 1] # $Id: index.html 1741 2008-07-05 15:30:00Z mbr $
[len: 50, tot: 1]     printf "[len: %${mlen}d, tot: %${mnum}d] %s",
[len: 48, tot: 1]             $len, $len_stats{$len}, $url{$len};
[len: 44, tot: 1] # prints out a file sorted by longest lines
[len: 43, tot: 1] for my $len (sort {$b <=> $a} keys %url) {
[len: 37, tot: 1]         if $mnum < $len_stats{$len};
[len: 34, tot: 1]     $mlen = $len if $mlen < $len;
[len: 32, tot: 1] open F, "< $ARGV[0]" or die $!;
[len: 29, tot: 1]     $mnum = $len_stats{$len}
[len: 25, tot: 1]     my $len = length $_;
[len: 24, tot: 1]     $len_stats{$len}++;
[len: 22, tot: 2] $mnum = length $mnum;
[len: 21, tot: 1]     $url{$len} = $_;
[len: 20, tot: 2] my %len_stats = ();
[len: 19, tot: 1] #!/usr/bin/perl -w
[len: 14, tot: 3] while (<F>) {
[len: 12, tot: 1] use strict;
[len:  9, tot: 1] close F;
[len:  8, tot: 1] exit 0;
[len:  2, tot: 5] }
[len:  1, tot: 6] 
Now, let's execute the line_len.pl script against the trac_access_log file and look at one of the longest web requests. (The line_len.pl script was able to reduce the 12,000,000 web requests in my Trac logs to a total of 610 interesting lines.) This particular request is 888 characters long, but there were some other similar suspicious requests that had over 4,000 characters that are not displayed for brevity:
[len: 888, tot: 1] 195.250.160.37 - - [02/Mar/2008:00:30:17 \
-0500] "GET /trac/fwsnort/anydiff?new_path=%2Ffwsnort%2Ftags%2Ffwsnort\
-1.0.3%2Fsnort_rules%2Fweb-cgi.rules&old_path=%2Ffwsnort%2Ftags%2F\
fwsnort-1.0.3%2Fsnort_rules%2Fweb-cgi.rules&new_rev=http%3A%2F%2Ff\
1234.info%2Fnew5%2Findex.html%0Ahttp%3A%2F%2Fa1234.info%2Fnew4%2F\
map.html%0Ahttp%3A%2F%2Ff1234.info%2Fnew2%2Findex.html%0Ahttp%3A%2F\
%2Fs1234.info%2Fnew9%2Findex.html%0Ahttp%3A%2F%2Ff1234.info%2Fnew6%2F\
map.html%0A&old_rev=http%3A%2F%2Ff1234.info%2Fnew5%2Findex.html%0Ahttp\
%3A%2F%2Fa1234.info%2Fnew4%2Fmap.html%0Ahttp%3A%2F%2Ff1234.info%2Fnew2\
%2Findex.html%0Ahttp%3A%2F%2Fs1234.info%2Fnew9%2Findex.html%0Ahttp%3A\
%2F%2Ff1234.info%2Fnew6%2Fmap.html%0A HTTP/1.1" 200 3683 "-" \
"User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; \
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR \
1.1.4322; .NET CLR 2.0.50727; InfoPath.2)"
My guess is that the above request is a bot that is trying to do one two things: 1) force Trac to accept the content in the request (which contains a bunch of links to pages like "http://f1234.info/new/index.html" - note that I altered the domain so as to not legitimize the original content) and display it for other Trac users or to search engines, or 2) force Trac itself to generate web requests to the provided links (perhaps as a way to increase hit or referrer counts from domains - like mine - that are not affiliated with the spammer). Either way, the strategy is flawed because the request is against the Trac "anydiff" interface which doesn't accept user content other than svn revision numbers, and (at least in Trac-0.10.4) such requests do not cause Trac to issue any external DNS or web requests - I verified this with tcpdump on my Trac server after generating similar requests against it.

Still, in all of my Trac web logs, the most suspicious web requests are against the "anydiff" interface, and specifically against the "web-cgi.rules" file bundled within the fwsnort project. But, the requests never come from the same IP address, the "anydiff" spam attempts never hit any other link besides the web-cgi.rules page, and they started with regularity in March, 2008. This makes a stronger case for the activity coming from bot that is unable to infer that its activities are not actually working (no surprise there). Finally, I left the original IP address 195.250.160.37 of the web request above intact so that you can look for it in your own web logs. Although 195.250.160.37 is not listed in the Spamhaus DNSBL service, a rudimentary Google search indicates that 195.250.160.37 has been noticed before by other sites as a comment spammer.

SPA Talk at the Last HOPE Computer Security Conference

SPA talk at the Last HOPE conference Next month in NYC the final Hackers On Planet Earth (HOPE) conference will take place from July 18th through the 20th. I will be giving a talk there entitled "Port Knocking and Single Packet Authorization: Practical Deployments", and here is the abstract:

   Port Knocking and its big brother, Single Packet Authorization (SPA), can provide a robust additional layer of protection for services such as SSH, but there are many competing Port Knocking and SPA implementations. This talk will present practical usages of fwknop in Port Knocking and SPA modes, and discuss what works and what doesn't from a protocol perspective. Integration points for both iptables and ipfw firewalls on Linux and FreeBSD systems will be highlighted, and client-side support on Windows will be demonstrated. Finally, advanced functionality such as inbound NAT support for authenticated connections, sending SPA packets over the Tor anonymity network, and covert channel usages will be discussed. With SPA deployed, anyone scanning for a service with Nmap cannot even tell that it is listening; let alone target it with an exploit (zero-day or not).

A goal for the talk will be to start with the most basic port knocking deployment (a shared sequence of only one port) and build from there into encrypted port knocking sequences, and then move into the SPA realm with SPA packets encrypted with Rijndael and finally with GnuPG. Along the way security tradeoffs will be discussed. For example, a shared sequence of a single port allows an extremely simplistic port knocking implementation (so there is less risk of a vulnerability in the port knocking software itself), but then any casual port scan or stray packet that hits the shared port also qualifies as a valid port knock sequence. At the high end, SPA packets encrypted with GnuPG solve all sorts of difficulties with simple port knocking from a protocol perspective, but there is the slight expense of a more complicated implementation (although it is still a lot harder to target an SPA implementation with an exploit than a complicated TCP-based service that advertises its existence to the world under any basic port scan).

At the talk I will also release the next version (1.9.6) of fwknop.

If you are going to be at the HOPE conference, please stop by and say 'hello'. No Starch Press will also be at the conference so I'm sure I will hang out at their booth much of the time as well.

Software Release - gootrude-0.2

Gootrude queries Yahoo Gootrude-0.2 is available for download. This release changes the default search engine from Google to Yahoo because it appears that Yahoo's Terms of Service do not prohibit automated queries (although I'm not a lawyer). Gootrude retains the ability to query Google at your own risk if you so desire. As long as you use Gootrude as designed to collect search engine results only once per day with a limited number of search terms (say, 20 or less), it is unlikely to provoke a negative reaction from search engines. Over time, support for many additional search engines will be added to Gootrude so that search results can be trended from all sorts of different data sources.

Also, this post should really have announced Gootrude as a "search results trender" instead of a "search trender". The goal of the project is made clear in the README, and here is the complete ChangeLog, for the Gootrude-0.2 release:

  • Added support for querying Yahoo for search results and made this the default because Google's TOS does not technially allow automated queries. However, Gootrude continues to support querying Google for search results, and responsible use of Gootrude once per day with a limited set of search terms should most likely not be a cause for concern for Google. A new syntax of the searchterms.conf file allows search terms to express which search engine should be queried on an individual basis according to the following syntax (note the middle element): [Linux "highspeed firewalls"] [yahoo:count] [Linux_highspeed_firewalls.dat]
  • Changed the default USER_AGENT variable to "Gootrude <version>".
  • Added a percentage-based offset for the plot minimum and maximum ranges on the y-axis (with a default of 10% controlled by two new variables MIN_PERCENT_DIFF and MAX_PERCENT_DIFF). This value can also be set by the search terms themselves via an additional config element as follows (for a 20% offset instead for example): [yrange:20%/20%]
  • Increased SEARCH_TERM_DELAY to two seconds to be nicer to search engines.

Trending Low-Volume Google Searches - Introducing Gootrude

Introducing Gootrude UPDATE 06/16/08: 1) After making Slashdot today and reading the comments, I feel I should clarify a few things regarding this post. First, it was pointed out (quite rightly) that Gootrude trends the number of documents in Google's index that contain each search term, whereas Google Trends tracks the search volume associated with a search term. These are not the same thing. However, I would wager that they are related, though certainly not in some nice 1:1 correspondence. That is, if a relatively unique word - say, "myspace" - is mentioned within 100,000 web sites, then the number of times this word is used as a search term in Google will be higher than if "myspace" were mentioned in only 10 web sites just because it is exposed to many more people who would then be interested in all things "myspace". I would also wager that the reverse is true. So, if "myspace" is an extremely popular search term, then it will probably also appear in many more web sites around the Internet. Gootrude attempts to trend the number of hits a given search term returns in Google, and by the above reasoning, there is a loose correspondence between this and the number of times the term is searched for in Google. Perhaps this is not useful, but only time will tell after Gootrude is used by a lot of people. If you will allow the above interpretation, then the remainder of the post below makes sense.

2) It was pointed out that Gootrude violates the Google Terms of Service. After actually reading this document for the first time today, I think this is a correct interpretation, and if Google were to ask me to stop making Gootrude able to make web queries then I would comply with their request (and switch Gootrude to query Yahoo instead). However, let me just say that Gootrude is designed to be run once per day with a limited set of search terms (say, about 10). I personally make many more manual queries to Google every day than this with my web browser, and my usage of Gootrude cannot even remotely be interpreted as interfering with their server operations. I'm just interested in how Google (being the best search engine) views my open source projects. As a precautionary measure, I may switch Gootrude to query Yahoo by default anyway since their TOS does not seeem to prohibit this. Also, I would like to mention that other projects seem to make use of Google services in ways that may be questionable in view of the Google TOS (see the Gmail Filesystem for example) but Google seems to allow it. Google probably derives more benefits from open discussions that such projects foster than would justify shutting them down.

Now for the original post:

The Google Trends project allows you to input search terms like "Myspace", "2008 election", or "Linux", and see how Google tracks how popular these search terms are over time. The resulting graphs can be quite interesting - spikes in search volume can sometimes be correlated against particular news articles and world events, and the Google Trends interface points these out.

This is a handy tool, but there are many search terms that Google Trends does not display any results for. Such terms (such as "Linux Firewalls" - with the quotes) have insufficient search volumes to display graphs according to the error message that Google Trends generates. Fair enough. I suppose that Google sets an internal threshold on search volume, and this threshold could be set for reasons that range anywhere from Google Trends is still experimental to Google not wanting to provide data on how it builds its massive search index for emerging search terms. Either way, I would like a way to see search term trends that Google doesn't currently make available to me.

Although I'm an open source developer and author, search terms related to my projects are not popular enough yet to be displayed by Google Trends. So, I had to roll my own trending mechanism, and this blog post announces the release of a new open source tool Gootrude (see the quick start, source code, and download links) that I wrote to do just this. The basic strategy is to take a collection of search terms defined by the user, automatically query Google for the number of results associated with each of these search terms (this is displayed by Google when doing a web search), and graph these numbers over time with Gnuplot. At this point let me state up front that Gootrude only makes use of data that Google freely provides to everyone with normal web searches, and is meant to be run once per day (so as to not be a pest in terms of the numbers of queries it makes). As an example, if you type in the word "security" into the Google web interface, it will return a string like "Results 1 - 10 of about 1,010,000,000". The "1,010,000,000" number is collected by Gootrude and stored in a file along with the current time.

For the past year, I have sent a set of search terms through Google once per day with Gootrude and the results are displayed below. Visible within the data returned from Google are strange oscillations that vary quite a bit more than I would have expected, and also evidence for what happens when a large site (like linux.com) posts an article about a Cipherdyne project.

First, below is the graph of the fairly unique word "cipherdyne" since late June 2007. The filled-in red curve is the absolute number of search results (taken each day around 1am), and the green line is the 10-day moving average. Gootrude plot of cipherdyne search term As you can see, at the beginning of the graph around July 1st Google steadily shows about 28,000 results for "cipherdyne", but towards the end of July this dips to well below 20,000 only to rebound in August to about 30,000. Then, beginning around March 1st, 2008 the results shoot up to over 100,000 briefly and then back to around 70,000 in May. How does one interpret this data? It seems unlikely that these fluctuations can be entirely explained by "actual" day-by-day changes in how external sites reference the term "cipherdyne" - there must be some index updating component that is internal to Google at work here, and we'll see a better example of this below.

Now, here is the graph of the search term "gpgdir": Gootrude plot of gpgdir search term The most obvious feature of the gpgdir graph above is the large spike to around 60,000 results around May 1st. It turns out that an article was posted to linux.com on the 24th of April, so given that "gpgdir" is not a common word, the spike seems nicely correlated with the posting of the article as it got bounced around the Internet and blogosphere. A more interesting feature perhaps is the sharp cyclic oscillation between July and December 2007. During this time, search results for gpgdir bounced from 1,000 to around 10,000 and back again several times, and the transition each time was fast - making the jump to 10,000 over the course of two days and then stabilizing for about 10 days or so and then back down to 1,000. It is almost as though Google was trying to establish the proper order of magnitude for "gpgdir" search results during this time via a sort of step function.

Finally here is the graph of "single packet authorization": Gootrude plot of single packet authorization Again, we see a dramatic spike in search results - from around 5,000 to well over 50,000 and settling down to about 10,000 around the beginning of June. Although there has been some activity related to SPA in the Ubuntu forums and also in the Gentoo forums, if this caused Google to report the search results as over 50,000 why did this number return so precipitously back to around 10,000? The links have not gone away, but they were probably mentioned on other referencing sites and then moved to less important pages over time on those sites. Perhaps Google is trying to find the appropriate steady state for its search results, and there are many factors that Google takes into account that are not available to the public.

There are lots of unanswered questions this sort of data brings to mind:

  • All of the data for the above graphs was collected from a single Linux system. How different would the results be if several systems in different geographic locations collected the data and the average for each data point was used instead?
  • Each data point was collected around 1am every morning. If the data collection time were, say, 1pm, would the results have been significantly different?
  • What is the "optimal" time scale for the moving average? Given that Google's own Trends interface seems to show search results on the macro level, would a much longer moving average than 10 days - perhaps on the order of several weeks - be a more accurate reflection of search popularity?
One thing is clear - getting search results that are meaningful is much easier with unusual search terms. With the posting of this blog entry, the term "Gootrude" should evolve nicely within Google results, and the graph of these results will be updated daily on the main Gootrude page so you can see this evolution as it unfolds.

In closing, I would like to mention that Gootrude is just getting started, so there are lots of enhancements that need to be made. Some of the most important features to develop are:

  • Integration with the Google Charts API.
  • Development of an online web portal for Gootrude so that users don't have to have their own infrastructure to run Gootrude.
  • Ability to import search data from different Gootrude collection systems.
  • Add support for data collected from additional search engines.
If you are an open source developer and would like to contribute, see the TODO file for an updated list of development tasks, or send me an email (mbr[at]cipherdyne[dot]org). Also, if you have any ideas or feedback on why some of the graphs above look the way they do in the context of how Google builds its index, please email me.

Finally, here are a few additional graphs of search terms over the past year: Gootrude plot of fwsnort Gootrude plot of michael rash Gootrude plot of Linux Firewalls Attack Detection Gootrude plot of single packet authentication Gootrude plot of iptables attack visualization

Three software releases - psad, fwknop, gpgdir

Three software releases The following releases of the Cipherdyne security projects are now available: psad-2.1.3, fwknop-1.9.5, and gpgdir-1.9.1. The motivation for a group release stems from the need to make similar changes to the fwknop and gpgdir projects to update to version 2.11 of the Class::MethodMaker perl module from CPAN - a dependency of GnuPG::Interface. This version fixes a build error under recent versions of perl (such as perl-5.10.0) which are distributed on systems like Fedora 9. Also, for both fwknop and gpgdir, thanks to a suggestion made by Jean-Denis Girard on the fwknop mailing list, the default locale has been set to "C" via the LC_ALL environmental variable so that GnuPG output can be properly interpreted even on systems where a different locale is used. The locale can be manually set or not used at all with two new command line arguments --locale <str> and --no-locale respectively. On another note, Kevin Hilton has written an excellent how-to for fwknop on Ubuntu systems.

For psad, it was time to make a new release after it became necessary to update the whois client so that IP addresses such as 116.125.35.98 (which was scanning a psad user) could be properly identified with whois records. In addition, psad was updated to parse syslog files directly for iptables log messages instead of requiring reconfiguration of the syslog daemon to write kern.info messages to the /var/lib/psad/psadfifo named pipe. This simplifies the proper installation of psad, and is now a default setting. Although there is a slight performance penalty since psad now parses all messages that are written to the /var/log/messages file (this is the default path), it should not be noticeable on most systems. Further, the old behavior of using the named pipe can be restored via the ENABLE_SYSLOG_FILE variable in the /etc/psad/psad.conf file.

Finally, Franck Joncourt has made excellent progress in developing Debian packages for the IPTables::ChainMgr and IPTables::Parse modules, and he is also close to a Debian package for the fwknop project.

The complete change logs for these new releases can be found as follows: psad-2.1.3, fwknop-1.9.5, and gpgdir-1.9.1

Single Packet Authorization with Port Randomization

Single Packet Authorization with Port Randomization After two months of development, the 1.9.4 release of fwknop is available for download. This release introduces new functionality that has implications for hardening both fwknop SPA communications and the follow-on connections that client programs make (such as SSH). Specifically, the 1.9.4 release adds two port randomization options to 1) send the SPA packet over a random port between 10,000 and 65,535 (requires updating the default PCAP_FILTER variable on the fwknopd server side), and 2) select a random port that is used as the destination port in a NAT operation on the fwknopd server system. These two options can be used individually or together, and are enabled with two new command line options, --rand-port and --NAT-rand-port respectively, to the fwknop client (see examples below).

The inspiration for adding this functionality came from a post to the "Documentation, Tips & Tricks". Gentoo forum, and I have credited John Brendler with the idea. In response to John's post, I would like to mention however that all Port Knocking / Single Packet Authorization implementations suffer from "piggy-back exploits", including those that select random ports for SPA communications or for NAT operations against follow-on sessions. A "piggy-back exploit" is where an attacker takes advantage of the fact that a firewall rule inserted by a PK/SPA system accepts a connection from an IP address to a destination port specified by the SPA packet(s). So, if the attacker can spoof packets from this source IP, or if the attacker happens to be on the same internal network as the SPA client (and hence sends connections out through the same NAT device), then the firewall rule will accept these packets just as though they originated from the legitimate SPA client system. If an attacker is in a privileged position and can sniff the legitimate session as it is initiated, then one can envision an automated attack that spoofs packets from the same source IP and directs them at the same service. Further, such an "attack" can be made just by watching outgoing connections without paying any attention whatsoever to whether or not a set of SPA packets are sent first - it doesn't matter if the real connection is made to a random translated port on the SPA system; the attacker can see this port in the real connection itself.

Now, should you be concerned about such a piggy-back attack? Not really. First, if the attacker is not going through the same NAT device as the real connection, then any response to a spoofed packet will go back to the spoofed source - not back to the attacker. So, for TCP connections, unless the attacker can effectively perform a sequence prediction attack an existing connection (and even then that is of little use against an encrypted application layer protocol such as SSH), this is not very effective. Second, even if an attacker is behind the same NAT device as the SPA client, just being able to access the targeted service over TCP/IP does not imply an automatic vulnerability; SPA is an additive measure to whatever existing security mechanisms are already in place (barring a vulnerability in libpcap itself in the SPA server for example). Third, there are an awful lot of networks out there to which an attacker will not have such privileged access, and therefore not be in a position able to sniff anything useful. Forth, fwknop minimizes the opportunity for an attacker to conduct a piggy-back attack by maintaining a small window of time (30 seconds by default) for any new firewall rules after receiving a valid SPA packet. By using a connection tracking mechanism built into iptables or ipfw, any connection established during the accept window is allowed to remain open but all attempts to create a new connection must first preceeded with a new SPA packet in order to gain access.

Finally, although port randomization is an enhancement, fwknop has had the ability for a long time to allow the user to select the destination port for SPA packets with the --Server-port argument as well as the destination port for a NAT'd connection to an internal system. Hence, fwknop SPA packets are not always sent over udp/62201. But, I agree that it is useful to add the port randomization features that John Brendler suggested, and this is why I've implemented them in fwknop. Randomizing the SPA destination port along with the destination port of the follow-on connection makes traffic analysis more difficult.

Now, let us see the new --rand-port and --NAT-rand-port options in a practical example. We'll assume that the fwknopd server is at hostname spaserver with IP 11.1.1.1, and the fwknop client runs on the spaclient system with IP 12.2.2.2. We ultimately want to gain access to SSHD on the spaserver system, and we assume that iptables is configured in a default-drop stance for all attempts to communicate with SSHD. Also, there is no requirement to necessarily attempt to gain access only to an SSHD instance running on an internal server via a forwarded port - the iptables PREROUTING chain can forward a port to a local socket as well (based on a routing calculation for the destination IP), and on the fwknop client command line we use the --NAT-local argument for this.

Because the --rand-port option sends the SPA packet over a random destination port, we first need to set the PCAP_FILTER variable as follows in the /etc/fwknop/fwknop.conf file:
[spaserver]# vi /etc/fwknop/fwknop.conf
PCAP_FILTER                 udp dst portrange 10000-65535;

[spaserver]# /etc/init.d/fwknop restart
[+] knopwatchd is running (pid: 17584), stopping daemon
[+] knoptm is running (pid: 17582), stopping daemon
[+] fwknopd is running (pid: 17580), stopping daemon
Starting the fwknop daemons.
With the fwknopd server up and running, we now use the fwknop client to gain access to SSHD on the spaserver system via a randomly selected NAT'd port (and we show that SSHD is never accessible over the standard TCP port 22 even from the spaclient system):
[spaclient]$ nmap -sT -n -P0 -p 22 11.1.1.1

Starting Nmap 4.20 ( http://insecure.org ) at 2008-06-02 01:48 EDT
Interesting ports on 11.1.1.1:
PORT   STATE    SERVICE
22/tcp filtered ssh

Nmap finished: 1 IP address (1 host up) scanned in 12.017 seconds

[spaclient]$  fwknop -A tcp/22 --NAT-local --NAT-rand-port \
--rand-port -R -D 11.1.1.1

[+] Starting fwknop client (SPA mode)...
[+] Requesting NAT access for randomized port: 16791
    Resolving external IP via: http://www.whatismyip.org/
    Got external address: 12.2.2.2

[+] Enter an encryption key. This key must match a key in the file
    /etc/fwknop/access.conf on the remote system.

Encryption Key:

[+] Building encrypted Single Packet Authorization (SPA) message...
[+] Packet fields:

        Random data:    4846125760033285
        Username:       mbr
        Timestamp:      1212386108
        Version:        1.9.4
        Type:           5 (Local NAT access mode)
        Access:         12.2.2.2,tcp/22
        NAT access:     11.1.1.1,16791
        SHA256 digest:  ZyWG+nRGYMfWFssJuOy7bhGmJHpHia6T1igaNnVVhqI

[+] Sending 206 byte message to 11.1.1.1 over udp/52949...
    Requesting NAT access to tcp/22 on 11.1.1.1 via port 16791

[spaclient]$  ssh -p 16791 mbr@11.1.1.1
mbr@11.1.1.1's password:
[spaserver]$
The above output shows that the client system indeed has access to the spaserver system via TCP port 16791, which is forwarded to the local SSH daemon. In the /var/log/messages file, fwknopd has written the following messages to syslog:
[spaserver]# tail /var/log/messages
Jun  2 01:54:16 spaserver fwknopd: received valid Rijndael encrypted \
packet from: 12.2.2.2, remote user: mbr, client version: 1.9.4 (SOURCE \
line num: 151)
Jun  2 01:54:17 spaserver fwknopd: add FWKNOP_PREROUTING 12.2.2.2 \
-> 11.1.1.1(tcp/16791 to 22) DNAT rule 30 sec
Jun  2 01:54:17 spaserver fwknopd: add FWKNOP_INPUT 12.2.2.2 -> \
0.0.0.0/0(tcp/22) ACCEPT rule 30 sec
Jun  2 01:54:58 spaserver fwknop(knoptm): removed iptables \
FWKNOP_PREROUTING DNAT rule for 12.2.2.2 -> 11.1.1.1(tcp/22), 30 \
sec timeout exceeded
Jun  2 01:55:11 spaserver fwknop(knoptm): removed iptables \
FWKNOP_INPUT ACCEPT rule for 12.2.2.2 -> 0.0.0.0/0(tcp/22), 30 sec \
timeout exceeded
In closing, here is an abbreviated version (the randomization options are not duplicated here) of the fwknop-1.9.4 ChangeLog:

  • Added the ability to specify the port that SPA packets are sent over with the fwknop client by using the syntax "<host|IP>:<port>". So, for example, to have the client send an SPA packet to 11.1.1.1 over UDP port 12345 (instead of the default of 62201), one could use the following command:

    $ fwknop -A tcp/22 -R -D 11.1.1.1:12345

  • Bugfix to add a check for "keep-state" in ipfw policies in addition to the existing "check-state" check (noticed by Sebastien Jeanquier).
  • Updated the install.pl script to try to determine the OS type as early as possible during the install process.
  • Added the MIN_SPA_PKT_LEN variable with 160 (bytes) as the default. This allows fwknopd to ignore packets that are not at least this many bytes (including packet headers) before any decryption attempt is made.
  • Added --time-offset-plus and --time-offset-minus args to the fwknop client command line. This allows the time stamp within an SPA packet to be influenced without setting the system clock (which normal users cannot usually do). This is useful for when the client and server systems have clocks that are out of sync.
  • Bugfix on Ubuntu systems to make sure that the fwknop init script is installed with a priority of 99 instead of 20 - this puts fwknop as late as possible within the boot sequence so that the system is ready to run fwknop.
  • Bugfix to not open ports that are not specifically requested in an SPA packet even if those ports are listed in the OPEN_PORTS variable in the access.conf file.
  • Updated to version 5.47 of the Digest::SHA module.
  • Updated to version 0.7 of the IPTables::ChainMgr module (includes perldoc documentation).
  • Updated to version 0.6 of the IPTables::Parse module (includes perldoc documentation).
  • Added NAT, port randomization, and and time offset option discussions to fwknop(8) man page.

Software Release - gpgdir-1.9

gpgdir-1.9 released The 1.9 release of gpgdir is ready for download. This release introduces minor fixes to change the --Obfuscate file format and adds process locking against multiple instances of gpgdir from operating against the same directory.

On a side note, Ben Martin wrote an article on gpgdir entitled "Protecting directory trees with gpgdir" for linux.com. Ben emphasizes using the gpgdir --Wipe option to securely delete files from the filesystem after they are encrypted with GnuPG, and I agree with this. In addition, there is nothing that prevents gpgdir from being used in conjunction with an encrypted filesystem such as Cryptmount to achieve additional protections for directory structures (which gpgdir does not alter).

Here is the complete ChangeLog: for the 1.9 release:
  • Changed --Obfuscate-filenames format to not include the gpgdir PID. This allows directories to be encrypted/decrypted under -O multiple times without creating new filenames (which would pollute encrypted directories under rsync to other systems). The new -O encrypted filename format is just "gpgdir_<num>.gpg".
  • Added PID locking against directories so that multiple gpgdir processes cannot operate against the same top-level directory simultaneously. This is useful for users that typically operate with multiple shells and might launch gpgdir from any of them.

linux.com Article on fwknop

At linux.com Bob Currier has written a featured article on fwknop. He gives a good overview of how Single Packet Authorization (SPA) is different from port knocking, and illustrates how to use fwknop to harden SSH communications. Here is a quote from the article:

   Single packet authorization distills the essence of the port knocking concept down to a single packet. Rather than sending a series of packets to predefined ports, single packet authorization encodes the "knock" within the payload of one packet. Once a proper key has been received, SPA applications modify firewall rules to allow access to the authenticated host. We'll examine how this is accomplished by installing and testing the Firewall KNock Operator, better known as fwknop.

There are several comments attached to the article from interested users, and additional discussion of both port knocking and SPA topics can be found at Sebastien Jeanquier's online forum.

Site Update - WordPress Theme without Running WordPress

WordPress site WordPress has a loyal following in the blogosphere and is used to power thousands of websites and blogs, and several books have been written about it. A compelling measure of WordPress popularity is the number of downloadable themes that can provide an easily deployed and consistent look and feel to WordPress sites. So, when I was looking to update the presentation of the cipherdyne.org site, it seemed a natural step to consider a WordPress theme.
I've updated cipherdyne.org to use a slightly modified version of the Daleri Selection (v1.0) Theme by Andreas Viklund, but with a twist: I don't run actually Word Press. All of that PHP code and MySQL database backend is throwing a lot of complex code (and associated potential security vulnerabilities) at a problem that (in my case) can be solved in a simpler way. That is, I just want to provide an outlet for my software and publications, and maintain a blog for my corner of the security technology landscape. For this, I just need a themed website in plain HTML and CSS along with RSS and Atom feeds, and I need an effective way to manage all of the pages and create new blog posts. This is where perl, rsync, and subversion comes in.
The cipherdyne.org website and blog is managed by a set of custom perl scripts that perform each the following tasks:
  • Provide a way to create new blog posts and link them into the cipherdyne.org blog hierarchy. For example, the forward and backward links at the end of each post (such as this one) are auto-generated based on the posting date, and the permanent blog links are created from each post by the blog post title. The number of blog posts is summarized by date and organized into categories that can be browsed via the blog archives, and updates to the RSS and Atom feeds are automatically generated.
  • Validate HTML and XML page structure. This is exceeding easy through the use of the perl XML::Simple module. But, using the W3C HTML validator is more thorough, so I periodically use it as well to spot check various pages on cipherdyne.org.
  • Validate software release MD5 digests and GnuPG signatures (see the fwknop download page for example), and automatically correct if any digest is invalid.
  • Search through the entire cipherdyne.org website and flag any broken links (parsing the output of a recursive wget against the cipherdyne.org staging server make this easy).
  • Send blog pings out via the XMLRPC::Lite module to various blog aggregation services such as FeedBurner and Technorati.
  • Drive the entire cipherdyne.org site via Subversion for source control, and deploy with rsync to separate staging and production servers. When it comes to deploying a more complex piece of software for visualizing changes to the source code for any of the cipherdyne.org projects, my first choice is Trac, but when it comes to the main cipherdyne.org site, a set of HTML pages maintained by a consistent WordPress theme is sufficient.

Hakin9 March 2008 Issue

Hakin9 March 2008 Issue The March issue of Hakin9 Magazine contains some noteworthy articles and interviews. First is an article written by Ryan Maple entitled "Best Practices for Secure Shell" which discusses various security measures that an administrator can use to heighten the security of SSH. These measures include (among others) forcing the usage of SSH protocol version 2, restricting the address (via the ListenAddress variable) that SSHD binds to from the default of 0.0.0.0, using tcpwrappers, and configuring SSHD to listen on a port other than tcp/22. Covering Single Packet Authorization would have been difficult to include in the same article, but a reference is made to another online article Knock, Knock, Knockin' on EnGarde's Door (with FWKNOP) that does discuss protecting SSH with SPA. Next, is Matt Jonkman's fifth part in his series "Writing IPS Rules". This article covers the byte_test keyword in the Snort rules language and how to use it to write signatures against length encoded protocols. In particular, Matt illustrates using byte_test to look for specific byte values at particular offsets derived from data within the DHCP protocol. The offsets themselves are determined by the data on the wire and therefore cannot simply be hard coded within a signature beforehand. For those who are interested in the latest IDS signatures from Matt, he has updated the online home of the Bleeding Edge Snort ruleset to Emerging Threats. Finally, both Marcus Ranum and Richard Bejtlich were interviewed for the March issue. I would like to see Hakin9 do a more in-depth interview of Bejtlich though since he always has an insightful perspective on computer security - particularly as demonstrated in his book The Tao of Network Security Monitoring.