2013-08-28 10:20 AM
Hi All,
I have been having some serious frustrations trying to populate the email.src meta field.
I have asked RSA directly how to populate this and they informed me that its used for Logs not packets. however the email parser that comes with LIVE content only populates 'email' making it almost impossible to drill based on a sender. (for instance only wanting outbound mail instead of everything an email address sent or received.
Anyhow, I was told I would need a custom parser to achieve my objective, and this is what I have come up with:
<parser Name="From Mail Parser" desc="Version 0.1">
<!-- Parser Created by David McClennon @ Integralis.com -->
<declaration>
<!-- Declare meta keys to be used in this parser-->
<meta format="Text" key="email.dst" name="recipient"/>
<meta format="Text" key="email.src" name="sender"/>
<!-- Mail from and To identifiers to Match -->
<token name="MailFrom" value="MAIL FROM:<" options="linestart"/>
<!-- Position Identifiers -->
<number name="vMailPosition" scope="stream" />
<number name="vMailStop" scope="steam" />
<!-- Variables for holding strings -->
<string name="vEmailAddress" scope="stream" />
</declaration>
<!-- Evaluate From mail match -->
<match name="MailFrom">
<!-- Find ">" within 512 bytes -->
<find name="vMailPosition" value="<" length="512">
<!-- when found, assign contents between current potistion and vmailPosition to vEmailAddress -->
<read name="vEmailAddress" length="$vMailPosition">
<register name="sender" value="$vEmailAddress" />
</read>
</find>
</match>
</match>
</parser>
But for love nor money can I get it to work properly. I have tried a number of match combinations including encoding the "MAIL FROM:" in various formats, but cannot seem to get it to match or register the email address in the email.src register.
If anyone can see what I have done wrong, or have any suggestions, I would be most grateful.
Regards
Dave
2013-08-28 10:56 AM
A couple of tips- make sure you have a meta key for email.src in your local investigator index. For live deployment you also have to have these keys on the decoders/concentrators/brokers.
I presume you are working with a pcap of mail traffic for testing. After you create your parser and drop it into your parsers directory, you have to restart investigator and open it back up. This essentially reloads the parsers just like it was on a decoder. Now check the logs of Investigator under Help-> show log. Search the logs for this parser name. If it's broken, it usually drops a hint as to why. If it loads it will be listed along with every other local parser that loaded.
Just glancing at your parser, you reference vmailstop- this is either unneeded or should be a token, but its not referenced again. If you parser needs to locate "<" then that should be a token, registered above as the vmailstop. Then your find statement should be simply find vmailstop.
2013-08-28 10:56 AM
A couple of tips- make sure you have a meta key for email.src in your local investigator index. For live deployment you also have to have these keys on the decoders/concentrators/brokers.
I presume you are working with a pcap of mail traffic for testing. After you create your parser and drop it into your parsers directory, you have to restart investigator and open it back up. This essentially reloads the parsers just like it was on a decoder. Now check the logs of Investigator under Help-> show log. Search the logs for this parser name. If it's broken, it usually drops a hint as to why. If it loads it will be listed along with every other local parser that loaded.
Just glancing at your parser, you reference vmailstop- this is either unneeded or should be a token, but its not referenced again. If you parser needs to locate "<" then that should be a token, registered above as the vmailstop. Then your find statement should be simply find vmailstop.
2013-08-28 11:37 AM
<?xml version="1.0" encoding="utf-8"?>
<parsers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="parsers.xsd">
<parser name="FromMailParser" desc="extracts mail from info">
<declaration>
<token name="tMailFrom" value="User-Agent: Mozilla" options="linestart" />
<number name="vPosition" scope="stream" />
<string name="vMailFrom" scope="stream" />
<meta name="meta" key="email.src" format="Text" />
</declaration>
<match name="tMailFrom">
<find name="vPosition" value="<" length="512">
<read name="vMailFrom" length="$vPosition">
<register name="meta"
value="$vMailFrom" />
</read>
</find>
</match>
</parser>
</parsers>
2013-08-28 11:38 AM
I think the above will get you closer. Now you can create a separate parser for the recipient as well.
2013-08-28 11:42 AM
I found this lying around in my filesystem. No idea who made it or if it works. Looks like it requires a bunch of keys. Your mileage may vary, no complaints accepted if this doesn't work or if it blows up your decoder.
<?xml version="1.0" encoding="utf-8"?>
<parsers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="parsers.xsd">
<parser name="advanced_email" desc="advanced_email">
<declaration>
<!--
****
META DECLARATIONS
****
-->
<meta name="fromaddy" key="email.fromaddy" format="Text" />
<meta name="toaddy" key="email.toaddy" format="Text" />
<meta name="emailip" key="email.ip" format="Text" />
<meta name="emaildomain" key="email.domain" format="Text" />
<meta name="mailer" key="email.mailer" format="Text" />
<meta name="content" key="email.content" format="Text" />
<meta name="encoding" key="email.encoding" format="Text" />
<meta name="messid" key="email.messageid" format="Text" />
<meta name="bruteforce_alert" key="risk.warning" format="Text" />
<!--
****
STRINGS
****
-->
<string name="myString_Temp" />
<string name="myString_Empty" scope="constant"/>
<!--
****
NUMBERS
****
-->
<number name="myNum_offset"/>
<number name="myNum_offset2"/>
<number name="myNum_offset3"/>
<number name="myNum_FoundEHLO" scope="stream"/>
<number name="myNum_FoundPopLogic" scope="stream"/>
<number name="myNum_FoundLogin" scope="stream"/>
<number name="myNum_TriggeredAlertAlready" scope="stream"/>
<!--
****
TOKENS
****
-->
<token name="myToken_EHLO" value="EHLO" options="linestart" />
<token name="myToken_EHLO" value="HELO" options="linestart" />
<token name="myToken_FROM" value="MAIL From: <" options="linestart" />
<token name="myToken_FROM" value="MAIL From:<" options="linestart" />
<token name="myToken_TO" value="RCPT To: <" options="linestart" />
<token name="myToken_TO" value="RCPT To:<" options="linestart" />
<token name="myToken_Mailer" value="X-mailer: " options="linestart" />
<token name="myToken_Mailer" value="X-Mailer: " options="linestart" />
<token name="myToken_Forefront" value="X-Forefront-Antispam-Report: CIP:" options="linestart" />
<token name="myToken_MessageID" value="Message-ID:" options="linestart" />
<token name="myToken_ContentType" value="Content-Type:" options="linestart" />
<!-- <token name="myToken_Attachment" value="Content-Disposition: attachment; filename="" options="linestart" /> -->
<token name="myToken_Encoding" value="Content-Transfer-Encoding:" options="linestart" />
<!-- <token name="myToken_Subject" value="Subject: " options="linestart" /> -->
<!-- <token name="myToken_Server" value="220 " options="linestart" /> -->
<!-- IMAP logins -->
<token name="myToken_Login" value="A1 LOGIN " options="linestart" />
<token name="myToken_Login" value="A2 LOGIN " options="linestart" />
<token name="myToken_Login" value="A3 LOGIN " options="linestart" />
<token name="myToken_Login" value="A4 LOGIN " options="linestart" />
<token name="myToken_Login" value="A5 LOGIN " options="linestart" />
<token name="myToken_BruteForce" value="A10 LOGIN " options="linestart" />
<!-- POP tokens -->
<token name="myToken_PopLogic" value="RETR 1" options="linestart" />
<token name="myToken_PopLogic" value="RETR 2" options="linestart" />
<token name="myToken_PopLogic" value="RETR 3" options="linestart" />
<token name="myToken_PopLogic" value="RETR 4" options="linestart" />
<token name="myToken_PopLogic" value="RETR 5" options="linestart" />
<token name="myToken_PopLogic" value="RETR 6" options="linestart" />
<token name="myToken_PopLogic" value="RETR 7" options="linestart" />
<token name="myToken_PopLogic" value="RETR 8" options="linestart" />
<token name="myToken_PopLogic" value="RETR 9" options="linestart" />
<token name="myToken_Pop_from" value="From: " options="linestart" />
<token name="myToken_Pop_to" value="To: " options="linestart" />
<!--<token name="myToken_Pop_subject" value="Subject: " options="linestart" /> -->
</declaration>
<!--
****
FILTER MATCH
****
-->
<match name="myToken_EHLO">
<assign name="myNum_FoundEHLO" value="1"/>
</match>
<match name="myToken_PopLogic">
<assign name="myNum_FoundPopLogic" value="1"/>
</match>
<!--
****
REMAINING MATCHES
****
-->
<!--<match name="myToken_Pop_subject">
<if name="myNum_FoundPopLogic" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="128">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="subject2" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>-->
<match name="myToken_Pop_to">
<if name="myNum_FoundPopLogic" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="<" length="64">
<move direction="forward" value="$myNum_offset" />
<find name="myNum_offset" value=">" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="toaddy" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</find>
</match>
<match name="myToken_Pop_from">
<if name="myNum_FoundPopLogic" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="<" length="64">
<move direction="forward" value="$myNum_offset" />
<find name="myNum_offset" value=">" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="fromaddy" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</find>
</match>
<match name="myToken_FROM">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value=">" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="fromaddy" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<match name="myToken_TO">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value=">" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="toaddy" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<match name="myToken_Mailer">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="mailer" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<match name="myToken_ContentType">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="content" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<!-- <match name="myToken_Attachment">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value=""" length="128">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="attach" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match> -->
<match name="myToken_Encoding">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="encoding" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<match name="myToken_MessageID">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="messid" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<!-- Commenting out here for performance reasons
<match name="myToken_Subject">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="128">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="subject2" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
<match name="myToken_Login">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<if name="myNum_FoundLogin" equal="1">
<end/>
</if>
<find name="myNum_offset" value=" " length="128">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="username2" value="$myString_Temp" />
<assign name="myString_Temp" value="$myString_Empty"/>
<assign name="myNum_FoundLogin" value="1"/>
</if>
</read>
</find>
</match>
-->
<match name="myToken_Forefront">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value="
" length="512">
<find name="myNum_offset2" value=";" length="$myNum_offset">
<read name="myString_Temp" length="$myNum_offset2">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="emailip" value="$myString_Temp" />
</if>
</read>
</find>
<find name="myNum_offset2" value="RD:" length="$myNum_offset">
<move value="$myNum_offset2">
<decrement name="myNum_offset" value="$myNum_offset2"/>
<move value = "3" />
<find name="myNum_offset3" value=";" length="$myNum_offset">
<read name="myString_Temp" length="$myNum_offset3">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="emaildomain" value="$myString_Temp" />
</if>
</read>
</find>
</move>
</find>
</find>
<assign name="myString_Temp" value="$myString_Empty"/>
</match>
<match name="myToken_BruteForce">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<if name="myNum_TriggeredAlertAlready" equal="1">
<end/>
</if>
<register name="bruteforce_alert" value="bruteforce_email_login" />
<assign name="myNum_TriggeredAlertAlready" value="1"/>
</match>
</parser>
</parsers>
2013-08-28 11:56 AM
That is awesome thank you. (ps. I want your filesystem )
2013-08-28 11:57 AM
For that parser to work all I need to do is register the meta values on "decoder/concentrator/broker" and add the parser to the Flex.parser correct? Im not missing anything am I?
Regards
Dave
2013-08-28 12:11 PM
Here would be the keys you would need. Paste them into the concentrator/broker but:
Change the level to IndexNone on the decoders or you will meet your doom!
<key description="Email From Address" level="IndexValues" name="email.fromaddy" valueMax="100000" defaultAction="Open"/>
<key description="Email To Address" level="IndexValues" name="email.toaddy" valueMax="100000" defaultAction="Open"/>
<key description="Email IP" level="IndexValues" name="email.ip" valueMax="100000" defaultAction="Open"/>
<key description="Email Domain" level="IndexValues" name="email.domain" valueMax="100000" defaultAction="Open"/>
<key description="Email Mailer" level="IndexValues" name="email.mailer" valueMax="100000" defaultAction="Open"/>
<key description="Email Content" level="IndexValues" name="email.content" valueMax="100000" defaultAction="Open"/>
<key description="Email Encoding" level="IndexValues" name="email.encoding" valueMax="100000" defaultAction="Open"/>
<key description="Email Message ID" level="IndexValues" name="email.messageid" valueMax="100000" defaultAction="Open"/>
2013-08-28 01:27 PM
Fielder wrote:
Here would be the keys you would need. Paste them into the concentrator/broker but:
Change the level to IndexNone on the decoders or you will meet your doom!
Learn't that the hard way some time ago thank you for the confirmation. That is almost word for word what I had put in the index
2013-08-28 02:19 PM
1 final quick question if I may. how would I add meta to identity if the from is an internal domain?
I have a meta value "soc.misc" that I would like to give a value of "Internal" which I could then use in the following context
custom drill: "soc.misc !="Internal" which would in turn leave me with all inbound mail only.
I am guessing something like this:
<meta name="misc" key="soc.misc" format="Text" />
</declaration>
<!--snip-->
<match name="myToken_FROM">
<if name="myNum_FoundEHLO" notequal="1">
<end/>
</if>
<find name="myNum_offset" value=">" length="64">
<read name="myString_Temp" length="$myNum_offset">
<if name="myString_Temp" notequal="$myString_Empty">
<register name="fromaddy" value="$myString_Temp" />
<!-- Check for internal domain name -->
<find length="64" name="myNum_offset" value="mydomain.com"/>
<!-- if found register misc key value-->
<register name="misc" value="Internal"/>
</find>
<assign name="myString_Temp" value="$myString_Empty"/>
</if>
</read>
</find>
</match>
Do I need to move the pointer before running the find?
Thanks again for your help.
Dave