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
DetectTlsJa3HashRegisterTests(void)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 */
DetectTlsJa3HashTest01(void)37 static int DetectTlsJa3HashTest01(void)
38 {
39 /* Client hello */
40 uint8_t buf[] = { 0x16, 0x03, 0x03, 0x00, 0x84, 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;
64 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
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;
78 f.protomap = FlowGetProtoMapping(f.proto);
79
80 p->flow = &f;
81 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
82 p->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
83 f.alproto = ALPROTO_TLS;
84
85 StreamTcpInitConfig(TRUE);
86
87 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
88 FAIL_IF_NULL(de_ctx);
89
90 de_ctx->mpm_matcher = mpm_default_matcher;
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
113 FAIL_IF_NOT(PacketAlertCheck(p, 1));
114
115 AppLayerParserThreadCtxFree(alp_tctx);
116 DetectEngineThreadCtxDeinit(&tv, det_ctx);
117 DetectEngineCtxFree(de_ctx);
118
119 StreamTcpFreeConfig(TRUE);
120 FLOW_DESTROY(&f);
121 UTHFreePacket(p);
122
123 PASS;
124 }
125
126 /**
127 * \test Test matching on a simple client hello packet
128 */
DetectTlsJa3HashTest02(void)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;
160 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
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;
174 f.protomap = FlowGetProtoMapping(f.proto);
175
176 p->flow = &f;
177 p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
178 p->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED;
179 f.alproto = ALPROTO_TLS;
180
181 StreamTcpInitConfig(TRUE);
182
183 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
184 FAIL_IF_NULL(de_ctx);
185
186 de_ctx->mpm_matcher = mpm_default_matcher;
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
209 FAIL_IF_NOT(PacketAlertCheck(p, 1));
210
211 AppLayerParserThreadCtxFree(alp_tctx);
212 DetectEngineThreadCtxDeinit(&tv, det_ctx);
213 DetectEngineCtxFree(de_ctx);
214
215 StreamTcpFreeConfig(TRUE);
216 FLOW_DESTROY(&f);
217 UTHFreePacket(p);
218
219 PASS;
220 }
221
DetectTlsJa3HashRegisterTests(void)222 static void DetectTlsJa3HashRegisterTests(void)
223 {
224 UtRegisterTest("DetectTlsJa3HashTest01", DetectTlsJa3HashTest01);
225 UtRegisterTest("DetectTlsJa3HashTest02", DetectTlsJa3HashTest02);
226 }
227
228 #endif /* HAVE_NSS */
229