mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/gh-779-udp-state-sig'
* origin/topic/jsiwek/gh-779-udp-state-sig: GH-779: Add "udp-state" signature condition Rename RuleConditionTCPState::TCPState enum values Rename signature parser tokens to not be TCP-specific
This commit is contained in:
commit
b73cc816e9
11 changed files with 141 additions and 28 deletions
13
CHANGES
13
CHANGES
|
@ -1,4 +1,17 @@
|
||||||
|
|
||||||
|
3.3.0-dev.381 | 2020-10-12 11:15:29 -0700
|
||||||
|
|
||||||
|
* GH-779: Add "udp-state" signature condition (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
It accepts "originator" or "responder" states as a way to enforce that
|
||||||
|
the signature only matches packets in the associated direction.
|
||||||
|
The "established" state is rejected as an error since it doesn't
|
||||||
|
have a useful meaning like it does for the "tcp-state" condition.
|
||||||
|
|
||||||
|
* Rename RuleConditionTCPState::TCPState enum values (Jon Siwek, Corelight)
|
||||||
|
|
||||||
|
* Rename "tcp-state" signature parser tokens to not be TCP-specific (Jon Siwek, Corelight)
|
||||||
|
|
||||||
3.3.0-dev.377 | 2020-10-08 12:07:42 -0700
|
3.3.0-dev.377 | 2020-10-08 12:07:42 -0700
|
||||||
|
|
||||||
* GH-1200: ignore a maybe-uninitialized warning (Jon Siwek, Corelight)
|
* GH-1200: ignore a maybe-uninitialized warning (Jon Siwek, Corelight)
|
||||||
|
|
3
NEWS
3
NEWS
|
@ -34,6 +34,9 @@ New Functionality
|
||||||
See https://docs.zeek.org/en/master/frameworks/logging.html#filter-log-records
|
See https://docs.zeek.org/en/master/frameworks/logging.html#filter-log-records
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
|
- Added a ``udp-state`` signature condition to enforce matching against
|
||||||
|
either "originator" or "responder" flow direction of UDP packets.
|
||||||
|
|
||||||
Changed Functionality
|
Changed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
3.3.0-dev.377
|
3.3.0-dev.381
|
||||||
|
|
2
doc
2
doc
|
@ -1 +1 @@
|
||||||
Subproject commit 2960bd2ee131e1c565da3e02983bbe4b719bc607
|
Subproject commit fd3e22bf5efc42a572e83346031aec4493b3c803
|
|
@ -32,16 +32,16 @@ bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||||
|
|
||||||
auto* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(root);
|
auto* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(root);
|
||||||
|
|
||||||
if ( tcpstates & STATE_STATELESS )
|
if ( tcpstates & RULE_STATE_STATELESS )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( (tcpstates & STATE_ORIG) && ! state->IsOrig() )
|
if ( (tcpstates & RULE_STATE_ORIG) && ! state->IsOrig() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( (tcpstates & STATE_RESP) && state->IsOrig() )
|
if ( (tcpstates & RULE_STATE_RESP) && state->IsOrig() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( (tcpstates & STATE_ESTABLISHED ) &&
|
if ( (tcpstates & RULE_STATE_ESTABLISHED ) &&
|
||||||
! (is_established(ta->Orig()) &&
|
! (is_established(ta->Orig()) &&
|
||||||
is_established(ta->Resp())))
|
is_established(ta->Resp())))
|
||||||
return false;
|
return false;
|
||||||
|
@ -54,6 +54,31 @@ void RuleConditionTCPState::PrintDebug()
|
||||||
fprintf(stderr, " RuleConditionTCPState: 0x%x\n", tcpstates);
|
fprintf(stderr, " RuleConditionTCPState: 0x%x\n", tcpstates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RuleConditionUDPState::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||||
|
const u_char* data, int len)
|
||||||
|
{
|
||||||
|
analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer();
|
||||||
|
|
||||||
|
if ( ! root || ! root->IsAnalyzer("UDP") )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( states & RULE_STATE_STATELESS )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( (states & RULE_STATE_ORIG) && ! state->IsOrig() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( (states & RULE_STATE_RESP) && state->IsOrig() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuleConditionUDPState::PrintDebug()
|
||||||
|
{
|
||||||
|
fprintf(stderr, " RuleConditionUDPState: 0x%x\n", states);
|
||||||
|
}
|
||||||
|
|
||||||
void RuleConditionIPOptions::PrintDebug()
|
void RuleConditionIPOptions::PrintDebug()
|
||||||
{
|
{
|
||||||
fprintf(stderr, " RuleConditionIPOptions: 0x%x\n", options);
|
fprintf(stderr, " RuleConditionIPOptions: 0x%x\n", options);
|
||||||
|
|
|
@ -22,16 +22,16 @@ public:
|
||||||
virtual void PrintDebug() = 0;
|
virtual void PrintDebug() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum RuleStateKind {
|
||||||
|
RULE_STATE_ESTABLISHED = 1,
|
||||||
|
RULE_STATE_ORIG = 2,
|
||||||
|
RULE_STATE_RESP = 4,
|
||||||
|
RULE_STATE_STATELESS = 8
|
||||||
|
};
|
||||||
|
|
||||||
// Implements the "tcp-state" keyword.
|
// Implements the "tcp-state" keyword.
|
||||||
class RuleConditionTCPState : public RuleCondition {
|
class RuleConditionTCPState : public RuleCondition {
|
||||||
public:
|
public:
|
||||||
enum TCPState {
|
|
||||||
STATE_ESTABLISHED = 1,
|
|
||||||
STATE_ORIG = 2,
|
|
||||||
STATE_RESP = 4,
|
|
||||||
STATE_STATELESS = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit RuleConditionTCPState(int arg_tcpstates)
|
explicit RuleConditionTCPState(int arg_tcpstates)
|
||||||
{ tcpstates = arg_tcpstates; }
|
{ tcpstates = arg_tcpstates; }
|
||||||
|
|
||||||
|
@ -46,6 +46,20 @@ private:
|
||||||
int tcpstates;
|
int tcpstates;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implements the "udp-state" keyword.
|
||||||
|
class RuleConditionUDPState : public RuleCondition {
|
||||||
|
public:
|
||||||
|
explicit RuleConditionUDPState(int arg_states)
|
||||||
|
{ states = arg_states; }
|
||||||
|
|
||||||
|
bool DoMatch(Rule* rule, RuleEndpointState* state, const u_char* data,
|
||||||
|
int len) override;
|
||||||
|
|
||||||
|
void PrintDebug() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int states;
|
||||||
|
};
|
||||||
|
|
||||||
// Implements "ip-options".
|
// Implements "ip-options".
|
||||||
class RuleConditionIPOptions : public RuleCondition {
|
class RuleConditionIPOptions : public RuleCondition {
|
||||||
|
|
|
@ -58,15 +58,16 @@ static uint8_t ip4_mask_to_len(uint32_t mask)
|
||||||
%token TOK_SRC_IP
|
%token TOK_SRC_IP
|
||||||
%token TOK_SRC_PORT
|
%token TOK_SRC_PORT
|
||||||
%token TOK_TCP_STATE
|
%token TOK_TCP_STATE
|
||||||
|
%token TOK_UDP_STATE
|
||||||
%token TOK_STRING
|
%token TOK_STRING
|
||||||
%token TOK_TCP_STATE_SYM
|
%token TOK_STATE_SYM
|
||||||
%token TOK_ACTIVE
|
%token TOK_ACTIVE
|
||||||
%token TOK_BOOL
|
%token TOK_BOOL
|
||||||
%token TOK_POLICY_SYMBOL
|
%token TOK_POLICY_SYMBOL
|
||||||
|
|
||||||
%type <str> TOK_STRING TOK_IDENT TOK_POLICY_SYMBOL TOK_PATTERN pattern string
|
%type <str> TOK_STRING TOK_IDENT TOK_POLICY_SYMBOL TOK_PATTERN pattern string
|
||||||
%type <val> TOK_INT TOK_TCP_STATE_SYM TOK_IP_OPTION_SYM TOK_COMP
|
%type <val> TOK_INT TOK_STATE_SYM TOK_IP_OPTION_SYM TOK_COMP
|
||||||
%type <val> integer ipoption_list tcpstate_list opt_strength
|
%type <val> integer ipoption_list state_list opt_strength
|
||||||
%type <rule> rule
|
%type <rule> rule
|
||||||
%type <bl> TOK_BOOL opt_negate
|
%type <bl> TOK_BOOL opt_negate
|
||||||
%type <hdr_test> hdr_expr
|
%type <hdr_test> hdr_expr
|
||||||
|
@ -246,11 +247,19 @@ rule_attr:
|
||||||
(zeek::detail::RuleHdrTest::Comp) $2, $3));
|
(zeek::detail::RuleHdrTest::Comp) $2, $3));
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_TCP_STATE tcpstate_list
|
| TOK_TCP_STATE state_list
|
||||||
{
|
{
|
||||||
current_rule->AddCondition(new zeek::detail::RuleConditionTCPState($2));
|
current_rule->AddCondition(new zeek::detail::RuleConditionTCPState($2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| TOK_UDP_STATE state_list
|
||||||
|
{
|
||||||
|
if ( $2 & zeek::detail::RULE_STATE_ESTABLISHED )
|
||||||
|
rules_error("'established' is not a valid 'udp-state'");
|
||||||
|
|
||||||
|
current_rule->AddCondition(new zeek::detail::RuleConditionUDPState($2));
|
||||||
|
}
|
||||||
|
|
||||||
| TOK_ACTIVE TOK_BOOL
|
| TOK_ACTIVE TOK_BOOL
|
||||||
{ current_rule->SetActiveStatus($2); }
|
{ current_rule->SetActiveStatus($2); }
|
||||||
;
|
;
|
||||||
|
@ -382,10 +391,10 @@ ipoption_list:
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
tcpstate_list:
|
state_list:
|
||||||
tcpstate_list ',' TOK_TCP_STATE_SYM
|
state_list ',' TOK_STATE_SYM
|
||||||
{ $$ = $1 | $3; }
|
{ $$ = $1 | $3; }
|
||||||
| TOK_TCP_STATE_SYM
|
| TOK_STATE_SYM
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -75,23 +75,23 @@ true { rules_lval.val = true; return TOK_BOOL; }
|
||||||
false { rules_lval.val = false; return TOK_BOOL; }
|
false { rules_lval.val = false; return TOK_BOOL; }
|
||||||
|
|
||||||
established {
|
established {
|
||||||
rules_lval.val = zeek::detail::RuleConditionTCPState::STATE_ESTABLISHED;
|
rules_lval.val = zeek::detail::RULE_STATE_ESTABLISHED;
|
||||||
return TOK_TCP_STATE_SYM;
|
return TOK_STATE_SYM;
|
||||||
}
|
}
|
||||||
|
|
||||||
originator {
|
originator {
|
||||||
rules_lval.val = zeek::detail::RuleConditionTCPState::STATE_ORIG;
|
rules_lval.val = zeek::detail::RULE_STATE_ORIG;
|
||||||
return TOK_TCP_STATE_SYM;
|
return TOK_STATE_SYM;
|
||||||
}
|
}
|
||||||
|
|
||||||
responder {
|
responder {
|
||||||
rules_lval.val = zeek::detail::RuleConditionTCPState::STATE_RESP;
|
rules_lval.val = zeek::detail::RULE_STATE_RESP;
|
||||||
return TOK_TCP_STATE_SYM;
|
return TOK_STATE_SYM;
|
||||||
}
|
}
|
||||||
|
|
||||||
stateless {
|
stateless {
|
||||||
rules_lval.val = zeek::detail::RuleConditionTCPState::STATE_STATELESS;
|
rules_lval.val = zeek::detail::RULE_STATE_STATELESS;
|
||||||
return TOK_TCP_STATE_SYM;
|
return TOK_STATE_SYM;
|
||||||
}
|
}
|
||||||
|
|
||||||
lsrr {
|
lsrr {
|
||||||
|
@ -132,6 +132,7 @@ same-ip return TOK_SAME_IP;
|
||||||
src-ip return TOK_SRC_IP;
|
src-ip return TOK_SRC_IP;
|
||||||
src-port return TOK_SRC_PORT;
|
src-port return TOK_SRC_PORT;
|
||||||
tcp-state return TOK_TCP_STATE;
|
tcp-state return TOK_TCP_STATE;
|
||||||
|
udp-state return TOK_UDP_STATE;
|
||||||
active return TOK_ACTIVE;
|
active return TOK_ACTIVE;
|
||||||
|
|
||||||
file-magic { rules_lval.val = zeek::detail::Rule::FILE_MAGIC; return TOK_PATTERN_TYPE; }
|
file-magic { rules_lval.val = zeek::detail::Rule::FILE_MAGIC; return TOK_PATTERN_TYPE; }
|
||||||
|
|
10
testing/btest/Baseline/signatures.udp-state/out
Normal file
10
testing/btest/Baseline/signatures.udp-state/out
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
signature_match [orig_h=192.168.17.58, orig_p=58755/udp, resp_h=8.8.8.8, resp_p=53/udp] - my_sig_udp_orig
|
||||||
|
0000 35 5e 01 00 00 01 00 00 00 00 00 00 06 67 6f 6f 5^...... .....goo
|
||||||
|
0010 67 6c 65 03 63 6f 6d 00 01 01 00 01 gle.com. ....
|
||||||
|
|
||||||
|
signature_match [orig_h=192.168.17.58, orig_p=58755/udp, resp_h=8.8.8.8, resp_p=53/udp] - my_sig_udp_resp
|
||||||
|
0000 35 5e 81 80 00 01 00 01 00 00 00 00 06 67 6f 6f 5^...... .....goo
|
||||||
|
0010 67 6c 65 03 63 6f 6d 00 01 01 00 01 c0 0c 01 01 gle.com. ........
|
||||||
|
0020 00 01 00 00 54 49 00 13 00 05 69 73 73 75 65 73 ....TI.. ..issues
|
||||||
|
0030 79 6d 61 6e 74 65 63 2e 63 6f 6d ymantec. com
|
||||||
|
|
2
testing/btest/Baseline/signatures.udp-state/reject
Normal file
2
testing/btest/Baseline/signatures.udp-state/reject
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
error: Error in signature (udp-established.sig:5): 'established' is not a valid 'udp-state'
|
||||||
|
|
36
testing/btest/signatures/udp-state.zeek
Normal file
36
testing/btest/signatures/udp-state.zeek
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# @TEST-EXEC: zeek -b -s udp-states.sig -r $TRACES/dns-caa.pcap %INPUT >out
|
||||||
|
# @TEST-EXEC-FAIL: zeek -b -s udp-established.sig -r $TRACES/dns-caa.pcap %INPUT >reject 2>&1
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
# @TEST-EXEC: btest-diff reject
|
||||||
|
|
||||||
|
@TEST-START-FILE udp-states.sig
|
||||||
|
signature my_sig_udp_orig {
|
||||||
|
ip-proto == udp
|
||||||
|
payload /.+/
|
||||||
|
udp-state originator
|
||||||
|
event "my_sig_udp_orig"
|
||||||
|
}
|
||||||
|
|
||||||
|
signature my_sig_udp_resp {
|
||||||
|
ip-proto == udp
|
||||||
|
payload /.+/
|
||||||
|
udp-state responder
|
||||||
|
event "my_sig_udp_resp"
|
||||||
|
}
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
@TEST-START-FILE udp-established.sig
|
||||||
|
signature my_sig_udp_est {
|
||||||
|
ip-proto == udp
|
||||||
|
payload /.+/
|
||||||
|
udp-state established
|
||||||
|
event "my_sig_udp_est"
|
||||||
|
}
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
event signature_match(state: signature_state, msg: string, data: string)
|
||||||
|
{
|
||||||
|
print fmt("signature_match %s - %s", state$conn$id, msg);
|
||||||
|
local s = split_string(hexdump(data), /\n/);
|
||||||
|
for ( i in s ) print s[i];
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue