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  SigMatch *sm = NULL;
89 
91  return -1;
92 
93  if ((modbus = rs_modbus_parse(str)) == NULL) {
94  SCLogError(SC_ERR_PCRE_MATCH, "invalid modbus option");
95  goto error;
96  }
97 
98  /* Okay so far so good, lets get this into a SigMatch and put it in the Signature. */
99  sm = SigMatchAlloc();
100  if (sm == NULL)
101  goto error;
102 
103  sm->type = DETECT_AL_MODBUS;
104  sm->ctx = (void *) modbus;
105 
106  SigMatchAppendSMToList(s, sm, g_modbus_buffer_id);
107 
108  SCReturnInt(0);
109 
110 error:
111  if (modbus != NULL)
112  DetectModbusFree(de_ctx, modbus);
113  if (sm != NULL)
114  SCFree(sm);
115  SCReturnInt(-1);
116 }
117 
118 static int DetectModbusMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state,
119  void *txv, const Signature *s, const SigMatchCtx *ctx)
120 {
121  return rs_modbus_inspect(txv, (void *)ctx);
122 }
123 
124 /**
125  * \brief Registration function for Modbus keyword
126  */
128 {
130  sigmatch_table[DETECT_AL_MODBUS].desc = "match on various properties of Modbus requests";
131  sigmatch_table[DETECT_AL_MODBUS].url = "/rules/modbus-keyword.html#modbus-keyword";
133  sigmatch_table[DETECT_AL_MODBUS].Setup = DetectModbusSetup;
134  sigmatch_table[DETECT_AL_MODBUS].Free = DetectModbusFree;
135  sigmatch_table[DETECT_AL_MODBUS].AppLayerTxMatch = DetectModbusMatch;
136 
139 
140  g_modbus_buffer_id = DetectBufferTypeGetByName("modbus");
141 }
util-byte.h
SigTableElmt_::url
const char * url
Definition: detect.h:1238
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1493
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1237
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1225
SigTableElmt_::name
const char * name
Definition: detect.h:1235
stream-tcp.h
ALPROTO_MODBUS
@ ALPROTO_MODBUS
Definition: app-layer-protos.h:42
Flow_
Flow data structure.
Definition: flow.h:356
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:784
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1206
rust.h
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1220
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1086
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:228
util-debug.h
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1024
SCEnter
#define SCEnter(...)
Definition: util-debug.h:298
detect.h
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:316
SCReturn
#define SCReturn
Definition: util-debug.h:300
detect-modbus.h
DetectAppLayerInspectEngineRegister2
void DetectAppLayerInspectEngineRegister2(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr2 Callback2, InspectionBufferGetDataPtr GetData)
register inspect engine at start up time
Definition: detect-engine.c:228
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1203
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:238
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:308
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:314
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:76
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:255
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:1951
DETECT_AL_MODBUS
@ DETECT_AL_MODBUS
Definition: detect-engine-register.h:240
str
#define str(s)
Definition: suricata-common.h:280
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-parse.h
Signature_
Signature container.
Definition: detect.h:539
SigMatch_
a single match condition for a signature
Definition: detect.h:313
DetectModbusRegister
void DetectModbusRegister(void)
Registration function for Modbus keyword.
Definition: detect-modbus.c:127
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:302
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:352