Send an email with an attached file using telnet or netcat

Solution 1:

Okay, so using everyone's comments as a starting point I came up with this silly mess :-) ...

{ 
    sleep 5; 
    echo 'ehlo';
    sleep 3;
    echo 'MAIL FROM:<[email protected]>';
    sleep 3; 
    echo 'RCPT TO: <kyle@test_dest.com>';
    sleep 3;
    echo 'DATA';
    sleep 3;
    echo -e 'To:[email protected]\nMIME-Version: 1.0 (mime-construct 1.9)\nContent-Type: application/zip\nContent-Transfer-Encoding: base64\n\n';
    dd if=/dev/urandom bs=4 count=10 2>/dev/null | openssl base64;
    echo '.';
} | telnet mx1.testdest.com 25

Solution 2:

Ick. You're going to have to base64 encode the attachment and create the MIME headers.

Rather than generating a new message "on the fly" each time, it would probably be easier just to email yourself a very short example message from a "real" email program (leveraging the work that the people who wrote it did to put the attachment into the proper encoding and creating the MIME headers).

Save that message off into a text file w/ its headers (removing the transport header, of course), and just modify / copy / paste it into telnet or netcat for future sessions.


Solution 3:

While hand testing SMTP servers by hand is possible and viable, using a tool designed for this will be much easier.

This article explains SWAKS. swaks is designed for smtp server testing. Supports attachments, authentication and encryption!


Solution 4:

i sumbled upon this entry while i were searching for something of the same. and from the awnsers here and som additional research i managed to make this script.

#!/bin/sh

# Default reception
TOEMAIL="[email protected]";
# Default Subject
SUBJECT="You got mail - $DATE";
# Default Contents
MSGBODY="Hello, this is the default message body";
# Default Attachment
#ATTACHMENT="/tmp/testoutput"
# Default smtp server
mailserver="smtp.server.ltd"
mailserverPort="25"

showUsage() {
        echo "$0 -a /file/to/attach [-m /message/file] [-M \"Message string\"] -s \"subject\" -r [email protected]"
        echo
        echo "The attachment (-a) is required, if no attachment is used then rather use sendmail directly."
}

fappend() {
    echo "$2">>$1;
}
DATE=`date`

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# This might need correction to work on more places, this is tested at a ubuntu 13.10 machine.  #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
domain=`grep search /etc/resolv.conf | awk '{print $2;}'`
computer=`hostname`
user=`whoami`
FREMAIL="$user@$computer.$domain"

while getopts "M:m:a:s:r:" opt; do
  case $opt in
        s)
          SUBJECT="$OPTARG - $DATE"
          ;;
        r)
          TOEMAIL="$OPTARG"
          ;;
        m)
          MSGBODY=`cat $OPTARG`
          ;;
        M)
          MSGBODY="$OPTARG"
          ;;
        a)
          ATTACHMENT="$OPTARG"
          ;;
        :)
          showUsage
          ;;
        \?)
          showUsage
          ;;
  esac
done

if [ "$ATTACHMENT" = "" ]; then
        showUsage
        exit 1
fi

MIMETYPE=`file --mime-type -b $ATTACHMENT`
TMP="/tmp/tmpmail_"`date +%N`;
BOUNDARY=`date +%s|md5sum|awk '{print $1;}'`
FILENAME=`basename $ATTACHMENT`

DATA=`cat $ATTACHMENT|base64`

rm $TMP 2> /dev/null

fappend $TMP "EHLO $computer.$domain"
fappend $TMP "MAIL FROM:<$FREMAIL>"
fappend $TMP "RCPT TO:<$TOEMAIL>"
fappend $TMP "DATA"
fappend $TMP "From: $FREMAIL"
fappend $TMP "To: $TOEMAIL"
fappend $TMP "Reply-To: $FREMAIL"
fappend $TMP "Subject: $SUBJECT"
fappend $TMP "Content-Type: multipart/mixed; boundary=\"$BOUNDARY\""
fappend $TMP ""
fappend $TMP "This is a MIME formatted message.  If you see this text it means that your"
fappend $TMP "email software does not support MIME formatted messages."
fappend $TMP ""
fappend $TMP "--$BOUNDARY"
fappend $TMP "Content-Type: text/plain; charset=UTF-8; format=flowed"
fappend $TMP "Content-Disposition: inline"
fappend $TMP ""
fappend $TMP "$MSGBODY"
fappend $TMP ""
fappend $TMP ""
fappend $TMP "--$BOUNDARY"
fappend $TMP "Content-Type: $MIMETYPE; name=\"$FILENAME\""
fappend $TMP "Content-Transfer-Encoding: base64"
fappend $TMP "Content-Disposition: attachment; filename=\"$FILENAME\";"
fappend $TMP ""
fappend $TMP "$DATA"
fappend $TMP ""
fappend $TMP ""
fappend $TMP "--$BOUNDARY--"
fappend $TMP ""
fappend $TMP "."
fappend $TMP "quit"

netcat $mailserver $mailserverPort < $TMP >> $TMP
rc="$?"
if [ "$rc" -ne "0" ]; then
    echo "Returncode: $rc"
    echo "Please inspect $TMP"
else
    rm $TMP;
fi

One thing you might want to add is authentication. i dont need it so i havent added it.

I think it only requires md5sum, netcat, file, awk and the base64 commands, id guess they are pretty standard in most systems.


Solution 5:

Telnet - send email with multiple attachments

cat attachment.zip | base64 > zip.txt
cat attachment.pdf | base64 > pdf.txt

# Content-Type: text/csv; name="$FILE"                        # for CSV files
# Content-Type: application/x-msdownload; name="$FILE"    # for executable 
# Content-Type: text/xml; name="$FILE"                        # for xml files or try application/xml

telnet smtp.server.dom 25

HELO
MAIL FROM: [email protected]
RCPT TO: [email protected]
DATA
Subject: Test email
From: [email protected]
To: [email protected]
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="X-=-=-=-text boundary"

--X-=-=-=-text boundary
Content-Type: text/plain

Put your message here...

--X-=-=-=-text boundary
Content-Type: application/zip; name="file.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="file.zip"

UEsDBBQAAAAIAG1+zEoQa.... copy/paste zip.txt

--X-=-=-=-text boundary
Content-Type: text/pdf; name="file.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="file.pdf"

UEsDBBQAAAAIAG1+zEoQa.... copy/paste pdf.txt

--X-=-=-=-text boundary
.

QUIT