Good morning/afternoon/evening,
For this Saturday's post, I thought I'd put together another bash script on Solaris Unix using snoop. The last time we did this it was to grab cleartext logins and passwords. This time, I thought we'd look at email. SMTP, port 25, in particular.
Snooping through someone's physical mail (delivered to their home) would be a federal offense, but (to my knowledge) if you're a Unix or Linux administrator and have to analyze network traffic and interrogate packets at your place of work, there's almost no way you can avoid getting into other people's business. Most company's have an HR policy that your email is considered private and gaining access to another user's email, without their consent, is blah, blah, blah leading up to, and including termination. Of course, five minutes after said employee leaves the company, you're probably going to be called upon to provide just that sort of access (or the information gained by that access) to the same department that demanded you never ever do that sort of thing in the first place.
That being said, I'm pretty sure the law at this point is that a company can do whatever it wants with any data you create or use on their systems. If they need to, or want to, they can look at the email you send out and receive and where you go on the web, etc. I'm not sure why corporate America insists on assuring the average employee that their company-owned data is "personal and confidential" when all that email and web traffic has to be scanned by 15 security appliances before it can be allowed to enter or leave the company network? You can't block access to a website (even to, say, everyone in the company) without having to examine where every employee is going when they surf the web, etc. It probably makes for some yawn-inspiring legal battles ;)
Anyway, for the sake of today's argument, you're the root user (or someone with sufficient privilege to run snoop on Solaris Unix) and you're inspecting network traffic on an interface on a machine for a semi-legitimate reason.
If you need to check mail traffic, the simplest thing to do is snoop on port 25. This is the SMTP port and is used for sending and receiving email (you can also look at the POP and IMAP ports, but we'll wrap that into the everything's-pretty-much-all-the-same-when-you-get-right-down-to-it closing). You can get a good deal of information just running a straight-up snoop, like so:
host # snoop -o output_file port 25 <--- This snoop will use the default network interface, only capture traffic on port 25 and write the output to a file called "output_file."
The only problem you have is that, although it's readily clear who sent mail to whom, you can't see "what" they wrote. That's the stuff you want to see if you're going to be intercepting that information in real-time.
Note: In order to see the full contents of a packet, you don't need to use the "-v" flag. In fact, I'd strongly discourage it, since it pumps out about 50+ lines of IP stack layer information that you don't need for each and every packet!
If you want to see the full contents of the packets in snoop, just use the "-x" option and pass it the argument of an offset. "-x" gives you the entire packet, in both HEX and ASCII formats. You don't really need the HEX, since most humans read ASCII encoded text (like this) a lot more easily ;) A quick way to dump the HEX portion of each packet is to set the offset to 54 (for TCP traffic) and 42 (for UDP traffic). So, if you wanted to grab each packet and look at the ASCII contents only, you would type:
host # snoop -x 54 -o output_file port 25 <--- We're assuming TCP for the email transmission, although we'd capture any UDP packets that went to that port, also.
If you're ever snooping a protocol that doesn't fit the standards, or you forget these, you can almost always get the exact same effect (for TCP, UDP and any other protocol) by piping your output_file to awk when you're ready to read it, and just printing out the last field of every record, like so:
host # snoop -o output_file port 25
host # snoop -i output_file 2>&1 | awk '{ print $NF }'
The script we wrote for today doesn't take any arguments (but you should modify the snoop line if you want to specify a NIC with the "-d" option) and can be run simply, like this:
host # ./snoopmail.sh
And you'll get somewhat-ugly, but ultimately satisfying, results like this (yet another reason to never send a password via email): ..............To
...some.poor.guy
@xyz12345.com..S
ubject
Update 4....Hi
again....How are
ya,....Your new
password is bU
ggl3s....Please
do not share thi
s information wi
th any one!....T
hanks,.....Secur
ity..
Enjoy your Saturday, everyone :) Best wishes,
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License#!/bin/bash
#
# snoopmail.sh
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
if [ $# -ne 1 ]
then
echo "Usage: $0 SnoopOutputFile"
echo "Please capture packets with the suggested"
echo "settings: snoop -o output port 25"
exit 1
fi
snoop_file=$1
if [ ! -f $snoop_file ]
then
echo "Cannot find snoop output file $snoop_file. Exiting..."
exit 1
fi
snoop -i $snoop_file -x 54|sed -n '/DATA/,/QUIT/p'|grep -v SMTP|awk -F":" '{print $2}'|cut -c41- -
, Mike
linux unix internet technology
Saturday, April 19, 2008
Snooping Through Email On Solaris
Friday, April 18, 2008
Shell Script To Send Mail Using Bash File Descriptors
Hey There,
It's the weekend again, and I thought I'd wrap up this week's postings with quick script that, again, demonstrates a great way to take advantage of networking with bash using file descriptors on Linux or Unix. If you find this sort of thing fascinating (which I seem to ;), be sure to check out our orignal post on networking with bash file descriptors and the follow up regarding more things you can do with bash networking.
Note: Interestingly enough, apart from file descriptors 0, 1 and 2, you should also stay away from file descriptor 5. It seems bash uses this as its default file descriptor when a child process is created. Thankfully, I chose the number 9 (No Beatles pun intended ;)
Today's script sends email from the shell, directly to port 25 out, and is simple to run. It only takes a few arguments: Your From address, your To address, your mail server or relay, your domain and your message text (which you can put in any sort of file, as long as it's readable).
Ex:
host # ./mail.sh me@xyz.com you@xyz.com xyz.com localhost fileName
Hope you enjoy it and find some good use for it. If anything, it might make shooting emails out from the shell when you have a good idea much easier (before you have to fuss with Windows and lose your train of thought - Does that happen to everyone else, or just me ;).
Have a great weekend :)
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License#!/bin/bash
#
# mail.sh
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
if [ $# -ne 5 ]
then
echo "Usage: $0 FromAdress ToAdress Domain MailServer MailText"
exit 1
fi
from=$1
to=$2
domain=$3
mailserver=$4
mailtext=$5
if [ ! -f $mailtext ]
then
echo "Cannot find your mail text file. Exiting..."
exit 1
fi
exec 9<>/dev/tcp/$mailserver/25
echo "HELO $domain" >&9
read -r temp <&9
echo "$temp"
echo "Mail From: $from" >&9
read -r temp <&9
echo "$temp"
echo "Rcpt To: $to" >&9
read -r temp <&9
echo "$temp"
echo "Data" >&9
read -r temp <&9
echo "$temp"
cat $mailtext >&9
echo "." >&9
read -r temp <&9
echo "$temp"
echo "quit" >&9
read -r temp <&9
echo "$temp"
9>&-
9<&-
echo "All Done Sending Email. See above for errors"
exit 0
, Mike
linux unix internet technology
Posted by
Mike Golvach
at
12:06 AM
bash, bash script, cluster server, file descriptors, linux, mail, network, relay, script, unix
Saturday, February 23, 2008
Simple CGI AutoResponder Form
Hello again,
Today, we're going to hit up a fairly common CGI form technique used by pretty much every site on the internet today. At least, every e-commerce or interactive site. It's become expected, nowadays, that when you place an order for this or that, or you sign up for a message board, etc, that you'll be receiving an email to confirm this fact in a matter of minutes, if not seconds.
Our form below is a simple Perl CGI script that accepts input and reacts to it, by sending out an email to the person (or robot ;) requesting the information, and alerting us that we have a new mailing list member. It's somewhat similar, although completely different in function, to our previous post on processing and collecting emails from a CGI form. That script was functionally sound, but lacked the "reaction" that this script incorporates.
Like I said, this is a fairly bare-bones script (No limitations on Unix or Linux flavors it'll run on, as long as they can run Perl), so we're not getting deep into error checking or backend database operations, shopping carts, etc. Just a simple give and take (or take and give, depending on how you look at it ;). The user is going to input some requested data, and we're going to send them confirmation that we received that data (as well as a notification to ourselves). This CGI form assumes a frontend that passes it the form variables listed as $form{'VARIABLE_NAME'} throughout.
Here it is. Enjoy it and, hopefully, find some use for it within your larger applications :)
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License#!/usr/bin/perl
#
# JoinMailList.pl
# Simple Autoresponder Example
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
print "Content-type: text/html\n\n";
if ($ENV{'REQUEST_METHOD'} ne 'POST')
{
print <<"HTML";
<html><head><title>Whoops!</title></head>
<body><h1>Please Only Use the POST Method with this script!</h1>
</body></html>
HTML
exit;
}
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$form{$name} = $value;
}
chomp($date = `date`);
open(MAIL, "|/usr/lib/sendmail -t") || die "Can't open mailer!";
print MAIL "To: $form{'email'}\n";
print MAIL "From: OURCOMPANY\@OURSITE.COM\n";
print MAIL "Subject: Thanks For Joining Our Mailing List\n\n";
print MAIL <<"EOA";
Hey There,
Thanks a million for joining our mailing list. We will send you your first
email as soon as possible!
EOA
close(MAIL);
open(MAILER, "|/usr/lib/sendmail -t") || die "Can't open mailer!";
print MAILER "To: OURCOMPANY\@OURDOMAIN.COM\n";
print MAILER "From: newusers\@OURDOMAIN.COM\n";
print MAILER "Subject: Someone Just Joined Our Mailing List!\n\n";
print MAILER <<"EOB";
On $date, $form{'fname'} $form{'lname'} decided to join our little mailing list.
Yeehah
EOB
print MAILER <<"EOC";
$form{'fname'}\'s personal info:
$form{'fname'} $form{'lname'}
$form{'email'}
$form{'street'}
$form{'city'}, $form{'state'} $form{'zip'}
EOC
print MAILER "Please add $form{'fname'} to our list ASAP!\n";
print MAILER "Maybe we can finally sell something!\n";
close(MAILER);
print <<"HTML";
<html><head><title>Thanks for signing up!</title></head>
<body><h1> Thank you for joining our mailing list! </h1>
<b>$form{'fname'}</b>!,
Welcome to our mailing list. You should be receiving a confirmation email shortly!
The Mgmt.
</body></html>
HTML
exit;
, Mike
linux unix internet technology
Monday, February 4, 2008
Perl Script To Mail Users JTR Password Warnings
Hey there,
Today's post harkens back to an earlier post regarding a popular password cracking program called John The Ripper (JTR).
This Perl script we've put together for today will run equally well on Unix or Linux and takes the output file of a JTR run as its input. Then, it mails every account with a cracked password a little reminder note. The default filename JTR uses to save the passwords its cracked is called john.pot, so I'll use that in our example. You can, theoretically, change that output file name (which would change this script's input file name) to whatever you want.
You'd run the following script like so:
./pwwarn.pl <john.pot
You'll note that we're not reading the ARGV array to get the argument for the file name in the script, but rather reading from the standard input file descriptor (STDIN or <>). This should make it easier to integrate into any larger Perl script you've already written.
Hopefully this will help save you some administrative hassle. Also, hopefully, the automated password generation used to print the "threat password" (as in: You really don't want us to change it to this, do you? ;) will work to bring people over to your side of the security fence.
Cheers,
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License#!/usr/bin/perl
# pwwarn.pl
# Take output from JTR and send reminders via
# email to folks with really bad passwords
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
$tripwire = 0;
while ( <> ) {
if ( $_ =~ /^Loaded/ ) {
$tripwire = 1;
}
if ( $_ =~ /^Subject/ ) {
$hostname = $_;
chomp($hostname);
$hostname =~ s/.*Cracked on (.*)/$1/;
}
next if ( ! $tripwire );
next if ( $_ =~ /^Loaded/ );
next if ( $_ =~ /^guess/ );
next if ( $_ =~ /^ * *$/ );
push(@passwd, $_);
}
foreach $entry (@passwd) {
if ( $entry =~ /\(/ ) {
$entry =~ s/\(//;
$entry =~ s/\)//;
@entrees = split(/\s+/,$entry);
$entries{$entrees[1]} = $entrees[0];
}
}
foreach $key ( sort {$a <=> $b} keys %entries ) {
$random = rand('netstat -a'*10000);
$count=0;
$newpassword = "";
while ( $count < 8 ) {
$tester = rand('netstat -a')*100;
if ( $tester < 33 ) {
$tester += 33;
} elsif ( $tester > 93 ) {
$tester -= 7;
}
$newpassletter = sprintf("%c", $tester);
$newpassword .= $newpassletter;
$count++;
}
$newpassword =~ s/ ?//g;
open(MAILER, "|/usr/lib/sendmail -t ${key}\@xyz.com");
select MAILER;
print MAILER "Subject: Cracked Password\n";
print MAILER "From: sysadmin\@xyz.com\n";
print MAILER "Reply-To: sysadmin\@xyz.com\n";
print MAILER "This is an automatically generated notice.\n";
print MAILER "Do not reply to this letter.\n";
print MAILER "Replies will not be answered.\n";
print MAILER "\n";
print MAILER "The password for your account on $hostname was\n";
printf("cracked in %2.2f seconds.\n", $random);
print MAILER " username: $key\n";
print MAILER " password: $entries{$key}\n";
print MAILER "\n";
print MAILER " In the best-case scenario, a malicious user\n";
print MAILER "could have logged in as you and performed operations\n";
print MAILER "as you. In the worst-case scenario, someone could\n";
print MAILER "have logged in as you and used your account to wage\n";
print MAILER "an attack against this machine or other machines on \n";
print MAILER "the network.\n";
print MAILER " Please change your password immediately. After a\n";
print MAILER "certain amount of warnings, your password will be changed\n";
print MAILER "for you to something ugly like:\n";
print MAILER "\n";
print MAILER " $newpassword\n";
print MAILER "\n";
print MAILER " If you want to change it, and do not know how, please\n";
print MAILER "contact help\@xyz.com\n";
print MAILER "\n";
print MAILER " Remember, the security of the entire network depends on the\n";
print MAILER "security of its parts.\n";
print MAILER "\n";
print MAILER " Thank you,\n";
print MAILER " System Administration\n";
print MAILER "\n";
}
, Mike
linux unix internet technology
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:
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
linux unix internet technology

