Skip to content

Instantly share code, notes, and snippets.

@mbrownnycnyc
Last active December 16, 2015 21:21
Show Gist options
  • Save mbrownnycnyc/4ed056431664575a0a77 to your computer and use it in GitHub Desktop.
Save mbrownnycnyc/4ed056431664575a0a77 to your computer and use it in GitHub Desktop.
A (mostly not done) set of parsers for Ironport maillog files to extract some info. Purpose is to prove the usefulness of enabling SPF and RDNS protections.
--info--
RDNS lookups are performed and the results affect delivery is configured in the ironport by default (results can be reviewed in the maillog).
The SPF checks:
pra: primarily protects against phishing and new spam campaigns.
mailfrom: primarily protects against spoofing.
helo: not really that useful.
The SPF check result meanings:
1. None - no verification can be performed due to the lack of information.
2. Pass - the client is authorized to inject mail with the given identity.
3. Neutral - the domain owner does not assert whether the client is authorized to use the
given identity.
4. SoftFail - the domain owner believes the host is not authorized to use the given
identity but is not willing to make that strong of a statement.
5. Fail - the client is not authorized to inject mail with the given identity.
6. TempError - a transient error occurred during verification.
7. PermError - a permanent error occurred during verification.
N/A results from: a None status, no SPF lookups were available (including the lack of PRA entries in SPF v1 records), the sending server/domain is in the WHITELIST sender group.
The SPF check result considerations for message-filter construction:
None: this is fine. don't quarantine.
Pass: good. don't quarantine.
Neutral: this is fine. don't quarantine.
SoftFail: not good, but needs investigation. We can quarantine, but after a review of processed results for some period of time. It's possible this will result in mass mailers being quarantined.
Fail: bad. quarantine these.
TempFail: not great, but needs investigation.
PermError: bad. quarantine these.
In regards to sender verification, you can implement it, but you'll get much more value out of focusing on SPF.
-- find all Message IDs in an ironport mail_log file --
#http://stackoverflow.com/a/3520237/843000
$MIDs = @()
#find all MIDs
#findstr is a hell of a lot faster than select-string
$findstrout = findstr /R /C:".*Start MID .*ICID.*" "c:\users\myuser\desktop\mail.current"
$searchresults = $findstrout | select-string "Start MID (?<content>.*) ICID " -allmatches
foreach ($match in $searchresults.matches ){
$MIDs += $match.groups[1].value
}
-- Find SPF check results for some MIDs --
#There are three types of SPF checked that can be used in a message filter to quarantine email: helo, mailfrom, and pra checks (http://www.cisco.com/c/en/us/support/docs/security/email-security-appliance/118574-qa-esa-00.html)
$MIDResults = @()
foreach ($MessageID in $mids ) {
write-output "finding SPF info for Message ID: $MessageID"
$tempobj = "" | select MID, sender, SPFhelo, SPFmailfrom, SPFpra
$tempobj.mid = $MessageID
#MID 9731073 SPF: helo identity [email protected] Pass (v=spf1)
#MID 9731073 SPF: mailfrom identity [email protected] Pass (v=spf1)
#FAIL: MID 9731073 SPF: pra identity [email protected] None headers from
#PASS: MID 9766442 SPF: pra identity [email protected] Pass (spf2.0) headers from
$findstrout = findstr /R /C:".*$MessageID.*SPF: .*" "c:\users\myuser\desktop\mail.current"
#find helo result
foreach ($line in $findstrout){
$line -match "helo identity (?<sender>.*) (?<heloresult>.*) \(v=spf1\)" | out-null
$tempobj.sender = $matches['sender']
$tempobj.spfhelo = $matches['heloresult']
}
#find mailfrom result
foreach ($line in $findstrout){
$line -match "mailfrom identity (?<sender>.*) (?<mailfromresult>.*) \(v=spf1\)" | out-null
$tempobj.spfmailfrom = $matches['mailfromresult']
}
#find pra result
foreach ($line in $findstrout){
if ($line -match "pra identity (?<sender>.*) None headers from") {
$tempobj.spfpra = "Fail"
}
if ($line -match "pra identity (?<sender>.*) (?<praresult>.*) \(spf2.0\) headers from") {
$tempobj.spfpra = $matches['praresult']
}
}
$MIDResults += $tempobj
}
$MIDResults | convertto-csv
-- Find SPF and Quarantine activity by MID --
foreach ($MessageID in $mids ) {
write-output $MessageID
findstr /R ".*$MessageID.*SPF.* .*$MessageID.*Quarantine.* .*Quarantine.*$MessageID.*" "c:\users\myuser\desktop\mail.current" >> c:\users\myuser\desktop\msgid_spf_out.txt
}
foreach ($MessageID in (get-content "C:\Users\myuser\Desktop\bad_msgid_list.txt") ) {
#findstr is a hell of a lot faster than select-string
write-output $MessageID >> c:\users\myuser\desktop\msgid_spf_out.txt
findstr /R ".*$MessageID.*SPF.* .*$MessageID.*Quarantine.* .*Quarantine.*$MessageID.*" "c:\users\myuser\desktop\mail.current" >> c:\users\myuser\desktop\msgid_spf_out.txt
}
-- find ICID (connection ID) for MID --
$MID_ICIDPairs = @()
foreach ($MessageID in (get-content "C:\Users\myuser\Desktop\bad_msgid_list.txt") ) {
$tempobj = "" | select MID, ICID
$tempobj.mid = $MessageID
write-host $MessageID
#find the ICID given a MID
$findstrout = findstr /R ".*$MessageID.*ICID.*From:.*" "c:\users\myuser\desktop\mail.current"
$findstrout -match "MID $MessageID ICID (?<content>.*) From:" | out-null
$tempobj.icid = $matches['content']
$MID_ICIDPairs += $tempobj
}
$MID_ICIDPairs | convertto-csv
-- given an ICID, find the RDNS result --
$RDNSresults = @()
foreach ($ConnectionID in ($midicid.icid)) {
$tempobj = "" | select ICID,RDNS,Server
$tempobj.icid = $ConnectionID
write-host $ConnectionID
#find the ICID given a MID
#"New SMTP ICID 10855701 interface Data 1 (172.16.8.51) address 172.245.12.148 reverse dns host ldhnl.shoax.eu verified yes"
$findstrout = findstr /R /C:".*New SMTP ICID $ConnectionID.*reverse dns.*" "c:\users\myuser\desktop\mail.current"
$findstrout -match "reverse dns host (?<server>.*) verified (?<RDNSresult>.*)" | out-null
$tempobj.RDNS = $matches['RDNSresult']
$tempobj.server = $matches['server']
$RDNSresults += $tempobj
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment