Fix a couple of problems with signature matching.

- IPv4 CIDR specifications didn't work with dst-ip/src-ip.

    - The "payload-size" condition was unreliable with UDP traffic.
This commit is contained in:
Robin Sommer 2016-10-19 13:48:17 -07:00
parent bd0a374c87
commit 5cf2320fbc
9 changed files with 63 additions and 6 deletions

View file

@ -89,6 +89,10 @@ bool RuleConditionPayloadSize::DoMatch(Rule* rule, RuleEndpointState* state,
// on the pure rules now. // on the pure rules now.
return false; return false;
if ( state->PayloadSize() == 0 )
// We are interested in the first non-empty chunk.
return false;
uint32 payload_size = uint32(state->PayloadSize()); uint32 payload_size = uint32(state->PayloadSize());
switch ( comp ) { switch ( comp ) {

View file

@ -144,7 +144,7 @@ bool RuleHdrTest::operator==(const RuleHdrTest& h)
void RuleHdrTest::PrintDebug() void RuleHdrTest::PrintDebug()
{ {
static const char* str_comp[] = { "<=", ">=", "<", ">", "==", "!=" }; static const char* str_comp[] = { "<=", ">=", "<", ">", "==", "!=" };
static const char* str_prot[] = { "", "ip", "icmp", "tcp", "udp" }; static const char* str_prot[] = { "", "ip", "ipv6", "icmp", "icmpv6", "tcp", "udp", "next", "ipsrc", "ipdst" };
fprintf(stderr, " RuleHdrTest %s[%d:%d] %s", fprintf(stderr, " RuleHdrTest %s[%d:%d] %s",
str_prot[prot], offset, size, str_comp[comp]); str_prot[prot], offset, size, str_comp[comp]);
@ -1095,10 +1095,10 @@ void RuleMatcher::ExecRule(Rule* rule, RuleEndpointState* state, bool eos)
void RuleMatcher::ClearEndpointState(RuleEndpointState* state) void RuleMatcher::ClearEndpointState(RuleEndpointState* state)
{ {
state->payload_size = -1;
ExecPureRules(state, 1); ExecPureRules(state, 1);
state->payload_size = -1;
loop_over_list(state->matchers, j) loop_over_list(state->matchers, j)
state->matchers[j]->state->Clear(); state->matchers[j]->state->Clear();
} }

View file

@ -72,6 +72,7 @@ extern uint32 id_to_uint(const char* id);
class RuleHdrTest { class RuleHdrTest {
public: public:
// Note: Adapt RuleHdrTest::PrintDebug() when changing these enums.
enum Comp { LE, GE, LT, GT, EQ, NE }; enum Comp { LE, GE, LT, GT, EQ, NE };
enum Prot { NOPROT, IP, IPv6, ICMP, ICMPv6, TCP, UDP, NEXT, IPSrc, IPDst }; enum Prot { NOPROT, IP, IPv6, ICMP, ICMPv6, TCP, UDP, NEXT, IPSrc, IPDst };

View file

@ -14,7 +14,7 @@ extern void end_PS();
Rule* current_rule = 0; Rule* current_rule = 0;
const char* current_rule_file = 0; const char* current_rule_file = 0;
static uint8_t mask_to_len(uint32_t mask) static uint8_t ip4_mask_to_len(uint32_t mask)
{ {
if ( mask == 0xffffffff ) if ( mask == 0xffffffff )
return 32; return 32;
@ -23,7 +23,7 @@ static uint8_t mask_to_len(uint32_t mask)
uint8_t len; uint8_t len;
for ( len = 0; len < 32 && (! (x & (1 << len))); ++len ); for ( len = 0; len < 32 && (! (x & (1 << len))); ++len );
return len; return 32 - len;
} }
%} %}
@ -315,7 +315,7 @@ prefix_value:
TOK_IP TOK_IP
{ {
$$ = new IPPrefix(IPAddr(IPv4, &($1.val), IPAddr::Host), $$ = new IPPrefix(IPAddr(IPv4, &($1.val), IPAddr::Host),
mask_to_len($1.mask)); ip4_mask_to_len($1.mask));
} }
| TOK_IP6 | TOK_IP6
; ;

View file

@ -0,0 +1,6 @@
match, foo
match, foo
match, foo
match, foo
match, foo
match, foo

View file

@ -0,0 +1,6 @@
match, foo2
match, foo2
match, foo2
match, foo2
match, foo2
match, foo2

Binary file not shown.

View file

@ -0,0 +1,17 @@
# @TEST-EXEC: bro -r $TRACES/ntp.pcap %INPUT >output
# @TEST-EXEC: btest-diff output
@TEST-START-FILE a.sig
signature foo {
dst-ip == 17.0.0.0/8
ip-proto == udp
event "match"
}
@TEST-END-FILE
event signature_match(state: signature_state, msg: string, data: string)
{
print "match", state$sig_id;
}
@load-sigs ./a.sig

View file

@ -0,0 +1,23 @@
# @TEST-EXEC: bro -r $TRACES/ntp.pcap %INPUT >output
# @TEST-EXEC: btest-diff output
@TEST-START-FILE a.sig
signature foo1 {
ip-proto == udp
payload-size < 1
event "match"
}
signature foo2 {
ip-proto == udp
payload-size > 0
event "match"
}
@TEST-END-FILE
event signature_match(state: signature_state, msg: string, data: string)
{
print "match", state$sig_id;
}
@load-sigs ./a.sig