Filtering spam

As usual, we load first the smtp module disector. Then, we install our newly created dissector on flow addressed to port 25.

Next, we hook our security rule on event command which will pass to the evaluaton function the parsed command message. The rest of the rule is basic: we get the parmeter of MAIL command and check if the dommain name is banned.

-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.

local smtp = require('smtp')

local rem = require('regexp/pcre')
local email_pattern = rem.re:compile("@.*")

local forbidden_domain = 'packet-level.com'

smtp.install_tcp_rule(25)

haka.rule{
    hook = smtp.events.command,
    eval = function (flow, message)
        local command = message.command:lower()
        if command == 'mail' then
            local param = message.parameter
            local res, startpos, endpos = email_pattern:match(param)
            if not res then
                haka.alert {
                    description = "malformed email address",
                    severity = 'low'
                }
                flow:drop()
            else

                local mailfrom = param:sub(startpos+2, endpos)
                if mailfrom == "suspicious.org" then
                    haka.alert {
                        description = "forbidden mail domain",
                        severity = 'low'
                    }
                end
                flow:drop()
            end
        end
    end
}

Dumping mail content

The second security rule hooks on mail event and allows us to get the content of a mail in a streamed mode.

-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.

local smtp = require('smtp')

smtp.install_tcp_rule(25)

haka.rule{
    hook = smtp.events.mail_content,
    options = {
        streamed = true,
    },
    eval = function (flow, iter)
        local mail_content = {}

        for sub in iter:foreach_available() do
            table.insert(mail_content, sub:asstring())
        end

        print("== Mail Content ==")
        print(table.concat(mail_content))
        print("== End Mail Content ==")
    end
}

Note

These security rules are available in <haka_install_path>/share/haka/sample/smtp_dissetor. A smtp capture sample smtp.pcap is also provided in order to replay the above rules.