suricata
detect-tls-ja3-hash.c
Go to the documentation of this file.
1 /* Copyright (C) 2019 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  * \file
20  *
21  * \author Mats Klepsland <mats.klepsland@gmail.com>
22  *
23  */
24 
25 #ifndef HAVE_NSS
26 
27 static void DetectTlsJa3HashRegisterTests(void)
28 {
29  /* Don't register any tests */
30 }
31 
32 #else /* HAVE_NSS */
33 
34 /**
35  * \test Test matching on a simple client hello packet
36  */
37 static int DetectTlsJa3HashTest01(void)
38 {
39  /* Client hello */
40  uint8_t buf[] = { 0x16, 0x03, 0x03, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7E,
41  0x03, 0x03, 0x57, 0x04, 0x9F, 0x5D, 0xC9, 0x5C, 0x87,
42  0xAE, 0xF2, 0xA7, 0x4A, 0xFC, 0x59, 0x78, 0x23, 0x31,
43  0x61, 0x2D, 0x29, 0x92, 0xB6, 0x70, 0xA5, 0xA1, 0xFC,
44  0x0E, 0x79, 0xFE, 0xC3, 0x97, 0x37, 0xC0, 0x00, 0x00,
45  0x44, 0x00, 0x04, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0D,
46  0x00, 0x10, 0x00, 0x13, 0x00, 0x16, 0x00, 0x2F, 0x00,
47  0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x35,
48  0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00,
49  0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x40,
50  0x00, 0x41, 0x00, 0x44, 0x00, 0x45, 0x00, 0x66, 0x00,
51  0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B,
52  0x00, 0x84, 0x00, 0x87, 0x00, 0xFF, 0x01, 0x00, 0x00,
53  0x13, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0D, 0x00, 0x00,
54  0x0A, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x2E, 0x63,
55  0x6F, 0x6D, };
56 
57 
58  Flow f;
59  SSLState *ssl_state = NULL;
60  Packet *p = NULL;
61  ThreadVars tv;
62  DetectEngineThreadCtx *det_ctx = NULL;
63  TcpSession ssn;
65 
66  memset(&tv, 0, sizeof(ThreadVars));
67  memset(&f, 0, sizeof(Flow));
68  memset(&ssn, 0, sizeof(TcpSession));
69 
70  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
71  "192.168.1.5", "192.168.1.1",
72  41424, 443);
73 
74  FLOW_INITIALIZE(&f);
75  f.protoctx = (void *)&ssn;
76  f.flags |= FLOW_IPV4;
77  f.proto = IPPROTO_TCP;
79 
80  p->flow = &f;
83  f.alproto = ALPROTO_TLS;
84 
86 
88  FAIL_IF_NULL(de_ctx);
89 
91  de_ctx->flags |= DE_QUIET;
92 
93  Signature *s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
94  "(msg:\"Test ja3.hash\"; ja3.hash; "
95  "content:\"e7eca2baf4458d095b7f45da28c16c34\"; "
96  "sid:1;)");
97  FAIL_IF_NULL(s);
98 
99  SigGroupBuild(de_ctx);
100  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
101 
102  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS,
103  STREAM_TOSERVER, buf, sizeof(buf));
104  FAIL_IF(r != 0);
105 
106  ssl_state = f.alstate;
107  FAIL_IF_NULL(ssl_state);
108 
109  FAIL_IF_NULL(ssl_state->client_connp.ja3_hash);
110 
111  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
112 
114 
115  AppLayerParserThreadCtxFree(alp_tctx);
116  DetectEngineThreadCtxDeinit(&tv, det_ctx);
117  DetectEngineCtxFree(de_ctx);
118 
120  FLOW_DESTROY(&f);
121  UTHFreePacket(p);
122 
123  PASS;
124 }
125 
126 /**
127  * \test Test matching on a simple client hello packet
128  */
129 static int DetectTlsJa3HashTest02(void)
130 {
131  /* Client hello */
132  uint8_t buf[] = { 0x16, 0x03, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xbc,
133  0x03, 0x03, 0x03, 0xb7, 0x16, 0x16, 0x5a, 0xe7, 0xc1,
134  0xbd, 0x46, 0x2f, 0xff, 0xf3, 0x68, 0xb8, 0x6f, 0x6e,
135  0x93, 0xdf, 0x06, 0x6a, 0xa7, 0x2d, 0xa0, 0xea, 0x9f,
136  0x48, 0xb5, 0xe7, 0x91, 0x20, 0xd7, 0x25, 0x00, 0x00,
137  0x1c, 0x0a, 0x0a, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c,
138  0xc0, 0x30, 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x13, 0xc0,
139  0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35,
140  0x00, 0x0a, 0x01, 0x00, 0x00, 0x77, 0x1a, 0x1a, 0x00,
141  0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
142  0x12, 0x00, 0x10, 0x00, 0x00, 0x0d, 0x77, 0x77, 0x77,
143  0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6e,
144  0x6f, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00,
145  0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
146  0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01,
147  0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x05, 0x00,
148  0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00,
149  0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68,
150  0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e,
151  0x31, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a,
152  0x00, 0x0a, 0x00, 0x08, 0xba, 0xba, 0x00, 0x1d, 0x00,
153  0x17, 0x00, 0x18, 0x0a, 0x0a, 0x00, 0x01, 0x00 };
154 
155  Flow f;
156  SSLState *ssl_state = NULL;
157  ThreadVars tv;
158  DetectEngineThreadCtx *det_ctx = NULL;
159  TcpSession ssn;
161 
162  memset(&tv, 0, sizeof(ThreadVars));
163  memset(&f, 0, sizeof(Flow));
164  memset(&ssn, 0, sizeof(TcpSession));
165 
166  Packet *p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
167  "192.168.1.5", "192.168.1.1",
168  41424, 443);
169 
170  FLOW_INITIALIZE(&f);
171  f.protoctx = (void *)&ssn;
172  f.flags |= FLOW_IPV4;
173  f.proto = IPPROTO_TCP;
175 
176  p->flow = &f;
179  f.alproto = ALPROTO_TLS;
180 
182 
184  FAIL_IF_NULL(de_ctx);
185 
187  de_ctx->flags |= DE_QUIET;
188 
189  Signature *s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
190  "(msg:\"Test ja3.hash\"; ja3.hash; "
191  "content:\"bc6c386f480ee97b9d9e52d472b772d8\"; "
192  "sid:1;)");
193  FAIL_IF_NULL(s);
194 
195  SigGroupBuild(de_ctx);
196  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
197 
198  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS,
199  STREAM_TOSERVER, buf, sizeof(buf));
200  FAIL_IF(r != 0);
201 
202  ssl_state = f.alstate;
203  FAIL_IF_NULL(ssl_state);
204 
205  FAIL_IF_NULL(ssl_state->client_connp.ja3_hash);
206 
207  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
208 
210 
211  AppLayerParserThreadCtxFree(alp_tctx);
212  DetectEngineThreadCtxDeinit(&tv, det_ctx);
213  DetectEngineCtxFree(de_ctx);
214 
216  FLOW_DESTROY(&f);
217  UTHFreePacket(p);
218 
219  PASS;
220 }
221 
222 static void DetectTlsJa3HashRegisterTests(void)
223 {
224  UtRegisterTest("DetectTlsJa3HashTest01", DetectTlsJa3HashTest01);
225  UtRegisterTest("DetectTlsJa3HashTest02", DetectTlsJa3HashTest02);
226 }
227 
228 #endif /* HAVE_NSS */
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
struct Flow_ * flow
Definition: decode.h:443
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:344
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Signature container.
Definition: detect.h:496
#define TRUE
void * protoctx
Definition: flow.h:400
main detection engine ctx
Definition: detect.h:724
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
SSLv[2.0|3.[0|1|2|3]] state structure.
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:296
uint8_t flags
Definition: detect.h:725
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
uint16_t mpm_matcher
Definition: detect.h:773
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1742
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
uint8_t flowflags
Definition: decode.h:437
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
int mpm_default_matcher
Definition: util-mpm.h:170
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
#define PKT_HAS_FLOW
Definition: decode.h:1092
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
Per thread variable structure.
Definition: threadvars.h:57
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:441
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
uint8_t protomap
Definition: flow.h:404
Flow data structure.
Definition: flow.h:325
#define FLOW_IPV4
Definition: flow.h:94
uint32_t flags
Definition: flow.h:379
SSLStateConnp client_connp
#define PKT_STREAM_EST
Definition: decode.h:1090
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)