lua: Expose byte extract to lua match scripts

Allow lua match scripts to access variables defined in rule by
byte_extract or byte_math

Issue: 2871
pull/7713/head
Benjamin Wilkins 3 years ago committed by Victor Julien
parent 3de735ae70
commit 57ef80f5ec

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2021 Open Information Security Foundation
/* Copyright (C) 2007-2022 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
@ -481,6 +481,32 @@ static int LuaDecrFlowint(lua_State *luastate)
}
static int LuaGetByteVar(lua_State *luastate)
{
DetectLuaData *ld = NULL;
DetectEngineThreadCtx *det_ctx = LuaStateGetDetCtx(luastate);
if (det_ctx == NULL)
return LuaCallbackError(luastate, "internal error: no ldet_ctx");
int ret = GetLuaData(luastate, &ld);
if (ret != 0)
return ret;
if (!lua_isnumber(luastate, 1)) {
LUA_ERROR("bytevar id not a number");
}
int id = lua_tonumber(luastate, 1);
if (id < 0 || id >= DETECT_LUAJIT_MAX_BYTEVARS) {
LUA_ERROR("bytevar id out of range");
}
uint32_t idx = ld->bytevar[id];
lua_pushinteger(luastate, det_ctx->byte_values[idx]);
return 1;
}
void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld,
DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p, const Signature *s, uint8_t flags)
{
@ -494,6 +520,7 @@ void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld,
LuaStateSetSignature(lua_state, s);
LuaStateSetFlow(lua_state, f);
LuaStateSetDetCtx(lua_state, det_ctx);
if (det_ctx->tx_id_set) {
if (f && f->alstate) {
@ -551,6 +578,9 @@ int LuaRegisterExtensions(lua_State *lua_state)
lua_pushcfunction(lua_state, LuaDecrFlowint);
lua_setglobal(lua_state, "SCFlowintDecr");
lua_pushcfunction(lua_state, LuaGetByteVar);
lua_setglobal(lua_state, "SCByteVarGet");
LuaRegisterFunctions(lua_state);
LuaRegisterHttpFunctions(lua_state);
LuaRegisterDnsFunctions(lua_state);

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2014 Open Information Security Foundation
/* Copyright (C) 2007-2022 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
@ -37,6 +37,8 @@
#include "detect-engine-state.h"
#include "detect-engine-build.h"
#include "detect-byte.h"
#include "flow.h"
#include "flow-var.h"
#include "flow-util.h"
@ -702,7 +704,7 @@ error:
return NULL;
}
static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld)
static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const Signature *s)
{
int status;
@ -774,7 +776,7 @@ static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld)
if (k == NULL)
continue;
/* handle flowvar separately as it has a table as value */
/* handle flowvar and bytes separately as they have a table as value */
if (strcmp(k, "flowvar") == 0) {
if (lua_istable(luastate, -1)) {
lua_pushnil(luastate);
@ -819,6 +821,35 @@ static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld)
}
lua_pop(luastate, 1);
continue;
} else if (strcmp(k, "bytevar") == 0) {
if (lua_istable(luastate, -1)) {
lua_pushnil(luastate);
while (lua_next(luastate, -2) != 0) {
/* value at -1, key is at -2 which we ignore */
const char *value = lua_tostring(luastate, -1);
SCLogDebug("value %s", value);
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(luastate, 1);
if (ld->bytevars == DETECT_LUAJIT_MAX_BYTEVARS) {
SCLogError(SC_ERR_LUA_ERROR, "too many bytevars registered");
goto error;
}
DetectByteIndexType idx;
if (!DetectByteRetrieveSMVar(value, s, &idx)) {
SCLogError(SC_ERR_LUA_ERROR,
"Unknown byte_extract or byte_math var "
"requested by lua script - %s",
value);
goto error;
}
ld->bytevar[ld->bytevars++] = idx;
SCLogDebug("script uses bytevar %u with script id %u", idx, ld->bytevars - 1);
}
}
lua_pop(luastate, 1);
continue;
}
v = lua_tostring(luastate, -1);
@ -986,7 +1017,7 @@ static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *st
if (lua == NULL)
goto error;
if (DetectLuaSetupPrime(de_ctx, lua) == -1) {
if (DetectLuaSetupPrime(de_ctx, lua, s) == -1) {
goto error;
}

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2021 Open Information Security Foundation
/* Copyright (C) 2007-2022 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
@ -36,6 +36,7 @@ typedef struct DetectLuaThreadData {
#define DETECT_LUAJIT_MAX_FLOWVARS 15
#define DETECT_LUAJIT_MAX_FLOWINTS 15
#define DETECT_LUAJIT_MAX_BYTEVARS 15
typedef struct DetectLuaData {
int thread_ctx_id;
@ -48,6 +49,8 @@ typedef struct DetectLuaData {
uint16_t flowints;
uint16_t flowvars;
uint32_t flowvar[DETECT_LUAJIT_MAX_FLOWVARS];
uint16_t bytevars;
uint32_t bytevar[DETECT_LUAJIT_MAX_BYTEVARS];
uint32_t sid;
uint32_t rev;
uint32_t gid;

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Open Information Security Foundation
/* Copyright (C) 2014-2022 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
@ -102,6 +102,8 @@ const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr";
const char lua_ext_key_s[] = "suricata:lua:signature:ptr";
/* key for file pointer */
const char lua_ext_key_file[] = "suricata:lua:file:ptr";
/* key for DetectEngineThreadCtx pointer */
const char lua_ext_key_det_ctx[] = "suricata:lua:det_ctx:ptr";
/* key for streaming buffer pointer */
const char lua_ext_key_streaming_buffer[] = "suricata:lua:streaming_buffer:ptr";
@ -230,6 +232,22 @@ void LuaStateSetFile(lua_State *luastate, File *file)
lua_settable(luastate, LUA_REGISTRYINDEX);
}
/** \brief get DetectEngineThreadCtx pointer from the lua state */
DetectEngineThreadCtx *LuaStateGetDetCtx(lua_State *luastate)
{
lua_pushlightuserdata(luastate, (void *)&lua_ext_key_det_ctx);
lua_gettable(luastate, LUA_REGISTRYINDEX);
void *det_ctx = lua_touserdata(luastate, -1);
return (DetectEngineThreadCtx *)det_ctx;
}
void LuaStateSetDetCtx(lua_State *luastate, DetectEngineThreadCtx *det_ctx)
{
lua_pushlightuserdata(luastate, (void *)&lua_ext_key_det_ctx);
lua_pushlightuserdata(luastate, (void *)det_ctx);
lua_settable(luastate, LUA_REGISTRYINDEX);
}
LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate)
{
lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer);

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Open Information Security Foundation
/* Copyright (C) 2014-2022 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
@ -67,6 +67,9 @@ Signature *LuaStateGetSignature(lua_State *luastate);
/** \brief get file pointer from the lua state */
File *LuaStateGetFile(lua_State *luastate);
/** \brief get detect engine thread context pointer from the lua state */
DetectEngineThreadCtx *LuaStateGetDetCtx(lua_State *luastate);
LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate);
int LuaStateGetDirection(lua_State *luastate);
@ -88,6 +91,8 @@ void LuaStateSetSignature(lua_State *luastate, const Signature *s);
void LuaStateSetFile(lua_State *luastate, File *file);
void LuaStateSetDetCtx(lua_State *luastate, DetectEngineThreadCtx *det_ctx);
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv);
void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b);

Loading…
Cancel
Save