suricata
detect-template-rust-buffer.c
Go to the documentation of this file.
1 /* Copyright (C) 2015-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  * TODO: Update the \author in this file and detect-template.h.
20  * TODO: Update description in the \file section below.
21  * TODO: Remove SCLogNotice statements or convert to debug.
22  */
23 
24 /**
25  * \file
26  *
27  * \author FirstName LastName <yourname@domain>
28  *
29  * Set up of the "template_rust" keyword to allow content
30  * inspections on the decoded template application layer buffers.
31  */
32 
33 #include "suricata-common.h"
34 #include "conf.h"
35 #include "detect.h"
36 #include "detect-parse.h"
37 #include "detect-engine.h"
40 #include "app-layer-parser.h"
41 #include "detect-engine-build.h"
42 #include "rust.h"
43 
44 static int DetectTemplateRustBufferSetup(DetectEngineCtx *, Signature *, const char *);
45 static uint8_t DetectEngineInspectTemplateRustBuffer(DetectEngineCtx *de_ctx,
46  DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine,
47  const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
48 #ifdef UNITTESTS
49 static void DetectTemplateRustBufferRegisterTests(void);
50 #endif
51 static int g_template_rust_id = 0;
52 
54 {
55  /* TEMPLATE_START_REMOVE */
56  if (ConfGetNode("app-layer.protocols.template-rust") == NULL) {
57  return;
58  }
59  /* TEMPLATE_END_REMOVE */
60  sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].name = "template_rust_buffer";
62  "Template content modifier to match on the template buffers";
63  sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].Setup = DetectTemplateRustBufferSetup;
64 #ifdef UNITTESTS
65  sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].RegisterTests = DetectTemplateRustBufferRegisterTests;
66 #endif
68 
69  /* register inspect engines */
71  DetectEngineInspectTemplateRustBuffer, NULL);
73  DetectEngineInspectTemplateRustBuffer, NULL);
74 
75  g_template_rust_id = DetectBufferTypeGetByName("template_buffer");
76 
77  SCLogNotice("Template application layer detect registered.");
78 }
79 
80 static int DetectTemplateRustBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
81 {
82  s->init_data->list = g_template_rust_id;
83 
85  return -1;
86 
87  return 0;
88 }
89 
90 static uint8_t DetectEngineInspectTemplateRustBuffer(DetectEngineCtx *de_ctx,
91  DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine,
92  const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
93 {
95  const uint8_t *data = NULL;
96  uint32_t data_len = 0;
97 
98  if (flags & STREAM_TOSERVER) {
99  rs_template_get_request_buffer(txv, &data, &data_len);
100  } else if (flags & STREAM_TOCLIENT) {
101  rs_template_get_response_buffer(txv, &data, &data_len);
102  }
103 
104  if (data != NULL) {
105  const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f,
106  data, data_len, 0, DETECT_CI_FLAGS_SINGLE,
108  if (match) {
110  }
111  }
112 
113  SCLogNotice("Returning %u.", ret);
114  return ret;
115 }
116 
117 #ifdef UNITTESTS
118 
119 #include "util-unittest.h"
120 #include "util-unittest-helper.h"
121 #include "flow-util.h"
122 #include "stream-tcp.h"
123 #include "detect-engine-alert.h"
124 
125 static int DetectTemplateRustBufferTest(void)
126 {
128  DetectEngineThreadCtx *det_ctx = NULL;
129  DetectEngineCtx *de_ctx = NULL;
130  Flow f;
131  Packet *p;
132  TcpSession tcp;
133  ThreadVars tv;
134  Signature *s;
135 
136  uint8_t request[] = "12:Hello World!";
137 
138  /* Setup flow. */
139  memset(&f, 0, sizeof(Flow));
140  memset(&tcp, 0, sizeof(TcpSession));
141  memset(&tv, 0, sizeof(ThreadVars));
142  p = UTHBuildPacket(request, sizeof(request), IPPROTO_TCP);
143  FLOW_INITIALIZE(&f);
145  f.protoctx = (void *)&tcp;
146  f.proto = IPPROTO_TCP;
147  f.flags |= FLOW_IPV4;
148  p->flow = &f;
151  StreamTcpInitConfig(true);
152 
155 
156  /* This rule should match. */
157  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any ("
158  "msg:\"TEMPLATE Test Rule\"; "
159  "template_rust_buffer; content:\"World!\"; "
160  "sid:1; rev:1;)");
161  FAIL_IF_NULL(s);
162 
163  /* This rule should not match. */
164  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any ("
165  "msg:\"TEMPLATE Test Rule\"; "
166  "template_rust_buffer; content:\"W0rld!\"; "
167  "sid:2; rev:1;)");
168  FAIL_IF_NULL(s);
169 
171  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
172 
174  NULL, alp_tctx, &f, ALPROTO_TEMPLATE, STREAM_TOSERVER, request, sizeof(request));
175 
176  /* Check that we have app-layer state. */
178 
179  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
180  FAIL_IF(!PacketAlertCheck(p, 1));
181  FAIL_IF(PacketAlertCheck(p, 2));
182 
183  /* Cleanup. */
184  if (alp_tctx != NULL)
186  if (det_ctx != NULL)
187  DetectEngineThreadCtxDeinit(&tv, det_ctx);
188  if (de_ctx != NULL)
190  if (de_ctx != NULL)
192  StreamTcpFreeConfig(true);
193  FLOW_DESTROY(&f);
194  UTHFreePacket(p);
195 
196  PASS;
197 }
198 
199 static void DetectTemplateRustBufferRegisterTests(void)
200 {
201  UtRegisterTest("DetectTemplateRustBufferTest",
202  DetectTemplateRustBufferTest);
203 }
204 #endif /* UNITTESTS */
DetectEngineAppInspectionEngine_
Definition: detect.h:424
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1753
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1295
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1018
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1293
stream-tcp.h
detect-template-rust-buffer.h
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Flow_::proto
uint8_t proto
Definition: flow.h:372
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
Packet_::flags
uint32_t flags
Definition: decode.h:473
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:181
Flow_
Flow data structure.
Definition: flow.h:350
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1287
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:836
DETECT_AL_TEMPLATE_BUFFER
@ DETECT_AL_TEMPLATE_BUFFER
Definition: detect-engine-register.h:292
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2580
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:312
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:222
rust.h
UTHBuildPacket
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.
Definition: util-unittest-helper.c:338
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1884
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2620
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:467
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:264
Flow_::protoctx
void * protoctx
Definition: flow.h:440
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1278
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:96
util-unittest.h
util-unittest-helper.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1119
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:359
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:263
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1092
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
SignatureInitData_::list
int list
Definition: detect.h:562
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DETECT_ENGINE_INSPECT_SIG_MATCH
#define DETECT_ENGINE_INSPECT_SIG_MATCH
Definition: detect-engine-state.h:38
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
Definition: detect-engine-content-inspection.h:36
app-layer-parser.h
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2211
Packet_
Definition: decode.h:436
detect-engine-build.h
detect-engine-alert.h
conf.h
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:662
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2142
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:291
detect-engine-content-inspection.h
DetectEngineAppInspectionEngine_::smd
SigMatchData * smd
Definition: detect.h:441
Packet_::flow
struct Flow_ * flow
Definition: decode.h:475
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3291
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:49
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:690
flags
uint8_t flags
Definition: decode-gre.h:0
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1303
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3501
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:127
DETECT_ENGINE_INSPECT_SIG_NO_MATCH
#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH
Definition: detect-engine-state.h:37
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
str
#define str(s)
Definition: suricata-common.h:291
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:486
Flow_::alstate
void * alstate
Definition: flow.h:475
Flow_::flags
uint32_t flags
Definition: flow.h:420
detect-parse.h
Signature_
Signature container.
Definition: detect.h:593
ALPROTO_TEMPLATE
@ ALPROTO_TEMPLATE
Definition: app-layer-protos.h:59
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:224
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2541
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1473
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
register inspect engine at start up time
Definition: detect-engine.c:216
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:65
DetectTemplateRustBufferRegister
void DetectTemplateRustBufferRegister(void)
Definition: detect-template-rust-buffer.c:53
TcpSession_
Definition: stream-tcp-private.h:283
DetectEngineContentInspection
bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode)
wrapper around DetectEngineContentInspectionInternal to return true/false only
Definition: detect-engine-content-inspection.c:723
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:237
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:449
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1015
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1285