Sunday, November 11, 2007

Checking If A Mail Server Is An Open Relay Using Perl and Berkeley Sockets!

SPAM is common enough nowadays that you can probably find some version of this basic check somewhere on the web (probably a lot of places), but our intent here is to take a look at what's behind the pretty looking web pages and/or software, used in determining whether or not the mail server you're runnning (or any mail server, for that matter) is an open relay.

Below is a little script I put together using Perl (and its Socket module - based on Berkeley Sockets) that will do this check for you. In a future post, we'll explore Berkeley Sockets programming at a more granular level (as it's far outside the scope of this simple blog post), but for now check out the script below:


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/bin/perl

#
# 2007 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

use Socket;

$host = "whateverMailServerYouWantToCheck.xyz.com";
$relaydomain = "xyz.com";
$sender = "eggi@noOneWillEverPickThisDomain.com";
$adressee = "info@hopefullyThisMailServerIsNotInTheDomainWereTesting.zyx.com";
$protocol = "tcp";
$port = 25;

if ( $port =~ /\D/) {
$port = getservbyname($port, $protocol);
}
unless ( $port ) {
print "No port : ${port}/$protocol\n";
}
$inet_address = inet_aton($host) || die "No host: ${host}!";
$port_address = sockaddr_in($port, $inet_address);
$protocol_num = getprotobyname('$protocol');
socket(SOCKET, PF_INET, SOCK_STREAM, $protocol_num) || die "Socket: $!";
connect(SOCKET, $port_address) || die "Socket $!";
send(SOCKET, $line, 'SOCK_STREAM') == length($line) || die "Cannot Send Message!: $!\n";
print SOCKET "HELO $relaydomain\n";
print SOCKET "MAIL From: $sender\n";
print SOCKET "RCPT To: $adressee\n";
print SOCKET "DATA\n";
print SOCKET "Subject: If this didn't get rejected - you may be running an open relay!\n";
print SOCKET ".\n";
print SOCKET "quit\n";
close(SOCKET) || die "Close $!";
exit(0);


At a very basic level, there are just a few things (covered in the script above) that you need to do to quickly determine if a mail server is an open relay. First, make sure you're sending from a different domain than the mail server's domain. Second, connect to the mail server and attempt to send mail to another (different) domain. If this works, the mail server is acting as an open relay.

Of course, like I said, it might be easier to just go to any number of sites on the web and have that free service do the check for you. But, in any event, this way can be more fun and you can customize it to do whatever (hopefully, good and decent) things you want it to :)

, Mike