suricata
detect-modbus.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 ANSSI
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * \file
30  *
31  * \author David DIALLO <diallo@et.esiea.fr>
32  *
33  * Implements the Modbus function and access keywords
34  * You can specify a:
35  * - concrete function like Modbus:
36  * function 8, subfunction 4 (diagnostic: Force Listen Only Mode)
37  * - data (in primary table) register access (r/w) like Modbus:
38  * access read coils, address 1000 (.i.e Read coils: at address 1000)
39  * - write data value at specific address Modbus:
40  * access write, address 1500<>2000, value >2000 (Write multiple coils/register:
41  * at address between 1500 and 2000 value greater than 2000)
42  */
43 
44 #include "suricata-common.h"
45 
46 #include "detect.h"
47 #include "detect-parse.h"
48 #include "detect-engine.h"
49 
50 #include "detect-modbus.h"
51 
52 #include "util-debug.h"
53 #include "util-byte.h"
54 
55 #include "stream-tcp.h"
56 #include "rust.h"
57 
58 static int g_modbus_buffer_id = 0;
59 
60 /** \internal
61  *
62  * \brief this function will free memory associated with DetectModbus
63  *
64  * \param ptr pointer to DetectModbus
65  */
66 static void DetectModbusFree(DetectEngineCtx *de_ctx, void *ptr) {
67  SCEnter();
68  if (ptr != NULL) {
69  rs_modbus_free(ptr);
70  }
71  SCReturn;
72 }
73 
74 /** \internal
75  *
76  * \brief this function is used to add the parsed "id" option into the current signature
77  *
78  * \param de_ctx Pointer to the Detection Engine Context
79  * \param s Pointer to the Current Signature
80  * \param str Pointer to the user provided "id" option
81  *
82  * \retval 0 on Success or -1 on Failure
83  */
84 static int DetectModbusSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
85 {
86  SCEnter();
87  DetectModbusRust *modbus = NULL;
88 
90  return -1;
91 
92  if ((modbus = rs_modbus_parse(str)) == NULL) {
93  SCLogError("invalid modbus option");
94  goto error;
95  }
96 
97  /* Okay so far so good, lets get this into a SigMatch and put it in the Signature. */
99  de_ctx, s, DETECT_AL_MODBUS, (SigMatchCtx *)modbus, g_modbus_buffer_id) == NULL) {
100  goto error;
101  }
102 
103  SCReturnInt(0);
104 
105 error:
106  if (modbus != NULL)
107  DetectModbusFree(de_ctx, modbus);
108  SCReturnInt(-1);
109 }
110 
111 static int DetectModbusMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state,
112  void *txv, const Signature *s, const SigMatchCtx *ctx)
113 {
114  return rs_modbus_inspect(txv, (void *)ctx);
115 }
116 
117 /**
118  * \brief Registration function for Modbus keyword
119  */
121 {
123  sigmatch_table[DETECT_AL_MODBUS].desc = "match on various properties of Modbus requests";
124  sigmatch_table[DETECT_AL_MODBUS].url = "/rules/modbus-keyword.html#modbus-keyword";
126  sigmatch_table[DETECT_AL_MODBUS].Setup = DetectModbusSetup;
127  sigmatch_table[DETECT_AL_MODBUS].Free = DetectModbusFree;
128  sigmatch_table[DETECT_AL_MODBUS].AppLayerTxMatch = DetectModbusMatch;
129 
132 
133  g_modbus_buffer_id = DetectBufferTypeGetByName("modbus");
134 }
util-byte.h
SigTableElmt_::url
const char * url
Definition: detect.h:1312
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1738
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1311
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:128
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1299
SigTableElmt_::name
const char * name
Definition: detect.h:1309
stream-tcp.h
ALPROTO_MODBUS
@ ALPROTO_MODBUS
Definition: app-layer-protos.h:42
Flow_
Flow data structure.
Definition: flow.h:356
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:843
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1280
rust.h
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1294
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1094
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:267
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1098
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect.h
SCReturn
#define SCReturn
Definition: util-debug.h:273
detect-modbus.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1277
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:344
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
DetectEngineInspectGenericList
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:2112
DETECT_AL_MODBUS
@ DETECT_AL_MODBUS
Definition: detect-engine-register.h:266
str
#define str(s)
Definition: suricata-common.h:291
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
detect-parse.h
Signature_
Signature container.
Definition: detect.h:603
DetectModbusRegister
void DetectModbusRegister(void)
Registration function for Modbus keyword.
Definition: detect-modbus.c:120
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:240
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:437
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275