20.3.14.

流信息通过 suricata.flow 库暴露给 Lua 脚本。使用时需要先引入该库,例如:

local flow = require("suricata.flow")

以下是当前可用的流信息访问函数。

20.3.14.1. 初始化

20.3.14.1.1. get

初始化当前引擎正在处理的流对象以供脚本使用:

f = flow.get()

20.3.14.2. 时间相关

20.3.14.2.1. timestamps

获取流中首尾数据包的时间戳(以UTC时间`1970-01-01 00:00:00`为基准的秒和微秒值),返回4个数值:

f = flow.get()
local start_sec, start_usec, last_sec, last_usec = f:timestamps()

20.3.14.2.2. timestring_legacy

获取流中首个数据包的时间戳字符串,格式为:11/24/2009-18:57:25.179869。该格式与`fast.log`、`http.log`等传统输出格式一致:

f = flow.get()
print f:timestring_legacy()

20.3.14.2.3. timestring_iso8601

获取流中首个数据包的时间戳字符串,格式为:2015-10-06T15:16:43.136733+0000。该格式与EVE输出格式一致:

f = flow.get()
print f:timestring_iso8601()

20.3.14.3. 端口与地址

20.3.14.4. tuple

通过`tuple`方法获取IP版本号(4或6)、源IP/目的IP(字符串形式)、IP协议号(整型)及端口号(整型)。

协议号取自IP头,详见:https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml

f = flow.get()
ipver, srcip, dstip, proto, sp, dp = f:tuple()

20.3.14.5. 应用层协议

20.3.14.5.1. app_layer_proto

获取流的`alproto`字符串(若未知则返回"unknown")。返回5个值:<alproto>, <alproto_ts>, <alproto_tc>, <alproto_orig>, <alproto_expect>。

示例:

f = flow.get()
alproto, alproto_ts, alproto_tc, alproto_orig, alproto_expect = f:app_layer_proto()

`orig`和`expect`用于协议变更场景。例如SMTP STARTTLS场景中,`orig`通常为"smtp"而`expect`为"tls"。

20.3.14.6. 其他功能

20.3.14.6.1. has_alerts

若流中存在告警则返回`true`:

f = flow.get()
alerted = f:has_alerts()

20.3.14.6.2. id

获取流ID。注意直接打印`id`可能输出科学计数法,建议使用以下方式:

f = flow.get()
id = f:id()
id_str = string.format("%.0f", id)
print ("Flow ID: " .. id_str .."\n")

20.3.14.6.3. stats

获取流中双向数据包计数和字节数(返回4个数值):

f = flow.get()
tscnt, tsbytes, tccnt, tcbytes = f:stats()

20.3.14.7. 示例

一个简单的日志函数,在流触发告警时输出流详情:

function log(args)
    local f = flow.get()
    ts = f:timestring_iso8601()
    has_alerts = f:has_alerts()
    ipver, srcip, dstip, proto, sp, dp = f:tuple()
    alproto, alproto_ts, alproto_tc, alproto_orig, alproto_expect = f:app_layer_proto()
    start_sec, start_usec, last_sec, last_usec = f:timestamps()
    id = f:id()

    if has_alerts then
        file:write ("[**] Start time " .. ts .. " [**] -> alproto " .. alproto .. " [**] " .. proto .. " [**] alerted: true\n[**] First packet: " .. start_sec .." [**] Last packet: " .. last_sec .. " [**] Flow id: " .. id .. "\n")
        file:flush()
    end
end

完整脚本示例可参考Suricata-verify项目:https://github.com/OISF/suricata-verify/tree/master/tests