mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Add Teredo analysis option to reduce false positive decapsulation.
The Tunnel::yielding_teredo_decapsulation (on by default) makes it so the Teredo analyzer doesn't attempt to decapsulate payloads when there's already a sibling analyzer that thinks it's parsing the right protocol. Sometimes, UDP payloads just happen to look like they are validly Teredo-encapsulated and doing further analysis on the decapsulated packet can quickly turn into a weird; this change helps reduce such weirds.
This commit is contained in:
parent
9ddb70b109
commit
6f346c8406
7 changed files with 92 additions and 2 deletions
|
@ -2705,6 +2705,14 @@ export {
|
||||||
|
|
||||||
## Toggle whether to do IPv6-in-Teredo decapsulation.
|
## Toggle whether to do IPv6-in-Teredo decapsulation.
|
||||||
const enable_teredo = T &redef;
|
const enable_teredo = T &redef;
|
||||||
|
|
||||||
|
## With this option set, the Teredo analysis will first check to see if
|
||||||
|
## other protocol analyzers have confirmed that they think they're
|
||||||
|
## parsing the right protocol and only continue with Teredo tunnel
|
||||||
|
## decapsulation if nothing else has yet confirmed. This can help
|
||||||
|
## reduce false positives of UDP traffic (e.g. DNS) that also happens
|
||||||
|
## to have a valid Teredo encapsulation.
|
||||||
|
const yielding_teredo_decapsulation = T &redef;
|
||||||
} # end export
|
} # end export
|
||||||
module GLOBAL;
|
module GLOBAL;
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,10 @@ private:
|
||||||
for ( analyzer_list::iterator var = the_kids.begin(); \
|
for ( analyzer_list::iterator var = the_kids.begin(); \
|
||||||
var != the_kids.end(); var++ )
|
var != the_kids.end(); var++ )
|
||||||
|
|
||||||
|
#define LOOP_OVER_GIVEN_CONST_CHILDREN(var, the_kids) \
|
||||||
|
for ( analyzer_list::const_iterator var = the_kids.begin(); \
|
||||||
|
var != the_kids.end(); var++ )
|
||||||
|
|
||||||
class SupportAnalyzer : public Analyzer {
|
class SupportAnalyzer : public Analyzer {
|
||||||
public:
|
public:
|
||||||
SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
|
SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig)
|
||||||
|
|
|
@ -158,13 +158,37 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
int rslt = sessions->ParseIPPacket(len, te.InnerIP(), IPPROTO_IPV6, inner);
|
int rslt = sessions->ParseIPPacket(len, te.InnerIP(), IPPROTO_IPV6, inner);
|
||||||
|
|
||||||
if ( rslt == 0 )
|
if ( rslt == 0 )
|
||||||
ProtocolConfirmation();
|
{
|
||||||
|
if ( BifConst::Tunnel::yielding_teredo_decapsulation &&
|
||||||
|
! ProtocolConfirmed() )
|
||||||
|
{
|
||||||
|
// Only confirm the Teredo tunnel and start decapsulating packets
|
||||||
|
// when no other sibling analyzer thinks it's already parsing the
|
||||||
|
// right protocol.
|
||||||
|
bool sibling_has_confirmed = false;
|
||||||
|
if ( Parent() )
|
||||||
|
{
|
||||||
|
LOOP_OVER_GIVEN_CONST_CHILDREN(i, Parent()->GetChildren())
|
||||||
|
{
|
||||||
|
if ( (*i)->ProtocolConfirmed() )
|
||||||
|
sibling_has_confirmed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! sibling_has_confirmed )
|
||||||
|
ProtocolConfirmation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Aggressively decapsulate anything with valid Teredo encapsulation
|
||||||
|
ProtocolConfirmation();
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ( rslt < 0 )
|
else if ( rslt < 0 )
|
||||||
ProtocolViolation("Truncated Teredo", (const char*) data, len);
|
ProtocolViolation("Truncated Teredo", (const char*) data, len);
|
||||||
else
|
else
|
||||||
ProtocolViolation("Teredo payload length", (const char*) data, len);
|
ProtocolViolation("Teredo payload length", (const char*) data, len);
|
||||||
|
|
||||||
if ( rslt != 0 ) return;
|
if ( rslt != 0 || ! ProtocolConfirmed() ) return;
|
||||||
|
|
||||||
Val* teredo_hdr = 0;
|
Val* teredo_hdr = 0;
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,6 @@ const Tunnel::max_depth: count;
|
||||||
const Tunnel::enable_ip: bool;
|
const Tunnel::enable_ip: bool;
|
||||||
const Tunnel::enable_ayiya: bool;
|
const Tunnel::enable_ayiya: bool;
|
||||||
const Tunnel::enable_teredo: bool;
|
const Tunnel::enable_teredo: bool;
|
||||||
|
const Tunnel::yielding_teredo_decapsulation: bool;
|
||||||
|
|
||||||
const Threading::heartbeat_interval: interval;
|
const Threading::heartbeat_interval: interval;
|
||||||
|
|
19
testing/btest/Baseline/core.tunnels.false-teredo/weird.log
Normal file
19
testing/btest/Baseline/core.tunnels.false-teredo/weird.log
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path weird
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
|
||||||
|
#types time string addr port addr port string string bool string
|
||||||
|
1258567191.405770 - - - - - truncated_header - F bro
|
||||||
|
1258567191.486869 UWkUyAuUGXf 192.168.1.105 57696 192.168.1.1 53 Teredo_payload_len_mismatch - F bro
|
||||||
|
1258578181.260420 - - - - - truncated_header - F bro
|
||||||
|
1258578181.516140 nQcgTWjvg4c 192.168.1.104 64838 192.168.1.1 53 Teredo_payload_len_mismatch - F bro
|
||||||
|
1258579063.557927 - - - - - truncated_header - F bro
|
||||||
|
1258579063.784919 j4u32Pc5bif 192.168.1.104 55778 192.168.1.1 53 Teredo_payload_len_mismatch - F bro
|
||||||
|
1258581768.568451 - - - - - truncated_header - F bro
|
||||||
|
1258581768.898165 TEfuqmmG4bh 192.168.1.104 50798 192.168.1.1 53 Teredo_payload_len_mismatch - F bro
|
||||||
|
1258584478.859853 - - - - - truncated_header - F bro
|
||||||
|
1258584478.989528 FrJExwHcSal 192.168.1.104 64963 192.168.1.1 53 Teredo_payload_len_mismatch - F bro
|
||||||
|
1258600683.934458 - - - - - truncated_header - F bro
|
||||||
|
1258600683.934672 5OKnoww6xl4 192.168.1.103 59838 192.168.1.1 53 Teredo_payload_len_mismatch - F bro
|
BIN
testing/btest/Traces/tunnels/false-teredo.pcap
Normal file
BIN
testing/btest/Traces/tunnels/false-teredo.pcap
Normal file
Binary file not shown.
34
testing/btest/core/tunnels/false-teredo.bro
Normal file
34
testing/btest/core/tunnels/false-teredo.bro
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# @TEST-EXEC: bro -r $TRACES/tunnels/false-teredo.pcap %INPUT >output
|
||||||
|
# @TEST-EXEC: test ! -e weird.log
|
||||||
|
# @TEST-EXEC: bro -r $TRACES/tunnels/false-teredo.pcap %INPUT Tunnel::yielding_teredo_decapsulation=F >output
|
||||||
|
# @TEST-EXEC: btest-diff weird.log
|
||||||
|
|
||||||
|
function print_teredo(name: string, outer: connection, inner: teredo_hdr)
|
||||||
|
{
|
||||||
|
print fmt("%s: %s", name, outer$id);
|
||||||
|
print fmt(" ip6: %s", inner$hdr$ip6);
|
||||||
|
if ( inner?$auth )
|
||||||
|
print fmt(" auth: %s", inner$auth);
|
||||||
|
if ( inner?$origin )
|
||||||
|
print fmt(" origin: %s", inner$origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
event teredo_packet(outer: connection, inner: teredo_hdr)
|
||||||
|
{
|
||||||
|
print_teredo("packet", outer, inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
event teredo_authentication(outer: connection, inner: teredo_hdr)
|
||||||
|
{
|
||||||
|
print_teredo("auth", outer, inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
event teredo_origin_indication(outer: connection, inner: teredo_hdr)
|
||||||
|
{
|
||||||
|
print_teredo("origin", outer, inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
event teredo_bubble(outer: connection, inner: teredo_hdr)
|
||||||
|
{
|
||||||
|
print_teredo("bubble", outer, inner);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue