美文网首页
lua 支持

lua 支持

作者: lx_jian | 来源:发表于2019-07-05 15:41 被阅读0次

    1. Lua在Suricata中的使用

    Lua脚本可以在Suricata的两个组件中使用。第一个是在输出。第二个是检测引擎的规则中。

    这个两个功能都使用一系列函数来访问Suricata提取的数据。您可以在Lua函数页面中获取函数列表。

    1.1 Lua 输出

    Lua可以用来写任意输出。有关更多信息,请参阅Lua输出

    1.2 Lua检测

    Lua脚本可以用作规则中的过滤条件。有关更多信息,请查看下面的Lua函数

    2. Lua函数

    2.1 packet

    初始化为:

    function  init(args)

            localneeds={}

            needs["type"]="packet"

            return needs

    end

    2.1.1 SCPacketTimestamp

    获取数据包时间戳为2个数字:自1970-01-01 00:00:00 UTC以来经过的秒数和微秒数.

    function  log(args)

          localsec,usec=SCPacketTimestamp()

    end

    2.1.2  SCPacketTimeString

    添加SCPacketTimeString以获取数据包时间字符串的格式为:11/24 / 2009-18:57:25.179869

    function log(args)

          ts=SCPacketTimeString()

    end

    2.1.3 SCPacketTuple

    ipver,srcip,dstip,proto,sp,dp=SCPacketTuple()

    2.1.4 SCPacketPayload 

    p = SCPacketPayload()

    2.2 flow

    function  init(args)

            localneeds={}

            needs["type"]="flow"

            return needs

    end

    2.2.1. SCFlowTimestamps

    获取流中第一个和最后一个数据包的时间戳(秒和微秒)

    startts,lastts=SCFlowTimestamps()

    startts_s,lastts_s,startts_us,lastts_us=SCFlowTimestamps()

    2.2.2. SCFlowTimeString

    startts=SCFlowTimeString()

    2.2.3. SCFlowTuple

    ipver,srcip,dstip,proto,sp,dp=SCFlowTuple()

    2.2.4. SCFlowAppLayerProto

    从流程中获取alprotos作为字符串。如果alproto(尚未)已知,则返回“unknown”。

    如:

    function  log(args)

            alproto=SCFlowAppLayerProto()

            if  alproto~=nil then

                    print(alproto)

            end

    end

    返回5个值:<alproto> <alproto_ts> <alproto_tc> <alproto_orig> <alproto_expect>

    更改和升级协议时使用Orig和expect。在SMTP STARTTLS案例中,orig通常设置为“smtp”并期望“tls”。

    2.2.5. SCFlowHasAlerts

    如果流有警报,则返回true。

    如:

    function  log(args)

            has_alerts=SCFlowHasAlerts()

            if has_alerts then

                --do something

            end

    end

    2.2.6. SCFlowStats

    获取每个流的数据包和字节数。

    tscnt,tsbytes,tccnt,tcbytes=SCFlowStats()

    2.2.7. SCFlowId

    获取流ID

    id=SCFlowId()

    请注意,简单地打印“id”可能会导致打印科学记数法。为避免这种情况,只需:

    id=SCFlowId()

    idstr=string.format("%.0f",id)

    print("Flow ID: "..idstr.."\n")

    2.3 HTTP

    初始化

    function  init(args)

            localneeds={}

            needs["protocol"]="http"

            return needs

    end

    2.3.1 HttpGetRequestBody和HttpGetResponseBody

    通过HttpGetRequestBody和HttpGetResponseBody为脚本提供标准化的正文数据。

    无法保证所有身体都可以使用.

    如:

    function  log(args)

            a,o,e=HttpGetResponseBody();

            --print("offset "..o.." end "..e)

            for n,vinipairs(a) do

                    print(v)

            end

    end

    2.3.2 HttpGetRequestHost

    从libhtp的tx-> request_hostname获取主机,它可以是url的主机部分,也可以是Host头的主机部分。

    如:

    http_host = HttpGetRequestHost()

    if http_host==nil then

        http_host="<hostname unknown>"

    end

    2.3.3 HttpGetRequestHeader 

    http_ua = HttpGetRequestHeader("User-Agent")

    if  http_ua==nil then

            http_ua="<useragent unknown>"

    end

    2.3.4 HttpGetResponseHeader

    server=HttpGetResponseHeader("Server");

    print("Server: "..server);

    2.3.5 HttpGetRequestLine

    rl=HttpGetRequestLine();

    print("Request Line: "..rl);

    2.3.6 HttpGetResponseLine

    rsl=HttpGetResponseLine();

    print("Response Line: "..rsl);

    2.3.7 HttpGetRawRequestHeaders

    rh=HttpGetRawRequestHeaders();

    print("Raw Request Headers: "..rh);

    2.3.8 HttpGetRawResponseHeaders 

    rh=HttpGetRawResponseHeaders();

    print("Raw Response Headers: "..rh);

    2.3.9 HttpGetRequestUriRaw

    http_uri=HttpGetRequestUriRaw()

    if http_uri==nil then

            http_uri="<unknown>"

    end

    2.3.10 HttpGetRequestUriNormalized

    http_uri =HttpGetRequestUriNormalized() 

    if http_uri==nilthen

        http_uri="<unknown>"

    end

    2.3.11 HttpGetRequestHeaders

    a=HttpGetRequestHeaders();

    for n,vinpairs(a) do 

        print(n,v)

    end

    2.3.12 HttpGetResponseHeaders

    a=HttpGetResponseHeaders();

    for n,vinpairs(a) do

        print(n,v)

    end

    2.4 DNS 

    2.4.1 DnsGetQueries 

    dns_query=DnsGetQueries();

    if dns_query~=nil then

            for n,tinpairs(dns_query) do

                    rrname=t["rrname"]

                    rrtype=t["type"]

                    print("QUERY: "..ts.." "..rrname.." [**] "..rrtype.." [**] ".."TODO".." [**] "..srcip..":"..sp.." -> "..dstip..":"..dp)

            end

    end

    返回一个表格的表

    2.4.2 DnsGetAnswers

    dns_answers = DnsGetAnswers();

    if dns_answers ~= nil then

        for n, t in pairs(dns_answers) do

            rrname = t["rrname"]

            rrtype = t["type"]

            ttl = t["ttl"]

            print ("ANSWER: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..

                  ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..

                  dstip .. ":" .. dp)

        end

    end

    返回一个表格的表

    2.4.3 DnsGetAuthorities 

    dns_auth = DnsGetAuthorities();

    if dns_auth ~= nil then

        for n, t in pairs(dns_auth) do

            rrname = t["rrname"]

            rrtype = t["type"]

            ttl = t["ttl"]

            print ("AUTHORITY: " .. ts .. " " .. rrname .. " [**] " .. rrtype .. " [**] " ..

                  ttl .. " [**] " .. srcip .. ":" .. sp .. " -> " ..

                  dstip .. ":" .. dp)

        end

    end

    返回一个表格的表

    2.4.4 DnsGetRcode 

    rcode = DnsGetRcode();

    if rcode == nil then

        return 0

    end

    print (rcode)

    返回带有错误消息的lua字符串,或者为nil

    2.4.5 DnsGetRecursionDesired 

    if  DnsGetRecursionDesired()==true then

            print("RECURSION DESIRED")

    end

    2.5 TLS 

    初始化为:

    function init (args)

        local needs = {}

        needs["protocol"] = "tls"

        return needs

    end

    2.5.1 TlsGetVersion 

    通过TlsGetVersion将TLS会话中的协商版本作为字符串获取。

    如:

    function log(args)

        version=TlsGetVersion()

        if version then

            -- do something

        end

    end

    2.5.2 TlsGetCertInfo 

    通过TlsGetCertInfo为脚本提供证书信息。

    如:

    function log (args)

        version, subject, issuer, fingerprint = TlsGetCertInfo()

        if version == nil then

            return 0

        end

    end

    2.5.3 TlsGetCertChain

    通过TlsGetCertChain使证书链可用于脚本。

    输出是一个证书数组,每个证书都是带有数据和长度密钥的哈希。

    如:

    -- Use debian lua-luaossl coming from https://github.com/wahern/luaossl

    local x509 = require"openssl.x509"

      chain = TlsGetCertChain()

      for k, v in pairs(chain) do

          -- v.length is length of data

          -- v.data is raw binary data of certificate

          cert = x509.new(v["data"], "DER")

          print(cert:text() .. "\n")

      end

    2.5.4 TlsGetCertNotAfter 

    获取证书有效期结束的Unix时间戳。

    function log (args)

        notafter = TlsGetCertNotAfter()

        if notafter < os.time() then

            -- expired certificate

        end

    end

    2.5.5 TlsGetCertNotBefore 

    获取证书有效期开始的Unix时间戳。

    如:

    function log (args)

        notbefore = TlsGetCertNotBefore()

        if notbefore > os.time() then

            -- not yet valid certificate

        end

    end

    2.5.6 TlsGetCertSerial 

    通过TlsGetCertSerial获取TLS证书序列号。

    如:

    function log (args)

        serial = TlsGetCertSerial()

        if serial then

            -- do something

        end

    end

    2.5.7 TlsGetSNI 

    从TLS连接获取服务器名称指示。

    如:

    function log (args)

        asked_domain = TlsGetSNI()

        if string.find(asked_domain, "badguys") then

            -- ok connection to bad guys let's do someting

        end

    end

    2.6 JA3

    必须在Suricata配置文件中启用JA3(将'app-layer.protocols.tls.ja3-fingerprints'设置为'yes')。

    初始化为:

    function init (args)

        local needs = {}

        needs["protocol"] = "tls"

        return needs

    end

    2.6.1 Ja3GetHash 

    通过Ja3GetHash获取JA3哈希(JA3字符串的md5sum)。

    如:

    function log (args)

        hash = Ja3GetHash()

        if hash == nil then

            return

        end

    end

    2.6.2 Ja3GetString

    通过Ja3GetString获取JA3字符串。

    如:

    function log (args)

        str = Ja3GetString()

        if str == nil then

            return

        end

    end

    2.7 SSH

    初始为:

    function init (args)

        local needs = {}

        needs["protocol"] = "ssh"

        return needs

    end

    2.7.1 SshGetServerProtoVersion

    通过SshGetServerProtoVersion获取服务器使用的SSH协议版本。

    如:

    function log (args)

        version = SshGetServerProtoVersion()

        if version == nil then

            return 0

        end

    end

    2.7.2 SshGetServerSoftwareVersion

    通过SshGetServerSoftwareVersion获取服务器使用的SSH软件。

    如:

    function log (args)

        software = SshGetServerSoftwareVersion()

        if software == nil then

            return 0

        end

    end

    2.7.3 SshGetClientProtoVersion

    通过SshGetClientProtoVersion获取客户端使用的SSH协议版本。

    如:

    function log (args)

        version = SshGetClientProtoVersion()

        if version == nil then

            return 0

        end

    end

    2.7.4 SshGetClientSoftwareVersion

    通过SshGetClientSoftwareVersion获取客户端使用的SSH软件。

    如:

    function log (args)

        software = SshGetClientSoftwareVersion()

        if software == nil then

            return 0

        end

    end

    2.8 Files

    要使用文件记录API,脚本的init()函数需要如下所示:

    function init (args)

        local needs = {}

        needs['type'] = 'file'

        return needs

    end

    2.8.1 SCFileInfo

    fileid,txid,name,size,magic,md5=SCFileInfo()

    返回fileid(数字),txid(数字),名称(字符串),大小(数字),magic(字符串),md5(十六进制)(字符串)

    2.8.2 SCFileState

    state,stored=SCFileState()

    返回状态(字符串),存储(bool)

    2.9  Alerts

    警报是“packet”记录器的子集:

    function init (args)

        local needs = {}

        needs["type"] = "packet"

        needs["filter"] = "alerts"

        return needs

    end

    2.9.1 SCRuleIds

    sid,rev,gid=SCRuleIds()

    2.9.2 SCRuleMsg

    msg=SCRuleMsg()

    2.9.3 SCRuleClass

    class,prio=SCRuleClass()

    2.10Streaming Data

    流数据当前可以注销重组的TCP数据和规范化的HTTP数据。将为每个连续数据块调用该脚本。

    在TCP重组数据的情况下,根据主机OS设置删除所有可能的重叠。

    function init (args)

        local needs = {}

        needs["type"] = "streaming"

        needs["filter"] = "tcp"

        return needs

    end

    在HTTP正文数据的情况下,如果适用,将解压缩并释放正文

    function init (args)

        local needs = {}

        needs["type"] = "streaming"

        needs["protocol"] = "http"

        return needs

    end

    2.10.1 SCStreamingBuffer

    function log(args)

        data = SCStreamingBuffer()

        hex_dump(data)

    end

    2.11 Flow variables

    可以从Lua访问,定义和修改Flow变量。为此,您必须使用本节中描述的函数并在init函数中声明计数器:

    function init(args)

        local needs = {}

        needs["tls"] tostring(true)

        needs["flowint"] = {"tls-cnt"}

        return needs

    end

    在这里,我们定义了一个tls-cnt Flowint,现在可以通过专用函数在输出或签名中使用。对Flow变量的访问是通过索引完成的,所以在我们的例子中我们需要使用0。

    function match(args)

        a = ScFlowintGet(0);

        if a then

            ScFlowintSet(0, a + 1)

        else

            ScFlowintSet(0, 1)

        end

    2.11.1 ScFlowintGet

    获取Flowint在参数给定的索引处

    2.11.2 ScFlowintSet

    将Flowint设置为第一个参数给定的索引。第二个参数是值。

    2.11.3 ScFlowintIncr

    在第一个参数给出的索引处递增Flowint。

    2.11.4 ScFlowintDecr

    在第一个参数给出的索引处减少Flowint。

    2.11.5 ScFlowvarGet

    获取参数给定的索引处的Flowvar。

    2.11.6 ScFlowvarSet

    设置Flowvar。第一个参数是索引,第二个是数据,第三个是数据长度。

    您可以使用它来设置字符串

    function init (args)

        local needs = {}

        needs["http.request_headers"] = tostring(true)

        needs["flowvar"] = {"cnt"}

        return needs

    end

    function match(args)

        a = ScFlowvarGet(0);

        if a then

            a = tostring(tonumber(a)+1)

            ScFlowvarSet(0, a, #a)

        else

            a = tostring(1)

            ScFlowvarSet(0, a, #a)

        end

    2.12 Misc

    2.12.1 SCThreadInfo

    tid,tname,tgroup=SCThreadInfo()

    它给出:tid(整数),tname(字符串),tgroup(字符串)

    2.12.2 SCLogError, SCLogWarning, SCLogNotice, SCLogInfo, SCLogDebug

    打印一条消息。它将进入yaml中定义的输出。是否打印取决于日志级别。

    如:

    SCLogError("some error message")

    2.12.3 SCLogPath

    公开日志路径

    name = "fast_lua.log"

    function setup (args)

        filename = SCLogPath() .. "/" .. name

        file = assert(io.open(filename, "a"))

    end

    相关文章

      网友评论

          本文标题:lua 支持

          本文链接:https://www.haomeiwen.com/subject/cgkshctx.html