suricata
detect-ssl-version.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-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 detect-ssl-version.c
20  *
21  * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
22  *
23  */
24 
25 /**
26  * \test DetectSslVersionTestParse01 is a test to make sure that we parse the
27  * "ssl_version" option correctly when given valid ssl_version option
28  */
29 static int DetectSslVersionTestParse01(void)
30 {
31  DetectSslVersionData *ssl = NULL;
32  ssl = DetectSslVersionParse("SSlv3");
33  FAIL_IF_NULL(ssl);
35  DetectSslVersionFree(ssl);
36  PASS;
37 }
38 
39 /**
40  * \test DetectSslVersionTestParse02 is a test to make sure that we parse the
41  * "ssl_version" option correctly when given an invalid ssl_version option
42  * it should return ssl = NULL
43  */
44 static int DetectSslVersionTestParse02(void)
45 {
46  DetectSslVersionData *ssl = NULL;
47  ssl = DetectSslVersionParse("2.5");
48  FAIL_IF_NOT_NULL(ssl);
49  DetectSslVersionFree(ssl);
50  PASS;
51 }
52 
53 /**
54  * \test DetectSslVersionTestParse03 is a test to make sure that we parse the
55  * "ssl_version" options correctly when given valid ssl_version options
56  */
57 static int DetectSslVersionTestParse03(void)
58 {
59  DetectSslVersionData *ssl = NULL;
60  ssl = DetectSslVersionParse("SSlv3,tls1.0, !tls1.2");
61  FAIL_IF_NULL(ssl);
66  DetectSslVersionFree(ssl);
67  PASS;
68 }
69 
70 #include "stream-tcp-reassemble.h"
71 
72 /** \test Send a get request in three chunks + more data. */
73 static int DetectSslVersionTestDetect01(void)
74 {
75  Flow f;
76  uint8_t sslbuf1[] = { 0x16 };
77  uint32_t ssllen1 = sizeof(sslbuf1);
78  uint8_t sslbuf2[] = { 0x03 };
79  uint32_t ssllen2 = sizeof(sslbuf2);
80  uint8_t sslbuf3[] = { 0x01 };
81  uint32_t ssllen3 = sizeof(sslbuf3);
82  uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x01 };
83  uint32_t ssllen4 = sizeof(sslbuf4);
84  TcpSession ssn;
85  Packet *p = NULL;
86  Signature *s = NULL;
87  ThreadVars th_v;
88  DetectEngineThreadCtx *det_ctx = NULL;
90 
91  memset(&th_v, 0, sizeof(th_v));
92  memset(&f, 0, sizeof(f));
93  memset(&ssn, 0, sizeof(ssn));
94 
95  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
96 
97  FLOW_INITIALIZE(&f);
98  f.protoctx = (void *)&ssn;
99  f.proto = IPPROTO_TCP;
100  p->flow = &f;
104  f.alproto = ALPROTO_TLS;
105 
107 
109  FAIL_IF_NULL(de_ctx);
110 
111  de_ctx->flags |= DE_QUIET;
112 
113  s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; sid:1;)");
114  FAIL_IF_NULL(s);
115 
116  SigGroupBuild(de_ctx);
117  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
118 
119  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS,
120  STREAM_TOSERVER, sslbuf1, ssllen1);
121  FAIL_IF(r != 0);
122 
123  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER,
124  sslbuf2, ssllen2);
125  FAIL_IF(r != 0);
126 
127  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER,
128  sslbuf3, ssllen3);
129  FAIL_IF(r != 0);
130 
131  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER,
132  sslbuf4, ssllen4);
133  FAIL_IF(r != 0);
134 
135  SSLState *app_state = f.alstate;
136  FAIL_IF_NULL(app_state);
137 
138  FAIL_IF(app_state->client_connp.content_type != 0x16);
139 
141 
142  SCLogDebug("app_state is at %p, app_state->server_connp.version 0x%02X app_state->client_connp.version 0x%02X",
143  app_state, app_state->server_connp.version, app_state->client_connp.version);
144 
145  /* do detect */
146  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
147 
149 
150  AppLayerParserThreadCtxFree(alp_tctx);
151  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
152  DetectEngineCtxFree(de_ctx);
153 
155  FLOW_DESTROY(&f);
156 
157  UTHFreePackets(&p, 1);
158 
159  PASS;
160 }
161 
162 static int DetectSslVersionTestDetect02(void)
163 {
164  Flow f;
165  uint8_t sslbuf1[] = { 0x16 };
166  uint32_t ssllen1 = sizeof(sslbuf1);
167  uint8_t sslbuf2[] = { 0x03 };
168  uint32_t ssllen2 = sizeof(sslbuf2);
169  uint8_t sslbuf3[] = { 0x01 };
170  uint32_t ssllen3 = sizeof(sslbuf3);
171  uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 };
172  uint32_t ssllen4 = sizeof(sslbuf4);
173  TcpSession ssn;
174  Packet *p = NULL;
175  Signature *s = NULL;
176  ThreadVars th_v;
177  DetectEngineThreadCtx *det_ctx = NULL;
179 
180  memset(&th_v, 0, sizeof(th_v));
181  memset(&f, 0, sizeof(f));
182  memset(&ssn, 0, sizeof(ssn));
183 
184  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
185 
186  FLOW_INITIALIZE(&f);
187  f.protoctx = (void *)&ssn;
188  f.proto = IPPROTO_TCP;
189  p->flow = &f;
193  f.alproto = ALPROTO_TLS;
194 
196 
198  FAIL_IF_NULL(de_ctx);
199 
200  de_ctx->flags |= DE_QUIET;
201 
202  s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; sid:1;)");
203  FAIL_IF_NULL(s);
204 
205  SigGroupBuild(de_ctx);
206  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
207 
208  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS,
209  STREAM_TOSERVER, sslbuf1, ssllen1);
210  FAIL_IF(r != 0);
211 
212  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER,
213  sslbuf2, ssllen2);
214  FAIL_IF(r != 0);
215 
216  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER,
217  sslbuf3, ssllen3);
218  FAIL_IF(r != 0);
219 
220  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER,
221  sslbuf4, ssllen4);
222  FAIL_IF(r != 0);
223 
224  SSLState *app_state = f.alstate;
225  FAIL_IF_NULL(app_state);
226 
227  FAIL_IF(app_state->client_connp.content_type != 0x16);
228 
230 
231  /* do detect */
232  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
233 
235 
236  AppLayerParserThreadCtxFree(alp_tctx);
237  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
238  DetectEngineCtxFree(de_ctx);
240  FLOW_DESTROY(&f);
241  UTHFreePackets(&p, 1);
242 
243  PASS;
244 }
245 
246 /**
247  * \brief this function registers unit tests for DetectSslVersion
248  */
249 static void DetectSslVersionRegisterTests(void)
250 {
251  UtRegisterTest("DetectSslVersionTestParse01", DetectSslVersionTestParse01);
252  UtRegisterTest("DetectSslVersionTestParse02", DetectSslVersionTestParse02);
253  UtRegisterTest("DetectSslVersionTestParse03", DetectSslVersionTestParse03);
254  UtRegisterTest("DetectSslVersionTestDetect01",
255  DetectSslVersionTestDetect01);
256  UtRegisterTest("DetectSslVersionTestDetect02",
257  DetectSslVersionTestDetect02);
258 }
#define SCLogDebug(...)
Definition: util-debug.h:335
struct Flow_ * flow
Definition: decode.h:446
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
uint16_t version
#define PASS
Pass the test.
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:767
SSLStateConnp server_connp
#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().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:203
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Signature container.
Definition: detect.h:522
#define TRUE
void * protoctx
Definition: flow.h:400
main detection engine ctx
Definition: detect.h:761
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:292
uint8_t flags
Definition: detect.h:762
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
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:1670
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:364
uint8_t flowflags
Definition: decode.h:440
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
#define DETECT_SSL_VERSION_NEGATED
SSLVersionData data[TLS_SIZE]
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
#define PKT_HAS_FLOW
Definition: decode.h:1094
uint8_t content_type
#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:444
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
Flow data structure.
Definition: flow.h:325
SSLStateConnp client_connp
#define PKT_STREAM_EST
Definition: decode.h:1092
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
DetectEngineCtx * DetectEngineCtxInit(void)