You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/src/detect-parse.h

118 lines
4.3 KiB
C

/* Copyright (C) 2007-2020 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Victor Julien <victor@inliniac.net>
*/
#ifndef SURICATA_DETECT_PARSE_H
#define SURICATA_DETECT_PARSE_H
#include "app-layer-protos.h"
#include "detect-engine-register.h"
// types from detect.h with only forward declarations for bindgen
typedef struct DetectEngineCtx_ DetectEngineCtx;
typedef struct Signature_ Signature;
typedef struct SigMatchCtx_ SigMatchCtx;
typedef struct SigMatch_ SigMatch;
typedef struct SigMatchData_ SigMatchData;
/** Flags to indicate if the Signature parsing must be done
* switching the source and dest (for ip addresses and ports)
* or otherwise as normal */
enum {
SIG_DIREC_NORMAL,
SIG_DIREC_SWITCHED
};
/** Flags to indicate if are referencing the source of the Signature
* or the destination (for ip addresses and ports)*/
enum {
SIG_DIREC_SRC,
SIG_DIREC_DST
};
/* prototypes */
detect: support multi buffer matching Multi buffer matching is implemented as a way for a rule to match on multiple buffers within the same transaction. Before this patch a rule like: dns.query; content:"example"; dns.query; content:".com"; would be equivalent to: dns.query; content:"example"; content:".com"; If a DNS query would request more than one name, e.g.: DNS: [example.net][something.com] Eeach would be inspected to have both patterns present. Otherwise, it would not be a match. So the rule above would not match, as neither example.net and somthing.com satisfy both conditions at the same time. This patch changes this behavior. Instead of the above, each time the sticky buffer is specified, it creates a separate detection unit. Each buffer is a "multi buffer" sticky buffer will now be evaluated against each "instance" of the sticky buffer. To continue with the above example: DNS: [example.net] <- matches 'dns.query; content:"example";' DNS: [something.com] <- matches 'dns.query; content:".com"' So this would now be a match. To make sure both patterns match in a single query string, the expression 'dns.query; content:"example"; content:".com";' still works for this. This patch doesn't yet enable the behavior for the keywords. That is done in a follow up patch. To be able to implement this the internal storage of parsed rules is changed. Until this patch and array of lists was used, where the index was the buffer id (e.g. http_uri, dns_query). Therefore there was only one list of matches per buffer id. As a side effect this array was always very sparsely populated as many buffers could not be mixed. This patch changes the internal representation. The new array is densely packed: dns.query; content:"1"; dns.query; bsize:1; content:"2"; [type: dns_query][list: content:"1";] [type: dns_query][list: bsize:1; content:"2";] The new scheme allows for multiple instances of the same buffer. These lists are then translated into multiple inspection engines during the final setup of the rule. Ticket: #5784.
2 years ago
int SignatureInitDataBufferCheckExpand(Signature *s);
Signature *SigAlloc(void);
void SigFree(DetectEngineCtx *de_ctx, Signature *s);
Signature *SigInit(DetectEngineCtx *, const char *sigstr);
SigMatchData* SigMatchList2DataArray(SigMatch *head);
void SigParseRegisterTests(void);
Signature *DetectEngineAppendSig(DetectEngineCtx *, const char *);
firewall: start of firewall rules support Config: Firewall rules are like normal rule, with some key differences. They are loaded separate, and first, from: ```yaml firewall-rule-path: /etc/suricata/firewall/ firewall-rule-files: - fw.rules ``` Can also be loaded with --firewall-rules-exclusive: Mostly for QA purposes. Allow -S with --firewall-rules-exclusive, so that firewall and threat detection rules can be tested together. Rules: Differences with regular "threat detection" rules: 1. these rules are evaluated before threat detection rules 2. these rules are evaluated in the order as they appear in the rule file 3. currently only rules specifying an explicit hook at supported a. as a consequence, no rules will be treated as (like) IP-only, PD-only or DE-only Require explicit action scope for firewall rules. Default policy is drop for the firewall tables. Actions: New action "accept" is added to allow traffic in the filter tables. New scope "accept:tx" is added to allow accepting a transaction. Tables: Rulesets are per table. Table processing order: `packet:filter` -> `packet:td` -> `app:*:*` -> `app:td`. Each of the tables has some unique properties: `packet:filter`: - default policy is `drop:packet` - rules are process in order - action scopes are explicit - `drop` or `accept` is immediate - `accept:hook` continues to `packet:td` `packet:td`: - default policy is `accept:hook` - rules are ordered by IDS/IPS ordering logic - action scopes are implicit - actions are queued - continues to `app:*:*` or `alert/action finalize` `app:*:*`: - default policy is `drop:flow` - rules are process in order - action scopes are explicit - `drop` is immediate - `accept` is conditional on possible `drop` from `packet:td` - `accept:hook` continues to `app:td`, `accept:packet` or `accept:flow` continues to `alert/action finalize` `app:td`: - default policy is `accept:hook` - rules are ordered by IDS/IPS ordering logic - action scopes are implicit - actions are queued - continues to `alert/action finalize` Implementation: During sigorder, split into packet:filter, app:*:* and general td. Allow fw rules to work when in pass:flow mode. When firewall mode is enabled, `pass:flow` will not skip the detection engine anymore, but instead process the firewall rules and then apply the pass before inspecting threat detect rules.
5 months ago
Signature *DetectFirewallRuleAppendNew(DetectEngineCtx *, const char *);
SigMatch *SCSigMatchAppendSMToList(DetectEngineCtx *, Signature *, uint16_t, SigMatchCtx *, int);
void SigMatchRemoveSMFromList(Signature *, SigMatch *, int);
int SigMatchListSMBelongsTo(const Signature *, const SigMatch *);
int DetectParseDupSigHashInit(DetectEngineCtx *);
void DetectParseDupSigHashFree(DetectEngineCtx *);
int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx,
Signature *s, const char *arg, int sm_type, int sm_list,
AppProto alproto);
bool SigMatchSilentErrorEnabled(const DetectEngineCtx *de_ctx,
const enum DetectKeywordId id);
bool SigMatchStrictEnabled(const enum DetectKeywordId id);
const char *DetectListToHumanString(int list);
const char *DetectListToString(int list);
void SigTableApplyStrictCommandLineOption(const char *str);
SigMatch *DetectGetLastSM(const Signature *);
SigMatch *DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s);
SigMatch *DetectGetLastSMFromLists(const Signature *s, ...);
SigMatch *DetectGetLastSMByListPtr(const Signature *s, SigMatch *sm_list, ...);
SigMatch *DetectGetLastSMByListId(const Signature *s, int list_id, ...);
int WARN_UNUSED SCDetectSignatureSetAppProto(Signature *s, AppProto alproto);
int WARN_UNUSED DetectSignatureSetMultiAppProto(Signature *s, const AppProto *alprotos);
/* parse regex setup and free util funcs */
#ifndef SURICATA_BINDGEN_H
typedef struct DetectParseRegex {
pcre2_code *regex;
pcre2_match_context *context;
struct DetectParseRegex *next;
} DetectParseRegex;
DetectParseRegex *DetectSetupPCRE2(const char *parse_str, int opts);
bool DetectSetupParseRegexesOpts(const char *parse_str, DetectParseRegex *parse_regex, int opts);
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *parse_regex);
void DetectParseRegexAddToFreeList(DetectParseRegex *parse_regex);
void DetectParseFreeRegexes(void);
void DetectParseFreeRegex(DetectParseRegex *r);
/* parse regex exec */
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str,
int start_offset, int options);
int SC_Pcre2SubstringCopy(
pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen);
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr,
PCRE2_SIZE *bufflen);
#endif
void DetectRegisterAppLayerHookLists(void);
#endif /* SURICATA_DETECT_PARSE_H */