mirror of https://github.com/OISF/suricata
lua/bytevar: convert SCByteVar to Lua lib
Similar to flowvars and flowints, but a byte var cannot be registered from a Lua script, but it still needs to be setup. Instead provide an "map" function that sets it up, or errors out if the byte var is unknown. This also required passing the signature into the Lua init method, as the state of the Signature object and the time of loading the Lua keyword is required.pull/13361/head
parent
5a19c95a07
commit
11b3ebcb5f
@ -0,0 +1,80 @@
|
|||||||
|
Bytevar
|
||||||
|
#######
|
||||||
|
|
||||||
|
The ``suricata.bytevar`` module provides access to variables defined by
|
||||||
|
``byte_extract`` and ``byte_math`` keywords in Suricata rules.
|
||||||
|
|
||||||
|
It is only available in Suricata Lua rules, not output scripts.
|
||||||
|
|
||||||
|
Setup
|
||||||
|
*****
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
local bytevars = require("suricata.bytevar")
|
||||||
|
|
||||||
|
Module Functions
|
||||||
|
****************
|
||||||
|
|
||||||
|
.. function:: bytevars.map(sig, varname)
|
||||||
|
|
||||||
|
Ensures that the ``bytevar`` exists and sets it up for further use
|
||||||
|
in the script by mapping it into the Lua context. Must be called
|
||||||
|
during ``init()``.
|
||||||
|
|
||||||
|
:param sig: The signature object passed to ``init()``
|
||||||
|
:param string varname: Name of the variable as defined in the rule
|
||||||
|
|
||||||
|
:raises error: If the variable name is unknown
|
||||||
|
:raises error: If too many byte variables are mapped
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function init(sig)
|
||||||
|
bytevars.map(sig, "var1")
|
||||||
|
bytevars.map(sig, "var2")
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
.. function:: bytevars.get(name)
|
||||||
|
|
||||||
|
Returns a byte variable object for the given name. May be called
|
||||||
|
during ``thread_init()`` to save a handle to the bytevar.
|
||||||
|
|
||||||
|
:param number name: Name of the variable previously setup with
|
||||||
|
``map()``.
|
||||||
|
|
||||||
|
:raises error: If variable name is not mapped with ``map()``.
|
||||||
|
|
||||||
|
:returns: A byte variable object
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function thread_init()
|
||||||
|
bv_var1 = bytevars.get("var1")
|
||||||
|
bv_var2 = bytevars.get("var2")
|
||||||
|
end
|
||||||
|
|
||||||
|
Byte Variable Object Methods
|
||||||
|
****************************
|
||||||
|
|
||||||
|
.. method:: bytevar:value()
|
||||||
|
|
||||||
|
Returns the current value of the byte variable.
|
||||||
|
|
||||||
|
:returns: The value of the byte variable.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
function match(args)
|
||||||
|
local var1 = bv_var1:value()
|
||||||
|
if var1 then
|
||||||
|
-- Use the value
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,127 @@
|
|||||||
|
/* Copyright (C) 2025 Open Information Security Foundation
|
||||||
|
*
|
||||||
|
* You can copy, redistribute or modify this Program under the terms of
|
||||||
|
* the GNU General Public License version 2 as published by the Free
|
||||||
|
* Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* version 2 along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "suricata-common.h"
|
||||||
|
#include "detect-byte.h"
|
||||||
|
#include "util-lua-common.h"
|
||||||
|
#include "util-lua-bytevarlib.h"
|
||||||
|
#include "util-lua.h"
|
||||||
|
#include "detect-lua.h"
|
||||||
|
#include "detect-lua-extensions.h"
|
||||||
|
|
||||||
|
#include "lauxlib.h"
|
||||||
|
|
||||||
|
static const char suricata_bytevar_mt[] = "suricata:bytevar:mt";
|
||||||
|
|
||||||
|
static DetectLuaData *GetLuaData(lua_State *luastate)
|
||||||
|
{
|
||||||
|
DetectLuaData *ld;
|
||||||
|
lua_pushlightuserdata(luastate, (void *)&luaext_key_ld);
|
||||||
|
lua_gettable(luastate, LUA_REGISTRYINDEX);
|
||||||
|
ld = lua_touserdata(luastate, -1);
|
||||||
|
return ld;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaBytevarMap(lua_State *L)
|
||||||
|
{
|
||||||
|
const Signature *s = lua_touserdata(L, -2);
|
||||||
|
const char *name = luaL_checkstring(L, -1);
|
||||||
|
DetectLuaData *ld = GetLuaData(L);
|
||||||
|
|
||||||
|
/* Is this name already mapped? */
|
||||||
|
for (uint16_t i = 0; i < ld->bytevars; i++) {
|
||||||
|
if (strcmp(ld->bytevar[i].name, name) == 0) {
|
||||||
|
lua_pushinteger(L, ld->bytevar[i].id);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ld->bytevars == DETECT_LUA_MAX_BYTEVARS) {
|
||||||
|
luaL_error(L, "too many bytevars mapped");
|
||||||
|
}
|
||||||
|
|
||||||
|
DetectByteIndexType idx;
|
||||||
|
if (!DetectByteRetrieveSMVar(name, s, &idx)) {
|
||||||
|
luaL_error(L, "unknown byte_extract or byte_math variable: %s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ld->bytevar[ld->bytevars].name = SCStrdup(name);
|
||||||
|
if (ld->bytevar[ld->bytevars].name == NULL) {
|
||||||
|
luaL_error(L, "failed to allocate memory for bytevar name: %s", name);
|
||||||
|
}
|
||||||
|
ld->bytevar[ld->bytevars++].id = idx;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaBytevarGet(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *name = luaL_checkstring(L, 1);
|
||||||
|
DetectLuaData *ld = GetLuaData(L);
|
||||||
|
if (ld == NULL) {
|
||||||
|
return luaL_error(L, "internal error: no lua data");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < ld->bytevars; i++) {
|
||||||
|
if (strcmp(ld->bytevar[i].name, name) == 0) {
|
||||||
|
uint32_t *bytevar_id = lua_newuserdata(L, sizeof(*bytevar_id));
|
||||||
|
*bytevar_id = ld->bytevar[i].id;
|
||||||
|
luaL_getmetatable(L, suricata_bytevar_mt);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return luaL_error(L, "unknown bytevar: %s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LuaBytevarValue(lua_State *L)
|
||||||
|
{
|
||||||
|
uint32_t *bytevar_id = luaL_checkudata(L, 1, suricata_bytevar_mt);
|
||||||
|
DetectEngineThreadCtx *det_ctx = LuaStateGetDetCtx(L);
|
||||||
|
if (det_ctx == NULL) {
|
||||||
|
return LuaCallbackError(L, "internal error: no det_ctx");
|
||||||
|
}
|
||||||
|
lua_pushinteger(L, det_ctx->byte_values[*bytevar_id]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg bytevarlib[] = {
|
||||||
|
// clang-format off
|
||||||
|
{ "map", LuaBytevarMap, },
|
||||||
|
{ "get", LuaBytevarGet, },
|
||||||
|
{ NULL, NULL, },
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_Reg bytevarmt[] = {
|
||||||
|
// clang-format off
|
||||||
|
{ "value", LuaBytevarValue, },
|
||||||
|
{ NULL, NULL, },
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
|
int LuaLoadBytevarLib(lua_State *L)
|
||||||
|
{
|
||||||
|
luaL_newmetatable(L, suricata_bytevar_mt);
|
||||||
|
lua_pushvalue(L, -1);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
luaL_setfuncs(L, bytevarmt, 0);
|
||||||
|
|
||||||
|
luaL_newlib(L, bytevarlib);
|
||||||
|
return 1;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/* Copyright (C) 2025 Open Information Security Foundation
|
||||||
|
*
|
||||||
|
* You can copy, redistribute or modify this Program under the terms of
|
||||||
|
* the GNU General Public License version 2 as published by the Free
|
||||||
|
* Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* version 2 along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SURICATA_UTIL_LUA_BYTEVARLIB_H
|
||||||
|
#define SURICATA_UTIL_LUA_BYTEVARLIB_H
|
||||||
|
|
||||||
|
#include "lua.h"
|
||||||
|
|
||||||
|
int LuaLoadBytevarLib(lua_State *L);
|
||||||
|
|
||||||
|
#endif /* SURICATA_UTIL_LUA_BYTEVARLIB_H */
|
Loading…
Reference in New Issue