SpamAssassin p0f plugin catches bot spam
Most spam right now originates from compromised Windows desktop systems. Bot herders are more than happy to sell or rent a few thousand infected Windows home computers to spammers.
If only there was a way for a mail server to detect when a Windows XP box is the source of email.
Well, of course there is. Michael Zalewski’s passive fingerprinting tool p0f can detect various operating systems with reasonable accuracy. Unlike active tools like NMap that spray a host with packets to determine open ports and what OS it’s running, passive fingerprinters just sniff network traffic as it goes by. Tell p0f to listen to TCP port 25 on your inbound mail server and you’ll get a real-time guess of which OS is being used on systems as they connect to you.
A few months ago I set up a p0f daemon to collect OS information on a client’s mail servers, then matched that with email identified as spam with SpamAssassin. It turned out that around 70% of spam that made it though the blacklists and other spam defences was being blasted from Windows XP home computers. I was going to try writing a SpamAssassin plugin to use that info, but fortunately someone beat me to it.
The SpamAssassin P0f plugin created by Mingchun (Vincent) Li uses p0f to add OS detection and scoring to SpamAssassin . It’s easy to set up and has SpamAssassin rules for increasing the score of mail originating from Windows boxes, and also decreasing the score for mail from Linux and Unix.
The plugin has three components:
- A perl daemon that runs p0F and sends OS guesses out a UDP port on localhost
- A SpamAssassin plugin that gathers the guess and increases or decreases the SpamAssassin score of the corresponding message.
- A configuration file containing system parameters, rules and scores.
Installing on Ubuntu or Debian
As far as I know, there is no packaged version of this plugin for Ubuntu or Debian. There is a packaged version of p0f in Ubuntu Feisty and older releases, but it seems to be version 2.0.5. You can use that but for greatest accuracy you might want to install p0f from source.
Before compiling p0f, you’ll need libpcap and libpcap-dev packages installed. After that compiling p0f is as simple extracting the tarball to a temporary directory then doing the usual “make; make install”. The p0f binary will be placed in directory /usr/local/sbin.
To install the SpamAssassin p0f plugin, follow the instructions in the INSTALL file. For no particularly good reason I used the UDP method rather than the Unix socket method:
- Download file p0f-analyzer.pl to directory /usr/local/bin or /usr/local/sbin and make it executable.
- Download files p0f-analyzer.pm and p0f-analyzer.cf to directory /etc/mail/spamassassin and make sure they are readable.
- Start p0f-analyzer.pl running with “/path/to/script/p0f-analyzer.pl 2345″
- Restart spamd. You might want to start spamd in debug mode with the “-D” parameter just to make sure the plugin loaded and is working.
If you want to use this plugin permanently, you’ll need to create an init script to run p0f-analyzer.pl at system startup.
Scoring
By default the plugin increases the SpamAssassin score of messages originating from a Windows XP box by 1.0. Other Windows versions increase the score by 0.1, and unrecognized OSs increase the score by 0.8. Mail from Unix systems ( *BSD, Solaris, HP/UX and Tru64) decrease the SpamAssassin score by 1.0.
There is no score for Linux servers in the default scoring, so on our installation we modified file p0f-analyser.cf to add Linux to the regexp for Unix systems:
header L_P0F_Unix X-P0f-OS-Fingerprint =~ /^((Free|Open|Net)BSD)|Linux|Solaris|HP-UX|Tru64/
Security
One additional change we made was to force p0f drop root privileges and chroot itself. Protocol analyzers (e.g. Ethereal / Wireshark) have a history of buffer overflows that have allowed attackers to send malformed packets to gain root on the host system. I haven’t seen any published vulnerabilities for p0f, but it’s always a good idea to run all network software with limited privileges.
The file p0f-analyzer.pl also trusts the system PATH to find the p0f binary. That’s not so bad since the script does the right thing by running in Perl taint mode and explicitly setting the PATH, but it always makes me less nervous to use full paths in scripts run by root.
To change file p0f-analyzer.pl to use a full path and run p0f as an unprivileged user, change the statement around line 104 to read:
open($p0f, "/usr/sbin/p0f -u username -l 'tcp dst port 25' 2>&1 | ") or die "Can't fork: $!";
…where “username” is an unprivileged user ID on your system, ideally one dedicated for use by p0f that has no login shell and a locked password.
Accuracy
OS fingerprinting is never completely accurate, but p0f seems to do well identifying most Windows XP systems. NAT routers and certain firewalls can make some systems unidentifiable, however. Also, spam originating from a Windows bot but sent through an open SMTP relay would of course take on the TCP/IP characteristics of the relay, but bot herders don’t usually go to that trouble.
A really determined spammer could change the characteristics of the TCP stack similar to what IP Personality does in Linux… but it’s highly unlikely any bot herder would bother. Of course if enough mail servers and firewalls start using OS detection to thwart bots, they may start doing that someday.
We’ve only just started using the SpamAssassin p0f plugin on one of our mailers as a test so it’s too soon to say how effective this approach really is. The idea is extremely cool though… hats off to the author for developing the plugin. I’ll keep an eye on our spam stats and report back when there’s enough real-world data.
Related posts:
- Blocking image spam with FuzzyOCR
- Project Honeypot spam report
- Spam more profitable than extortion?
- A simple tool to track and control spammers
6 Responses to “SpamAssassin p0f plugin catches bot spam”:
July 30th, 2007 at 1:42 pm
I’ve been testing this as well, however, my results indicate that p0f would not really be viable as an anti-botnet spam prevention technique. I’m finding that all Win32 machines are essentially identified as “Windows 2000 SP4/Windows XP SP1+” inclusive of Windows 2003 Server machines. While I would certainly love to say “I won’t do business with a Win32 MTA” this isn’t acceptable and p0f’s ability to distinguish between 2000, XP, 2003, and Vista seem quite lacking (at least when listening on SMTP).
I’d be curious to see if you’ve found differently as my MTA sits behind an OpenWRT router so perhaps my results are munged.
July 30th, 2007 at 3:35 pm
@evilghost:
With p0f 2.0.8 it seems to differentiate between Windows 2003 and other versions fairly well. But it’s on a machine directly connected to the Internet.
Anything that alters the incoming packets can affect analysis. If your router is doing port forwarding (“DNAT”) to a mail server running an RFC1918 IP address, it could be affecting the accuracy… haven’t experimented with that myself though.
If you could get p0f and the p0f-analyzer script running on your router directly that might help with the accuracy. The p0f spamassassin plugin is able to connect to a remote p0f-analyzer.
July 31st, 2007 at 9:37 am
I’ll try that and let you know if the results are any better. I was using p0f 2.0.8 compiled from source, however, I am doing DNAT forwarding so that could be the issue. Thanks for the suggestion and article, for archive value I will update the comments section with my findings.
July 31st, 2007 at 10:54 am
Still no luck. I’m running tcpdump on the router with pcap redirection over netcat to a fifo on the mail server running p0f. Win32 hosts always show up as “Windows 2000 SP4, XP SP1+” or “Windows 2000 SP2+, XP SP1+ (seldom 98)”. DNAT mangling shouldn’t occur because I’m listening directly on the ppp0 (Static IP over DSL) interface and sending pcap directly to p0f via netcat.
Router:
tcpdump -s0 -U -w – -i ppp0 tcp dst port 25|nc 192.168.1.1 10026
Server:
nc -l -p 10026 > /netcat.fifo &
./p0f -s /netcat.fifo -l -N
I guess I’m struggling to see the usability of such a solution when the likelihood of false positives seems to be abundant, however, I’ll always applaud efforts to thwart spammers.
p0f is version 2.0.8
July 31st, 2007 at 5:19 pm
@evilghost:
Thanks for the update. That should give you a clean traffic capture (very nifty use of netcat, btw)
Could be the PPP over ethernet encapsulation is changing something, or something the upstream ISP is doing (traffic shaper?)
For comparison, I also get a huge number of connections identified as “Windows 2000 SPx, XP SP1+” but do also see “Windows XP SP1+, 2000 SP3″ and similar fairly frequently. This is on a DSL connection as well, it’s not encumbered by PPPoE.
According to the authors
, p0f is currently the most accurate of the open source passive fingerprinters, but perhaps you want to experiment with others like SinFP (http://www.gomor.org/cgi-bin/sinfp.pl
September 27th, 2007 at 11:34 am
[...] a SpamAssassin plugin to use that info, but fortunately someone beat me to it…. source: SpamAssassin p0f plugin catches bot spam, Security [...]