Extracting email attachements from pcap files
From time to time, I need to examine email attachements that may have been delivered to my users, usually to see exactly what type of malware was included. Now, I could call them up and ask them if they got the message, but there are several reasons I don't like to do that. For example, I hate playing telephone tag, and I don't really want to encourage them to open the message for any reason.
Since I use Sguil, I have another option. I can extract the attachement from the network data directly. Here's how.
- Capture the session of interest as a pcap file. If you're also using Sguil, you can probably just do a SANCP search to find the network session that contained the message as it was delivered to your SMTP server. Open it up in Ethereal, which causes the Sguil client to copy the pcap file to your analysis workstation. Close Ethereal now, because you won't be using it for this.
- Once you have the pcap file, use the tcpflow tool to extract an ASCII version of the conversation. This will create two files, one for the server side of the session, and one for the client side. Here's an example, where xxx.xxx.xxx.xxx is the sending host, and zzz.zzz.zzz.zzz is your mail server:
% tcpflow -r xxx.xxx.xxx.xxx_yyyy_zzz.zzz.zzz.zzz_25-6.raw
% ls
xxx.xxx.xxx.xxx_yyyy_zzz.zzz.zzz.zzz_25-6.raw
xxx.xxx.xxx.xxx.yyyy-zzz.zzz.zzz.zzz.00025
zzz.zzz.zzz.zzz.0025-xxx.xxx.xxx.xxx.yyyy
The file you need to concern yourself with now is the one that ends in .00025. That's the one that contains the email message sent by the client. - Edit the *.00025 file in your favorite text editor. As it is now, it's a complete record of all the SMTP protocol events, and what you really want is just the data. The easiest thing is just to delete everything up to (but not including) the first line that starts with "Received:".
- Use the following perl command to read the mail file in via stdin and dump out the decoded MIME message. The script uses the MIME::Parser module (available from CPAN) to handle MIME decoding.
% perl -e 'use MIME::Parser; \
$parser = new MIME::Parser; \
$parser->output_under("/var/tmp"); \
$entity = $parser->parse(\*STDIN); \
$entity->dump_skeleton;' < *25
Content-type: multipart/mixed
Effective-type: multipart/mixed
Body-file: NONE
Subject: Message could not be delivered
Num-parts: 2
--
Content-type: text/plain
Effective-type: text/plain
Body-file: /var/tmp/msg-1150990039-2841-0/msg-2841-1.txt
--
Content-type: application/octet-stream
Effective-type: application/octet-stream
Body-file: /var/tmp/msg-1150990039-2841-0/letter.zip
Recommended-filename: letter.zip
--
As you can see, this command creates a directory /var/tmp/msg-XXXXXXX-XXXX-0/ which contains files for each piece of the MIME multipart message, including the attachement (in this case, /var/tmp/msg-1150990039-2841-0/letter.zip).
Now that you've got the attachement, you can use your favorite reverse engineering tools on it to figure out exactly what you've got on your hands.