Thursday, June 22, 2006

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.

  1. 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.
  2. 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 is the sending host, and zzz.zzz.zzz.zzz is your mail server:

    % tcpflow -r
    % ls

    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.
  3. 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:".
  4. 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/

    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/

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.


JimmytheGeek said...

Dude! This is awesome. If I thought of stuff this cool, I think my ego would get a little out of hand.


C.S.Lee said...

Nice write up dude, though I use to extract stuffs from pcap file while I need, however this is something awesome with perl usage as well.

Keep it up.