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  void *tx; // Quic or TLS Transaction
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 = (struct LuaTx *)lua_newuserdata(L, sizeof(*ltx));
53  if (ltx == NULL) {
54  return LuaCallbackError(L, "error: fail to allocate user data");
55  }
56  ltx->tx = tx;
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 = luaL_testudata(L, 1, ja3_tx);
68  if (ltx == NULL) {
69  lua_pushnil(L);
70  return 1;
71  }
72  if (ltx->alproto == ALPROTO_TLS) {
73  SSLState *ssl_state = (SSLState *)ltx->tx;
74  if (ssl_state->client_connp.ja3_hash == NULL) {
75  lua_pushnil(L);
76  return 1;
77  }
78  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->client_connp.ja3_hash,
79  strlen(ssl_state->client_connp.ja3_hash));
80  } // else QUIC {
81  const uint8_t *buf = NULL;
82  uint32_t b_len = 0;
83  if (!SCQuicTxGetJa3(ltx->tx, STREAM_TOSERVER, &buf, &b_len)) {
84  lua_pushnil(L);
85  return 1;
86  }
87  uint8_t ja3_hash[SC_MD5_HEX_LEN + 1];
88  // this adds a final zero
89  SCMd5HashBufferToHex(buf, b_len, (char *)ja3_hash, SC_MD5_HEX_LEN + 1);
90  return LuaPushStringBuffer(L, ja3_hash, SC_MD5_HEX_LEN);
91 }
92 
93 static int LuaJa3TxGetString(lua_State *L)
94 {
95  struct LuaTx *ltx = luaL_testudata(L, 1, ja3_tx);
96  if (ltx == NULL) {
97  lua_pushnil(L);
98  return 1;
99  }
100  if (ltx->alproto == ALPROTO_TLS) {
101  SSLState *ssl_state = (SSLState *)ltx->tx;
102  if (ssl_state->client_connp.ja3_str == NULL ||
103  ssl_state->client_connp.ja3_str->data == NULL) {
104  lua_pushnil(L);
105  return 1;
106  }
107  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->client_connp.ja3_str->data,
108  ssl_state->client_connp.ja3_str->used);
109  } // else QUIC {
110  const uint8_t *buf = NULL;
111  uint32_t b_len = 0;
112  if (!SCQuicTxGetJa3(ltx->tx, STREAM_TOSERVER, &buf, &b_len)) {
113  lua_pushnil(L);
114  return 1;
115  }
116  return LuaPushStringBuffer(L, buf, b_len);
117 }
118 
119 static int LuaJa3TxGetServerHash(lua_State *L)
120 {
121  struct LuaTx *ltx = luaL_testudata(L, 1, ja3_tx);
122  if (ltx == NULL) {
123  lua_pushnil(L);
124  return 1;
125  }
126  if (ltx->alproto == ALPROTO_TLS) {
127  SSLState *ssl_state = (SSLState *)ltx->tx;
128  if (ssl_state->server_connp.ja3_hash == NULL) {
129  lua_pushnil(L);
130  return 1;
131  }
132  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->server_connp.ja3_hash,
133  strlen(ssl_state->server_connp.ja3_hash));
134  } // else QUIC {
135  const uint8_t *buf = NULL;
136  uint32_t b_len = 0;
137  if (!SCQuicTxGetJa3(ltx->tx, STREAM_TOCLIENT, &buf, &b_len)) {
138  lua_pushnil(L);
139  return 1;
140  }
141  uint8_t ja3_hash[SC_MD5_HEX_LEN + 1];
142  // this adds a final zero
143  SCMd5HashBufferToHex(buf, b_len, (char *)ja3_hash, SC_MD5_HEX_LEN + 1);
144  return LuaPushStringBuffer(L, ja3_hash, SC_MD5_HEX_LEN);
145 }
146 
147 static int LuaJa3TxGetServerString(lua_State *L)
148 {
149  struct LuaTx *ltx = luaL_testudata(L, 1, ja3_tx);
150  if (ltx == NULL) {
151  lua_pushnil(L);
152  return 1;
153  }
154  if (ltx->alproto == ALPROTO_TLS) {
155  SSLState *ssl_state = (SSLState *)ltx->tx;
156  if (ssl_state->server_connp.ja3_str == NULL ||
157  ssl_state->server_connp.ja3_str->data == NULL) {
158  lua_pushnil(L);
159  return 1;
160  }
161  return LuaPushStringBuffer(L, (uint8_t *)ssl_state->server_connp.ja3_str->data,
162  ssl_state->server_connp.ja3_str->used);
163  } // else QUIC {
164  const uint8_t *buf = NULL;
165  uint32_t b_len = 0;
166  if (!SCQuicTxGetJa3(ltx->tx, STREAM_TOCLIENT, &buf, &b_len)) {
167  lua_pushnil(L);
168  return 1;
169  }
170  return LuaPushStringBuffer(L, buf, b_len);
171 }
172 
173 static const struct luaL_Reg txlib[] = {
174  // clang-format off
175  { "ja3_get_hash", LuaJa3TxGetHash },
176  { "ja3_get_string", LuaJa3TxGetString },
177  { "ja3s_get_hash", LuaJa3TxGetServerHash },
178  { "ja3s_get_string", LuaJa3TxGetServerString },
179  { NULL, NULL, }
180  // clang-format on
181 };
182 
183 static int LuaJa3Enable(lua_State *L)
184 {
185  SSLEnableJA3();
186  return 1;
187 }
188 
189 static const struct luaL_Reg ja3lib[] = {
190  // clang-format off
191  { "get_tx", LuaJa3GetTx },
192  { "enable_ja3", LuaJa3Enable },
193  { NULL, NULL,},
194  // clang-format on
195 };
196 
198 {
199  luaL_newmetatable(L, ja3_tx);
200  lua_pushvalue(L, -1);
201  lua_setfield(L, -2, "__index");
202  luaL_setfuncs(L, txlib, 0);
203 
204  luaL_newlib(L, ja3lib);
205  return 1;
206 }
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:301
util-lua-common.h
SSLState_::client_connp
SSLStateConnp client_connp
Definition: app-layer-ssl.h:322
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
SSLState_::server_connp
SSLStateConnp server_connp
Definition: app-layer-ssl.h:323
util-lua.h
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:85
ALPROTO_QUIC
@ ALPROTO_QUIC
Definition: app-layer-protos.h:57
LuaCallbackError
int LuaCallbackError(lua_State *luastate, const char *msg)
Definition: util-lua-common.c:59
SSLStateConnp_::ja3_hash
char * ja3_hash
Definition: app-layer-ssl.h:283
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:523
LuaTx
Definition: util-lua-dns.c:34
SSLEnableJA3
void SSLEnableJA3(void)
if not explicitly disabled in config, enable ja3 support
Definition: app-layer-ssl.c:3489
LuaTx::tx
void * tx
Definition: util-lua-ja3.c:36
LuaStateGetTX
void * LuaStateGetTX(lua_State *luastate)
get tx pointer from the lua state
Definition: util-lua.c:134
suricata-common.h
JA3Buffer_::used
uint32_t used
Definition: util-ja3.h:34
SSLStateConnp_::ja3_str
JA3Buffer * ja3_str
Definition: app-layer-ssl.h:282
LuaTx::tx
DNSTransaction * tx
Definition: util-lua-dns.c:35
LuaStateNeedProto
int LuaStateNeedProto(lua_State *luastate, AppProto alproto)
Definition: util-lua-common.c:396
app-layer-ssl.h
SCLuaLoadJa3Lib
int SCLuaLoadJa3Lib(lua_State *L)
Definition: util-lua-ja3.c:197
LuaPushStringBuffer
int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len)
Definition: util-lua.c:319