Project

General

Profile

Actions

Support #8534

open
JC JI

Lua detect rule: args["buffer"] is always empty in match() - buffer content inaccessible

Support #8534: Lua detect rule: args["buffer"] is always empty in match() - buffer content inaccessible

Added by jghs chha about 1 month ago. Updated 19 days ago.

Status:
Assigned
Priority:
Normal
Assignee:
Affected Versions:
Label:

Description

In Suricata 8.0.0, when using a Lua script as a detect keyword (lua:buffer.lua) placed after a sticky buffer (e.g., base64_data;lua:buffer.lua;), the args table passed to match() is always empty. Setting needs["buffer"] = true in init() does not populate args["buffer"].

Looking at the source code (detect-lua.c), DetectLuaMatchBuffer() correctly pushes buffer data into the args table, but it appears to never be called. Only DetectLuaMatch() is invoked, which passes an empty table.

Steps to reproduce:

function init(args)
    return {["buffer"] = true}
end
function match(args)
    for k, v in pairs(args) do
        print(k .. "=" .. type(v))
    end
    return 1
end

With rule: alert http any any -> any any (...; base64_data;lua:test.lua; ...)

Output: empty (no keys in args table).

Question: Is this a known limitation or a bug? Will a future version restore the ability for Lua detect scripts to access the current inspection buffer via args["buffer"], similar to older Suricata versions?

Currently the only workaround is to use suricata.http / suricata.packet libraries, which always return the full transaction/packet data regardless of buffer position.

PA Updated by Philippe Antoine 24 days ago Actions #1

  • Status changed from New to Feedback

I think this is because of base64_data which is getting obsolete

Could you instead try more modern transform from_base64 ?
Are you working on raw tcp stream ? Or on a http sticky buffer ?

JC Updated by jghs chha 23 days ago Actions #2

Philippe Antoine wrote in #note-1:

I think this is because of base64_data which is getting obsolete

Could you instead try more modern transform from_base64 ?
Are you working on raw tcp stream ? Or on a http sticky buffer ?

yep! working both on raw tcp and http sticky buffer not possible, not just here with base64_data.

JC Updated by jghs chha 23 days ago · Edited Actions #3

It would be even better if you could give me a buffer.lua script that works well in the HTTP sticky buffer area or TCP. Below is a roundabout strategy I wrote using AI analysis, but it is not perfect and will print all content instead of the specified buffer content.

local packet = require("suricata.packet")
local http = require("suricata.http")

function init(args)
    local needs = {}
    needs["packet"] = true
    return needs
end

function setup()
end

function match(args)
    local tx = http.get_tx()
    if tx then
        -- request
        local req_line = tx:request_line()
        if req_line then
            print("Request line: " .. tostring(req_line))
        end

        local req_headers = tx:request_headers_raw()
        if req_headers then
            print("Request headers:\n" .. tostring(req_headers))
        end

        local req_body = tx:request_body()
        if req_body then
            for i, chunk in ipairs(req_body) do
                print("Request body chunk[" .. i .. "]: " .. tostring(chunk))
            end
        end

        -- response
        local resp_line = tx:response_line()
        if resp_line then
            print("Response line: " .. tostring(resp_line))
        end

        local resp_headers = tx:response_headers_raw()
        if resp_headers then
            print("Response headers:\n" .. tostring(resp_headers))
        end

        local resp_body = tx:response_body()
        if resp_body then
            for i, chunk in ipairs(resp_body) do
                print("Response body chunk[" .. i .. "]: " .. tostring(chunk))
            end
        end
    end

    -- TCP payload
    local p = packet.get()
    if p then
        local payload = p:payload()
        if payload and #payload > 0 then
            print("TCP payload (" .. #payload .. " bytes): " .. payload)
        end
    end

    return 1
end

PA Updated by Philippe Antoine 20 days ago · Edited Actions #4

In Suricata 8.0, (unlike to 7 and before) the init function should not ask for the buffer anymore, see https://docs.suricata.io/en/suricata-8.0.4/rules/lua-detection.html

You should get it directly from the http lib or so

cc @Jason Ish

JI Updated by Jason Ish 19 days ago Actions #5

  • Status changed from Feedback to Assigned
  • Assignee set to Jason Ish
Actions

Also available in: PDF Atom