Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/userguide/lua/libs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ environment without access to additional modules.
packetlib
rule
ssh
ja3
90 changes: 90 additions & 0 deletions doc/userguide/lua/libs/ja3.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
JA3
---

JA3 details are exposes to Lua scripts with the
``suricata.ja3`` library, For example::

local ja3 = require("suricata.ja3")

If you want to use ja3, you can either set suricata.yaml option
``app-layer.protocols.tls.ja3-fingerprints`` to true,
or specify it in the ``init`` function of your lua script
by calling ``ja3.enable_ja3()``::

function init (args)
ja3.enable_ja3()
return {}
end

``ja3.enable_ja3()`` will not enable ja3 if they are explicitly
disabled, so you should add ``requires: feature ja3;`` to your rule.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks


For use in rule matching, the rule may **hook** into a TLS or QUIC
transaction state if you want to match on only one of these protocols.
Or you should use need ``ja3`` or ``ja3s`` in your init script::
Comment on lines +22 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify what hook means here? Are these rule hooks? If so, I suggest adding a reference to that. If something else, maybe we need rewording or a longer explanation? (or a pointer to where to find more info)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify what hook means here?

Not sure I can do it right, it comes from @jasonish doc about lua dns.

I am removing this as needs["ja3s"] = true looks more appropriate for ja3 lib


function init (args)
ja3.enable_ja3()
local needs = {}
needs["ja3s"] = true
return needs
end

Transaction
~~~~~~~~~~~

JA3 is transaction based, and the current transaction must be obtained before use::

local tx, err = ja3.get_tx()
if tx == err then
print(err)
end

All other functions are methods on the transaction (either a QUIC or a TLS one).

Transaction Methods
~~~~~~~~~~~~~~~~~~~

``ja3_get_hash()``
^^^^^^^^^^^^^^^^^^

Get the ja3 value as a hash.

Example::

local tx = ja3.get_tx()
local h = tx:ja3_get_hash();
print (h)

``ja3_get_string()``
^^^^^^^^^^^^^^^^^^^^

Get the ja3 value as a string.

Example::

local tx = ja3.get_tx()
local s = tx:ja3_get_string();
print (s)

``ja3s_get_hash()``
^^^^^^^^^^^^^^^^^^^

Get the ja3s value as a hash.

Example::

local tx = ja3.get_tx()
local h = tx:ja3s_get_hash();
print (h)

``ja3s_get_string()``
^^^^^^^^^^^^^^^^^^^^^

Get the ja3s value as a string.

Example::

local tx = ja3.get_tx()
local s = tx:ja3s_get_string();
print (s)
120 changes: 0 additions & 120 deletions doc/userguide/lua/lua-functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -348,126 +348,6 @@ Example:
end
end


JA3
---

JA3 must be enabled in the Suricata config file (set 'app-layer.protocols.tls.ja3-fingerprints' to 'yes').

For log output, initialize with:

::

function init (args)
local needs = {}
needs["protocol"] = "tls"
return needs
end

For detection, initialization is as follows:

::

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

Ja3GetHash
~~~~~~~~~~

Get the JA3 hash (md5sum of JA3 string) through Ja3GetHash.

Example:

::

function log (args)
hash = Ja3GetHash()
if hash == nil then
return
end
end

Ja3GetString
~~~~~~~~~~~~

Get the JA3 string through Ja3GetString.

Example:

::

function log (args)
str = Ja3GetString()
if str == nil then
return
end
end

Ja3SGetHash
~~~~~~~~~~~

Get the JA3S hash (md5sum of JA3S string) through JA3SGetHash.

Examples:

::

function log (args)
hash = Ja3SGetHash()
if hash == nil then
return
end
end

Or, for detection:

::

function match (args)
hash = Ja3SGetHash()
if hash == nil then
return 0
end

// matching code

return 0
end

JA3SGetString
~~~~~~~~~~~~~

