suricata
detect-mqtt-subscribe-topic.c
Go to the documentation of this file.
1 /* Copyright (C) 2020-2022 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 Sascha Steinbiss <sascha@steinbiss.name>
22  */
23 
24 #include "suricata-common.h"
25 
26 #include "app-layer.h"
27 #include "app-layer-parser.h"
28 
29 #include "conf.h"
30 #include "decode.h"
31 #include "detect.h"
32 #include "detect-content.h"
33 #include "detect-parse.h"
34 #include "detect-pcre.h"
35 #include "detect-engine.h"
37 #include "detect-engine-mpm.h"
40 #include "util-unittest.h"
41 #include "util-unittest-helper.h"
42 
43 #include "rust-bindings.h"
44 
45 #include "threads.h"
46 
47 #include "flow.h"
48 #include "flow-util.h"
49 #include "flow-var.h"
50 
51 #include "util-debug.h"
52 #include "util-spm.h"
53 #include "util-print.h"
54 #include "util-profiling.h"
55 
56 static int DetectMQTTSubscribeTopicSetup(DetectEngineCtx *, Signature *, const char *);
57 
58 static int g_mqtt_subscribe_topic_buffer_id = 0;
59 
60 static uint32_t subscribe_topic_match_limit = 100;
61 
62 static InspectionBuffer *MQTTSubscribeTopicGetData(DetectEngineThreadCtx *det_ctx,
63  const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv,
64  int list_id, uint32_t local_id)
65 {
66  SCEnter();
67 
68  if (subscribe_topic_match_limit > 0 && local_id >= subscribe_topic_match_limit)
69  return NULL;
70 
71  InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id);
72  if (buffer == NULL)
73  return NULL;
74  if (buffer->initialized)
75  return buffer;
76 
77  const uint8_t *data;
78  uint32_t data_len;
79  if (rs_mqtt_tx_get_subscribe_topic(txv, local_id, &data, &data_len) == 0) {
81  return NULL;
82  }
83 
84  InspectionBufferSetupMulti(buffer, transforms, data, data_len);
85  buffer->flags = DETECT_CI_FLAGS_SINGLE;
86 
87  SCReturnPtr(buffer, "InspectionBuffer");
88 }
89 
90 /**
91  * \brief Registration function for keyword: mqtt.subscribe.topic
92  */
94 {
95  sigmatch_table[DETECT_AL_MQTT_SUBSCRIBE_TOPIC].name = "mqtt.subscribe.topic";
96  sigmatch_table[DETECT_AL_MQTT_SUBSCRIBE_TOPIC].desc = "sticky buffer to match MQTT SUBSCRIBE topic";
97  sigmatch_table[DETECT_AL_MQTT_SUBSCRIBE_TOPIC].url = "/rules/mqtt-keywords.html#mqtt-subscribe-topic";
98  sigmatch_table[DETECT_AL_MQTT_SUBSCRIBE_TOPIC].Setup = DetectMQTTSubscribeTopicSetup;
101 
102  intmax_t val = 0;
103  if (ConfGetInt("app-layer.protocols.mqtt.subscribe-topic-match-limit", &val)) {
104  subscribe_topic_match_limit = val;
105  }
106  if (subscribe_topic_match_limit <= 0) {
107  SCLogDebug("Using unrestricted MQTT SUBSCRIBE topic matching");
108  } else {
109  SCLogDebug("Using MQTT SUBSCRIBE topic match-limit setting of: %u",
110  subscribe_topic_match_limit);
111  }
112 
113  DetectAppLayerMultiRegister("mqtt.subscribe.topic", ALPROTO_MQTT, SIG_FLAG_TOSERVER, 1,
114  MQTTSubscribeTopicGetData, 1, 1);
115 
116  DetectBufferTypeSetDescriptionByName("mqtt.subscribe.topic",
117  "subscribe topic query");
118 
119  g_mqtt_subscribe_topic_buffer_id = DetectBufferTypeGetByName("mqtt.subscribe.topic");
120 
121  DetectBufferTypeSupportsMultiInstance("mqtt.subscribe.topic");
122 }
123 
124 /**
125  * \brief setup the sticky buffer keyword used in the rule
126  *
127  * \param de_ctx Pointer to the Detection Engine Context
128  * \param s Pointer to the Signature to which the current keyword belongs
129  * \param str Should hold an empty string always
130  *
131  * \retval 0 On success
132  * \retval -1 On failure
133  */
134 
135 static int DetectMQTTSubscribeTopicSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
136 {
137  if (DetectBufferSetActiveList(de_ctx, s, g_mqtt_subscribe_topic_buffer_id) < 0)
138  return -1;
140  return -1;
141  return 0;
142 }
ConfGetInt
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:399
SigTableElmt_::url
const char * url
Definition: detect.h:1304
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1737
detect-content.h
detect-engine.h
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1509
SigTableElmt_::desc
const char * desc
Definition: detect.h:1303
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:127
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1301
InspectionBuffer::initialized
bool initialized
Definition: detect.h:377
DetectEngineTransforms
Definition: detect.h:408
DetectMQTTSubscribeTopicRegister
void DetectMQTTSubscribeTopicRegister(void)
Registration function for keyword: mqtt.subscribe.topic.
Definition: detect-mqtt-subscribe-topic.c:93
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DetectBufferSetActiveList
int DetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
Definition: detect-engine.c:1349
InspectionBuffer
Definition: detect.h:373
threads.h
Flow_
Flow data structure.
Definition: flow.h:360
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1295
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
DetectBufferTypeSupportsMultiInstance
void DetectBufferTypeSupportsMultiInstance(const char *name)
Definition: detect-engine.c:1036
detect-mqtt-subscribe-topic.h
InspectionBuffer::flags
uint8_t flags
Definition: detect.h:378
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1286
detect-pcre.h
detect-engine-prefilter.h
util-unittest.h
util-unittest-helper.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1086
DetectAppLayerMultiRegister
void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectionMultiBufferGetDataPtr GetData, int priority, int tx_min_progress)
Definition: detect-engine.c:2182
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:267
InspectionBufferSetupMultiEmpty
void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer)
setup the buffer empty
Definition: detect-engine.c:1560
decode.h
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1090
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect-engine-mpm.h
detect.h
app-layer-parser.h
util-profiling.h
DETECT_AL_MQTT_SUBSCRIBE_TOPIC
@ DETECT_AL_MQTT_SUBSCRIBE_TOPIC
Definition: detect-engine-register.h:313
conf.h
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
detect-engine-content-inspection.h
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:49
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
util-spm.h
InspectionBufferSetupMulti
void InspectionBufferSetupMulti(InspectionBuffer *buffer, const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
Definition: detect-engine.c:1573
str
#define str(s)
Definition: suricata-common.h:291
detect-parse.h
Signature_
Signature container.
Definition: detect.h:601
ALPROTO_MQTT
@ ALPROTO_MQTT
Definition: app-layer-protos.h:56
InspectionBufferMultipleForListGet
InspectionBuffer * InspectionBufferMultipleForListGet(DetectEngineThreadCtx *det_ctx, const int list_id, const uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
Definition: detect-engine.c:1513
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1485
DetectBufferTypeSetDescriptionByName
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
Definition: detect-engine.c:1183
flow.h
flow-var.h
app-layer.h