suricata
util-lua-ja3.c
Go to the documentation of this file.
1 /* Copyright (C) 2017 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 
19 /**
20  * \file
21  *
22  * \author Mats Klepsland <mats.klepsland@gmail.com>
23  *
24  */
25 
26 #include "suricata-common.h"
27 #include "util-lua-ja3.h"
28 #include "util-lua.h"
29 #include "util-lua-common.h"
30 #include "app-layer-ssl.h"
31 #include "rust.h"
32 
33 static const char ja3_tx[] = "suricata:ja3:tx";
34 
35 struct LuaTx {
36  SCLuaTxRef ref; // (flow, tx id); the state is resolved on demand
38 };
39 
40 static int LuaJa3GetTx(lua_State *L)
41 {
42  AppProto alproto = ALPROTO_QUIC;
44  alproto = ALPROTO_TLS;
45  } else if (!(LuaStateNeedProto(L, ALPROTO_QUIC))) {
46  return LuaCallbackError(L, "error: protocol nor tls neither quic");
47  }
48  void *tx = LuaStateGetTX(L);
49  if (tx == NULL) {
50  return LuaCallbackError(L, "error: no tx available");
51  }
52  struct LuaTx *ltx = SCLuaNewUserData(L, SCLUA_TUD_JA3_TX, sizeof(*ltx));
53  if (ltx == NULL) {
54  return LuaCallbackError(L, "error: fail to allocate user data");
55  }
56  SCLuaTxRefInit(L, &ltx->ref, LuaStateGetTxId(L));
57  ltx->alproto = alproto;
58 
59  luaL_getmetatable(L, ja3_tx);
60  lua_setmetatable(L, -2);
61 
62  return 1;
63 }
64 
65 static int LuaJa3TxGetHash(lua_State *L)
66 {
67  struct LuaTx *ltx = SCLuaTestUserData(L, 1, ja3_tx, SCLUA_TUD_JA3_TX);
68  if (ltx == NULL) {
69  lua_pushnil(L);
70  return 1;
71  }
72  SCLUA_RESOLVE_TX(L, &ltx->ref, txptr);
73  if (ltx->alproto == ALPROTO_TLS) {
74  SSLState *ssl_state = (SSLState *)txptr;
75  if (ssl_state->client_connp.ja3_hash == NULL) {
76  lua_pushnil(L);
77  return 1;
78  }
79  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->client_connp.ja3_hash,
80  strlen(ssl_state->client_connp.ja3_hash));
81  } // else QUIC {
82  const uint8_t *buf = NULL;
83  uint32_t b_len = 0;
84  if (!SCQuicTxGetJa3(txptr, STREAM_TOSERVER, &buf, &b_len)) {
85  lua_pushnil(L);
86  return 1;
87  }
88  uint8_t ja3_hash[SC_MD5_HEX_LEN + 1];
89  // this adds a final zero
90  SCMd5HashBufferToHex(buf, b_len, (char *)ja3_hash, SC_MD5_HEX_LEN + 1);
91  return LuaPushStringBuffer(L, ja3_hash, SC_MD5_HEX_LEN);
92 }
93 
94 static int LuaJa3TxGetString(lua_State *L)
95 {
96  struct LuaTx *ltx = SCLuaTestUserData(L, 1, ja3_tx, SCLUA_TUD_JA3_TX);
97  if (ltx == NULL) {
98  lua_pushnil(L);
99  return 1;
100  }
101  SCLUA_RESOLVE_TX(L, &ltx->ref, txptr);
102  if (ltx->alproto == ALPROTO_TLS) {
103  SSLState *ssl_state = (SSLState *)txptr;
104  if (ssl_state->client_connp.ja3_str == NULL ||
105  ssl_state->client_connp.ja3_str->data == NULL) {
106  lua_pushnil(L);
107  return 1;
108  }
109  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->client_connp.ja3_str->data,
110  ssl_state->client_connp.ja3_str->used);
111  } // else QUIC {
112  const uint8_t *buf = NULL;
113  uint32_t b_len = 0;
114  if (!SCQuicTxGetJa3(txptr, STREAM_TOSERVER, &buf, &b_len)) {
115  lua_pushnil(L);
116  return 1;
117  }
118  return LuaPushStringBuffer(L, buf, b_len);
119 }
120 
121 static int LuaJa3TxGetServerHash(lua_State *L)
122 {
123  struct LuaTx *ltx = SCLuaTestUserData(L, 1, ja3_tx, SCLUA_TUD_JA3_TX);
124  if (ltx == NULL) {
125  lua_pushnil(L);
126  return 1;
127  }
128  SCLUA_RESOLVE_TX(L, &ltx->ref, txptr);
129  if (ltx->alproto == ALPROTO_TLS) {
130  SSLState *ssl_state = (SSLState *)txptr;
131  if (ssl_state->server_connp.ja3_hash == NULL) {
132  lua_pushnil(L);
133  return 1;
134  }
135  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->server_connp.ja3_hash,
136  strlen(ssl_state->server_connp.ja3_hash));
137  } // else QUIC {
138  const uint8_t *buf = NULL;
139  uint32_t b_len = 0;
140  if (!SCQuicTxGetJa3(txptr, STREAM_TOCLIENT, &buf, &b_len)) {
141  lua_pushnil(L);
142  return 1;
143  }
144  uint8_t ja3_hash[SC_MD5_HEX_LEN + 1];
145  // this adds a final zero
146  SCMd5HashBufferToHex(buf, b_len, (char *)ja3_hash, SC_MD5_HEX_LEN + 1);
147  return LuaPushStringBuffer(L, ja3_hash, SC_MD5_HEX_LEN);
148 }
149 
150 static int LuaJa3TxGetServerString(lua_State *L)
151 {
152  struct LuaTx *ltx = SCLuaTestUserData(L, 1, ja3_tx, SCLUA_TUD_JA3_TX);
153  if (ltx == NULL) {
154  lua_pushnil(L);
155  return 1;
156  }
157  SCLUA_RESOLVE_TX(L, &ltx->ref, txptr);
158  if (ltx->alproto == ALPROTO_TLS) {
159  SSLState *ssl_state = (SSLState *)txptr;
160  if (ssl_state->server_connp.ja3_str == NULL ||
161  ssl_state->server_connp.ja3_str->data == NULL) {
162  lua_pushnil(L);
163  return 1;
164  }
165  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->server_connp.ja3_str->data,
166  ssl_state->server_connp.ja3_str->used);
167  } // else QUIC {
168  const uint8_t *buf = NULL;
169  uint32_t b_len = 0;
170  if (!SCQuicTxGetJa3(txptr, STREAM_TOCLIENT, &buf, &b_len)) {
171  lua_pushnil(L);
172  return 1;
173  }
174  return LuaPushStringBuffer(L, buf, b_len);
175 }
176 
177 static const struct luaL_Reg txlib[] = {
178  // clang-format off
179  { "ja3_get_hash", LuaJa3TxGetHash },
180  { "ja3_get_string", LuaJa3TxGetString },
181  { "ja3s_get_hash", LuaJa3TxGetServerHash },
182  { "ja3s_get_string", LuaJa3TxGetServerString },
183  { NULL, NULL, }
184  // clang-format on
185 };
186 
187 static int LuaJa3Enable(lua_State *L)
188 {
189  SSLEnableJA3();
190  /* global, parse-time switch: no result to return */
191  return 0;
192 }
193 
194 static const struct luaL_Reg ja3lib[] = {
195  // clang-format off
196  { "get_tx", LuaJa3GetTx },
197  { "enable_ja3", LuaJa3Enable },
198  { NULL, NULL,},
199  // clang-format on
200 };
201 
203 {
204  luaL_newmetatable(L, ja3_tx);
205  lua_pushvalue(L, -1);
206  lua_setfield(L, -2, "__index");
207  luaL_setfuncs(L, txlib, 0);
208 
209  luaL_newlib(L, ja3lib);
210  return 1;
211 }
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:265
LuaTx::ref
SCLuaTxRef ref
Definition: util-lua-dns.c:35
util-lua-common.h
SSLState_::client_connp
SSLStateConnp client_connp
Definition: app-layer-ssl.h:286
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
SSLState_::server_connp
SSLStateConnp server_connp
Definition: app-layer-ssl.h:287
util-lua.h
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:87
ALPROTO_QUIC
@ ALPROTO_QUIC
Definition: app-layer-protos.h:57
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:218
SCLuaTxRef_
Definition: util-lua-common.h:92
SSLStateConnp_::ja3_hash
char * ja3_hash
Definition: app-layer-ssl.h:245
util-lua-ja3.h
JA3Buffer_::data
char * data
Definition: util-ja3.h:32
rust.h
LuaTx::alproto
AppProto alproto
Definition: util-lua-ja3.c:37
lua_State
struct lua_State lua_State
Definition: suricata-common.h:527
LuaTx
Definition: util-lua-dns.c:34
SCLuaTestUserData
void * SCLuaTestUserData(lua_State *L, int idx, const char *mt, uint32_t type_id)
Definition: util-lua-common.c:123
SSLEnableJA3
void SSLEnableJA3(void)
if not explicitly disabled in config, enable ja3 support
Definition: app-layer-ssl.c:3581
SCLuaNewUserData
void * SCLuaNewUserData(lua_State *L, uint32_t type_id, size_t size)
Definition: util-lua-common.c:42
LuaStateGetTX
void * LuaStateGetTX(lua_State *luastate)
get tx pointer from the lua state
Definition: util-lua.c:234
LuaStateGetTxId
uint64_t LuaStateGetTxId(lua_State *luastate)
get tx id from the lua state
Definition: util-lua.c:240
suricata-common.h
JA3Buffer_::used
uint32_t used
Definition: util-ja3.h:34
SCLUA_RESOLVE_TX
#define SCLUA_RESOLVE_TX(L, refp, txvar)
Definition: util-lua-common.h:128
SCLuaTxRefInit
void SCLuaTxRefInit(lua_State *L, SCLuaTxRef *ref, uint64_t tx_id)
Definition: util-lua-common.c:164
SSLStateConnp_::ja3_str
JA3Buffer * ja3_str
Definition: app-layer-ssl.h:244
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:289
app-layer-ssl.h
SCLuaLoadJa3Lib
int SCLuaLoadJa3Lib(lua_State *L)
Definition: util-lua-ja3.c:202
SCLUA_TUD_JA3_TX
@ SCLUA_TUD_JA3_TX
Definition: util-lua-common.h:67
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:380