Get the JA3S string through Ja3SGetString.

Examples:

::

function log (args)
str = Ja3SGetString()
if str == nil then
return
end
end

Or, for detection:

::

function match (args)
str = Ja3SGetString()
if str == nil then
return 0
end

// matching code

return 0
end

Files
-----

Expand Down
20 changes: 12 additions & 8 deletions rust/src/quic/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* 02110-1301, USA.
*/

use crate::core::DetectEngineThreadCtx;
use crate::core::{DetectEngineThreadCtx, STREAM_TOCLIENT, STREAM_TOSERVER};
use crate::quic::quic::QuicTransaction;
use std::os::raw::c_void;
use std::ptr;
Expand Down Expand Up @@ -52,17 +52,21 @@ pub unsafe extern "C" fn SCQuicTxGetSni(

#[no_mangle]
pub unsafe extern "C" fn SCQuicTxGetJa3(
tx: &QuicTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
tx: &QuicTransaction, dir: u8, buffer: *mut *const u8, buffer_len: *mut u32,
) -> bool {
if tx.client {
if dir & STREAM_TOSERVER == 0 {
return false;
}
} else if dir & STREAM_TOCLIENT == 0 {
return false;
}
if let Some(ja3) = &tx.ja3 {
*buffer = ja3.as_ptr();
*buffer_len = ja3.len() as u32;
1
} else {
*buffer = ptr::null();
*buffer_len = 0;
0
return true;
}
return false;
}

#[no_mangle]
Expand Down
2 changes: 0 additions & 2 deletions src/detect-lua-extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

#include "util-lua.h"
#include "util-lua-common.h"
#include "util-lua-ja3.h"
#include "util-lua-tls.h"
#include "util-lua-smtp.h"
#include "util-lua-dnp3.h"
Expand Down Expand Up @@ -121,7 +120,6 @@ int LuaRegisterExtensions(lua_State *lua_state)
lua_setglobal(lua_state, "SCByteVarGet");

LuaRegisterFunctions(lua_state);
LuaRegisterJa3Functions(lua_state);
LuaRegisterTlsFunctions(lua_state);
LuaRegisterSmtpFunctions(lua_state);
return 0;
Expand Down
35 changes: 28 additions & 7 deletions src/detect-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-htp.h"
#include "app-layer-ssl.h"

#include "stream-tcp.h"

Expand All @@ -72,7 +73,8 @@ static int DetectLuaSetup (DetectEngineCtx *, Signature *, const char *);
static void DetectLuaRegisterTests(void);
#endif
static void DetectLuaFree(DetectEngineCtx *, void *);
static int g_smtp_generic_list_id = 0;
static int g_lua_ja3_list_id = 0;
static int g_lua_ja3s_list_id = 0;

/**
* \brief Registration function for keyword: lua
Expand All @@ -89,12 +91,18 @@ void DetectLuaRegister(void)
#ifdef UNITTESTS
sigmatch_table[DETECT_LUA].RegisterTests = DetectLuaRegisterTests;
#endif
g_smtp_generic_list_id = DetectBufferTypeRegister("smtp_generic");

DetectAppLayerInspectEngineRegister("smtp_generic", ALPROTO_SMTP, SIG_FLAG_TOSERVER, 0,
DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister("smtp_generic", ALPROTO_SMTP, SIG_FLAG_TOCLIENT, 0,
DetectEngineInspectGenericList, NULL);
g_lua_ja3_list_id = DetectBufferTypeRegister("ja3.lua");
DetectAppLayerInspectEngineRegister("ja3.lua", ALPROTO_TLS, SIG_FLAG_TOSERVER,
TLS_STATE_CLIENT_HELLO_DONE, DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister(
"ja3.lua", ALPROTO_QUIC, SIG_FLAG_TOSERVER, 1, DetectEngineInspectGenericList, NULL);

g_lua_ja3s_list_id = DetectBufferTypeRegister("ja3s.lua");
DetectAppLayerInspectEngineRegister("ja3s.lua", ALPROTO_TLS, SIG_FLAG_TOCLIENT,
TLS_STATE_SERVER_HELLO_DONE, DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister(
"ja3s.lua", ALPROTO_QUIC, SIG_FLAG_TOCLIENT, 1, DetectEngineInspectGenericList, NULL);

SCLogDebug("registering lua rule option");
}
Expand All @@ -103,6 +111,8 @@ void DetectLuaRegister(void)
#define FLAG_DATATYPE_PACKET BIT_U32(0)
#define FLAG_DATATYPE_PAYLOAD BIT_U32(1)
#define FLAG_DATATYPE_STREAM BIT_U32(2)
#define FLAG_LIST_JA3 BIT_U32(3)
#define FLAG_LIST_JA3S BIT_U32(4)
#define FLAG_DATATYPE_BUFFER BIT_U32(22)
#define FLAG_ERROR_LOGGED BIT_U32(23)
#define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
Expand Down Expand Up @@ -658,7 +668,11 @@ static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const
continue;
}

if (strcmp(k, "packet") == 0) {
if (strcmp(k, "ja3") == 0) {
ld->flags |= FLAG_LIST_JA3;
} else if (strcmp(k, "ja3s") == 0) {
ld->flags |= FLAG_LIST_JA3S;
} else if (strcmp(k, "packet") == 0) {
ld->flags |= FLAG_DATATYPE_PACKET;
} else if (strcmp(k, "payload") == 0) {
ld->flags |= FLAG_DATATYPE_PAYLOAD;
Expand Down Expand Up @@ -765,6 +779,13 @@ static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *st
SCLogError("lua failed to set up");
goto error;
}
if (list == 0) {
if (lua->flags & FLAG_LIST_JA3) {
list = g_lua_ja3_list_id;
} else if (lua->flags & FLAG_LIST_JA3S) {
list = g_lua_ja3s_list_id;
}
}

if (SigMatchAppendSMToList(de_ctx, s, DETECT_LUA, (SigMatchCtx *)lua, list) == NULL) {
goto error;
Expand Down
2 changes: 0 additions & 2 deletions src/output-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "util-lua.h"
#include "util-lua-common.h"
#include "util-lua-http.h"
#include "util-lua-ja3.h"
#include "util-lua-tls.h"
#include "util-lua-smtp.h"

Expand Down Expand Up @@ -588,7 +587,6 @@ static lua_State *LuaScriptSetup(const char *filename, LogLuaMasterCtx *ctx)

/* register functions common to all */
LuaRegisterFunctions(luastate);
LuaRegisterJa3Functions(luastate);
LuaRegisterTlsFunctions(luastate);
LuaRegisterSmtpFunctions(luastate);

Expand Down
4 changes: 2 additions & 2 deletions src/util-ja3.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ InspectionBuffer *Ja3DetectGetHash(DetectEngineThreadCtx *det_ctx,
uint32_t b_len = 0;
const uint8_t *b = NULL;

if (SCQuicTxGetJa3(txv, &b, &b_len) != 1)
if (!SCQuicTxGetJa3(txv, STREAM_TOSERVER | STREAM_TOCLIENT, &b, &b_len))
return NULL;
if (b == NULL || b_len == 0)
return NULL;
Expand All @@ -292,7 +292,7 @@ InspectionBuffer *Ja3DetectGetString(DetectEngineThreadCtx *det_ctx,
uint32_t b_len = 0;
const uint8_t *b = NULL;

if (SCQuicTxGetJa3(txv, &b, &b_len) != 1)
if (!SCQuicTxGetJa3(txv, STREAM_TOSERVER | STREAM_TOCLIENT, &b, &b_len))
return NULL;
if (b == NULL || b_len == 0)
return NULL;
Expand Down
Loading
Loading