From 9c388a18091d07e5adf5fa3b621c83fd46d5890a Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Wed, 3 Aug 2011 14:12:47 -0700 Subject: [PATCH 01/51] Adding support to de-capsulate tunnels. Checkpoint. Decapsulation happens after IP Defragmentation. The "identity" of the enclosing tunnel (the "parent") is added to the connection record of the child (tunneled) connection as an optional field $tunnel_parent. --- policy/bro.init | 6 ++++ src/CMakeLists.txt | 1 + src/Conn.cc | 5 ++- src/Conn.h | 3 +- src/ConnCompressor.cc | 4 +-- src/Sessions.cc | 46 ++++++++++++++++++++------- src/Sessions.h | 7 ++++- src/TunnelHandler.cc | 48 ++++++++++++++++++++++++++++ src/TunnelHandler.h | 73 +++++++++++++++++++++++++++++++++++++++++++ src/types.bif | 7 +++++ 10 files changed, 183 insertions(+), 17 deletions(-) create mode 100644 src/TunnelHandler.cc create mode 100644 src/TunnelHandler.h diff --git a/policy/bro.init b/policy/bro.init index fda8cfd6f4..17607a7113 100644 --- a/policy/bro.init +++ b/policy/bro.init @@ -81,6 +81,11 @@ type endpoint_stats: record { type AnalyzerID: count; +type tunnel_parent_t: record { + cid: conn_id; + tunnel_type: tunneltype_t; +}; + type connection: record { id: conn_id; orig: endpoint; @@ -92,6 +97,7 @@ type connection: record { hot: count; # how hot; 0 = don't know or not hot history: string; uid: string; + tunnel_parent: tunnel_parent_t &optional; }; type SYN_packet: record { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a5f096f70..e79fad4ca0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -388,6 +388,7 @@ set(bro_SRCS Timer.cc Traverse.cc Trigger.cc + TunnelHandler.cc Type.cc UDP.cc Val.cc diff --git a/src/Conn.cc b/src/Conn.cc index bab032cbd0..67e337fda9 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -139,7 +139,7 @@ unsigned int Connection::external_connections = 0; IMPLEMENT_SERIAL(Connection, SER_CONNECTION); -Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id) +Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent) { sessions = s; key = k; @@ -183,6 +183,8 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id) uid = 0; // Will set later. + tunnel_parent = arg_tunnel_parent; + if ( conn_timer_mgr ) { ++external_connections; @@ -370,6 +372,7 @@ RecordVal* Connection::BuildConnVal() char tmp[20]; conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62))); + conn_val->Assign(10, tunnel_parent); } if ( root_analyzer ) diff --git a/src/Conn.h b/src/Conn.h index 8f817fd003..e22c0b83ec 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -86,7 +86,7 @@ class Analyzer; class Connection : public BroObj { public: - Connection(NetSessions* s, HashKey* k, double t, const ConnID* id); + Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent); virtual ~Connection(); // Invoked when connection is about to be removed. Use Ref(this) @@ -335,6 +335,7 @@ protected: double inactivity_timeout; RecordVal* conn_val; LoginConn* login_conn; // either nil, or this + RecordVal* tunnel_parent; // nil if not tunneled int suppress_event; // suppress certain events to once per conn. unsigned int installed_status_timer:1; diff --git a/src/ConnCompressor.cc b/src/ConnCompressor.cc index e173463205..2d617b0fc4 100644 --- a/src/ConnCompressor.cc +++ b/src/ConnCompressor.cc @@ -521,7 +521,7 @@ Connection* ConnCompressor::Instantiate(HashKey* key, PendingConn* pending) // Fake the first packet. const IP_Hdr* faked_pkt = PendingConnToPacket(pending); Connection* new_conn = sessions->NewConn(key, pending->time, &conn_id, - faked_pkt->Payload(), IPPROTO_TCP); + faked_pkt->Payload(), IPPROTO_TCP, 0); if ( ! new_conn ) { @@ -574,7 +574,7 @@ Connection* ConnCompressor::Instantiate(double t, HashKey* key, conn_id.dst_port = tp->th_dport; Connection* new_conn = - sessions->NewConn(key, t, &conn_id, ip->Payload(), IPPROTO_TCP); + sessions->NewConn(key, t, &conn_id, ip->Payload(), IPPROTO_TCP, 0); if ( ! new_conn ) { diff --git a/src/Sessions.cc b/src/Sessions.cc index 1678f6798f..48fab1bff4 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -33,6 +33,7 @@ #include "DPM.h" #include "PacketSort.h" +#include "TunnelHandler.h" // These represent NetBIOS services on ephemeral ports. They're numbered // so that we can use a single int to hold either an actual TCP/UDP server @@ -128,6 +129,12 @@ NetSessions::NetSessions() arp_analyzer = new ARP_Analyzer(); else arp_analyzer = 0; + + + if ( 1 ) + tunnel_handler = new TunnelHandler(this); + else + tunnel_handler = 0; } NetSessions::~NetSessions() @@ -433,14 +440,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( discarder && discarder->NextPacket(ip_hdr, len, caplen) ) return; - int proto = ip_hdr->NextProto(); - if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && - proto != IPPROTO_ICMP ) - { - dump_this_packet = 1; - return; - } - FragReassembler* f = 0; uint32 frag_field = ip_hdr->FragField(); @@ -474,6 +473,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } } + TunnelInfo *tunnel_info = tunnel_handler->DecapsulateTunnel(ip_hdr, len, caplen, hdr, pkt); + if (tunnel_info) + { + ip4 = tunnel_info->child->IP4_Hdr(); + ip_hdr = tunnel_info->child; + len -= tunnel_info->hdr_len; + caplen -= tunnel_info->hdr_len; + } + + int proto = ip_hdr->NextProto(); + if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP && + proto != IPPROTO_ICMP ) + { + dump_this_packet = 1; + return; + } + len -= ip_hdr_len; // remove IP header caplen -= ip_hdr_len; @@ -561,7 +577,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, conn = (Connection*) d->Lookup(h); if ( ! conn ) { - conn = NewConn(h, t, &id, data, proto); + conn = NewConn(h, t, &id, data, proto, tunnel_info); if ( conn ) d->Insert(h, conn); } @@ -581,7 +597,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, conn->Event(connection_reused, 0); Remove(conn); - conn = NewConn(h, t, &id, data, proto); + conn = NewConn(h, t, &id, data, proto, tunnel_info); if ( conn ) d->Insert(h, conn); } @@ -609,6 +625,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, record_packet, record_content, hdr, pkt, hdr_size); + if ( tunnel_info ) + delete tunnel_info; if ( f ) { // Above we already recorded the fragment in its entirety. @@ -1045,13 +1063,17 @@ void NetSessions::GetStats(SessionStats& s) const } Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, - const u_char* data, int proto) + const u_char* data, int proto, TunnelInfo* tunnel_info) { // FIXME: This should be cleaned up a bit, it's too protocol-specific. // But I'm not yet sure what the right abstraction for these things is. int src_h = ntohs(id->src_port); int dst_h = ntohs(id->dst_port); int flags = 0; + RecordVal *tunnel_parent = 0; + + if ( tunnel_info ) + tunnel_parent = tunnel_info->GetRecordVal(); // Hmm... This is not great. TransportProto tproto; @@ -1098,7 +1120,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, id = &flip_id; } - Connection* conn = new Connection(this, k, t, id); + Connection* conn = new Connection(this, k, t, id, tunnel_parent); conn->SetTransport(tproto); dpm->BuildInitialAnalyzerTree(tproto, conn, data); diff --git a/src/Sessions.h b/src/Sessions.h index 6adc333282..9551ba5254 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -28,6 +28,9 @@ class Discarder; class SteppingStoneManager; class PacketFilter; +class TunnelHandler; +class TunnelInfo; + class PacketSortElement; struct SessionStats { @@ -144,7 +147,7 @@ protected: friend class TimerMgrExpireTimer; Connection* NewConn(HashKey* k, double t, const ConnID* id, - const u_char* data, int proto); + const u_char* data, int proto, TunnelInfo *tunnel_info); // Check whether the tag of the current packet is consistent with // the given connection. Returns: @@ -214,6 +217,8 @@ protected: int num_packets_processed; PacketProfiler* pkt_profiler; + TunnelHandler *tunnel_handler; + // We may use independent timer managers for different sets of related // activity. The managers are identified by an unique tag. typedef std::map TimerMgrMap; diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc new file mode 100644 index 0000000000..c739403ad8 --- /dev/null +++ b/src/TunnelHandler.cc @@ -0,0 +1,48 @@ +// $Id: Sessions.cc 7075 2010-09-13 02:39:38Z vern $ +// +// See the file "COPYING" in the main distribution directory for copyright. + + +#include "config.h" + +#include + +#include +#include + +#include "TunnelHandler.h" +#include "Conn.h" +#include "Sessions.h" + + +TunnelHandler::TunnelHandler(NetSessions *arg_s) + { + s = arg_s; + } + +TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int caplen, + const struct pcap_pkthdr* hdr, const u_char* const pkt) + { + TunnelInfo *tunnel_info = 0; + switch (ip_hdr->NextProto()) { +#ifdef BROv6 + case IPPROTO_IPV6: /* 6in4 and 6to4 */ + if (len < (int)sizeof(struct ip6_hdr) || caplen < (int)sizeof(struct ip6_hdr)) + { + s->Weird("truncated_header", hdr, pkt); + return 0; + } + // TODO: check if IP6 header makes sense + tunnel_info = new TunnelInfo(); + tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload()); + tunnel_info->tunneltype = BifEnum::IP6inIP; + tunnel_info->hdr_len = ip_hdr->HdrLen(); + tunnel_info->SetParentIPs(ip_hdr); + return tunnel_info; + break; +#endif + default: + break; + } /* end switch */ + return 0; + } diff --git a/src/TunnelHandler.h b/src/TunnelHandler.h new file mode 100644 index 0000000000..aa4cae0a39 --- /dev/null +++ b/src/TunnelHandler.h @@ -0,0 +1,73 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#ifndef tunnelhandler_h +#define tunnelhandler_h + +#include "IP.h" +#include "Conn.h" +#include "Sessions.h" +#include "Val.h" + + +class TunnelInfo { +public: + TunnelInfo() + { + child = 0; + tunneltype = BifEnum::NONE; + hdr_len = 0; + parent.src_addr = parent.dst_addr = 0; + parent.src_port = parent.dst_port = 0; + parent.is_one_way = 0; + } + ~TunnelInfo() + { + if (child) delete child; + } + + void SetParentIPs(const IP_Hdr *ip_hdr) + { + parent.src_addr = ip_hdr->SrcAddr(); + parent.dst_addr = ip_hdr->DstAddr(); + } + void SetParentPorts(uint32 src_port, uint32 dst_port) + { + parent.src_port = src_port; + parent.dst_port = dst_port; + } + + RecordVal* GetRecordVal() const + { + RecordVal *rv = new RecordVal(BifType::Record::tunnel_parent_t); + + RecordVal* id_val = new RecordVal(conn_id); + id_val->Assign(0, new AddrVal(parent.src_addr)); + id_val->Assign(1, new PortVal(ntohs(parent.src_port), TRANSPORT_UNKNOWN)); + id_val->Assign(2, new AddrVal(parent.dst_addr)); + id_val->Assign(3, new PortVal(ntohs(parent.dst_port), TRANSPORT_UNKNOWN)); + rv->Assign(0, id_val); + rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::tunneltype_t)); + return rv; + } + + IP_Hdr *child; + ConnID parent; + int hdr_len; + BifEnum::tunneltype_t tunneltype; +}; + +class TunnelHandler { +public: + TunnelHandler(NetSessions *arg_s); + ~TunnelHandler(); + + TunnelInfo* DecapsulateTunnel(const IP_Hdr* ip_hdr, int len, int caplen, + /* need those for passing them back to NetSessions::Weird() */ + const struct pcap_pkthdr* hdr, const u_char* const pkt); + +protected: + NetSessions *s; +}; + + +#endif diff --git a/src/types.bif b/src/types.bif index 8bc5ab8510..d44f177b82 100644 --- a/src/types.bif +++ b/src/types.bif @@ -167,3 +167,10 @@ enum ID %{ %} module GLOBAL; + +enum tunneltype_t %{ + NONE, + IP6inIP, +%} + +type tunnel_parent_t: record; From 8910cd2dcaf308f9febc575a38dcf32ed47be1d6 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Thu, 4 Aug 2011 15:25:13 -0700 Subject: [PATCH 02/51] Adding support to de-capsulate tunnels. Checkpoint. Re-organizing code. Adding UDP tunnel handlers. Using policy level redef'able consts to tune behavior. UDP port settings not working yet. --- policy/bro.init | 36 +++++++++-- src/Sessions.cc | 25 +++++--- src/TunnelHandler.cc | 144 +++++++++++++++++++++++++++++++++++++++---- src/TunnelHandler.h | 34 +++++++--- src/const.bif | 4 ++ src/types.bif | 13 +++- 6 files changed, 216 insertions(+), 40 deletions(-) diff --git a/policy/bro.init b/policy/bro.init index 17607a7113..8be0ab754a 100644 --- a/policy/bro.init +++ b/policy/bro.init @@ -81,10 +81,14 @@ type endpoint_stats: record { type AnalyzerID: count; -type tunnel_parent_t: record { - cid: conn_id; - tunnel_type: tunneltype_t; -}; +module Tunnel; +export { + type parent_t: record { + cid: conn_id; + tunnel_type: tunneltype_t; + }; +} # end export +module GLOBAL; type connection: record { id: conn_id; @@ -97,7 +101,7 @@ type connection: record { hot: count; # how hot; 0 = don't know or not hot history: string; uid: string; - tunnel_parent: tunnel_parent_t &optional; + tunnel_parent: Tunnel::parent_t &optional; }; type SYN_packet: record { @@ -1489,6 +1493,28 @@ const skip_http_data = F &redef; # UDP tunnels. See also: udp_tunnel_port, policy/udp-tunnel.bro. const parse_udp_tunnels = F &redef; +module Tunnel; +export { + # Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) + const decapsulate_ip = F &redef; + + # Whether to decapsulate URDP tunnels (e.g., Teredo, IPv4 in UDP) + const decapsulate_udp = F &redef; + + # If decapsulating UDP: the set of ports for which to do so + const udp_tunnel_ports: set[port] = { + 3544/udp, # Teredo + 5072/udp, # AYIAY + } &redef; + + # If udp_tunnel_allports is T udp_tunnel_ports is ignored and we + # check every UDP packet for tunnels. + const udp_tunnel_allports = F &redef; +} # end export +module GLOBAL; + + + # Load the site utilities. @load utils/site diff --git a/src/Sessions.cc b/src/Sessions.cc index 48fab1bff4..41a7f4c52d 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -131,10 +131,11 @@ NetSessions::NetSessions() arp_analyzer = 0; - if ( 1 ) + if ( BifConst::Tunnel::decapsulate_ip || BifConst::Tunnel::decapsulate_udp ) tunnel_handler = new TunnelHandler(this); else tunnel_handler = 0; + printf("tunnel_handler: %p\n", tunnel_handler); } NetSessions::~NetSessions() @@ -473,13 +474,20 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } } - TunnelInfo *tunnel_info = tunnel_handler->DecapsulateTunnel(ip_hdr, len, caplen, hdr, pkt); - if (tunnel_info) + len -= ip_hdr_len; // remove IP header + caplen -= ip_hdr_len; + + TunnelInfo *tunnel_info = 0; + if ( tunnel_handler ) { - ip4 = tunnel_info->child->IP4_Hdr(); - ip_hdr = tunnel_info->child; - len -= tunnel_info->hdr_len; - caplen -= tunnel_info->hdr_len; + tunnel_info = tunnel_handler->DecapsulateTunnel(ip_hdr, len, caplen, hdr, pkt); + if (tunnel_info) + { + ip4 = tunnel_info->child->IP4_Hdr(); + ip_hdr = tunnel_info->child; + len -= tunnel_info->hdr_len; + caplen -= tunnel_info->hdr_len; + } } int proto = ip_hdr->NextProto(); @@ -490,9 +498,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } - len -= ip_hdr_len; // remove IP header - caplen -= ip_hdr_len; - uint32 min_hdr_len = (proto == IPPROTO_TCP) ? sizeof(struct tcphdr) : (proto == IPPROTO_UDP ? sizeof(struct udphdr) : ICMP_MINLEN); diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index c739403ad8..3256894cd0 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -18,31 +18,151 @@ TunnelHandler::TunnelHandler(NetSessions *arg_s) { s = arg_s; + for (int i=0; i< 65536; i++) + udp_ports[i] = 0; + udp_ports[3544] = 1; + udp_ports[5072] = 1; } TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int caplen, const struct pcap_pkthdr* hdr, const u_char* const pkt) { TunnelInfo *tunnel_info = 0; + switch (ip_hdr->NextProto()) { #ifdef BROv6 case IPPROTO_IPV6: /* 6in4 and 6to4 */ - if (len < (int)sizeof(struct ip6_hdr) || caplen < (int)sizeof(struct ip6_hdr)) - { - s->Weird("truncated_header", hdr, pkt); - return 0; - } - // TODO: check if IP6 header makes sense - tunnel_info = new TunnelInfo(); - tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload()); - tunnel_info->tunneltype = BifEnum::IP6inIP; - tunnel_info->hdr_len = ip_hdr->HdrLen(); - tunnel_info->SetParentIPs(ip_hdr); - return tunnel_info; + if ( BifConst::Tunnel::decapsulate_ip ) + { + if (len < (int)sizeof(struct ip6_hdr) || caplen < (int)sizeof(struct ip6_hdr)) + { + s->Weird("truncated_header", hdr, pkt); + return 0; + } + // TODO: check if IP6 header makes sense + tunnel_info = new TunnelInfo(); + tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload()); + tunnel_info->tunneltype = BifEnum::Tunnel::IP6inIP; + tunnel_info->hdr_len = tunnel_info->child->HdrLen(); + tunnel_info->SetParentIPs(ip_hdr); + return tunnel_info; + } break; #endif + // TODO: IP in IP. Find test traces first. IP proto 0 and/or 4 + case IPPROTO_UDP: + if ( BifConst::Tunnel::decapsulate_udp ) + { + if (len < (int)sizeof(struct udphdr) || caplen < (int)sizeof(struct udphdr)) + { + // No weird here. Main packet processing will raise it. + return 0; + } + return HandleUDP(ip_hdr, len, caplen); + } + + break; default: break; } /* end switch */ return 0; } + +TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) + { + // We already know we that we have a valid UDP header + const u_char *data = ip_hdr->Payload(); + const struct udphdr* uh = (const struct udphdr*)data; + IP_Hdr *cand_ip_hdr = 0; + BifEnum::Tunnel::tunneltype_t tunneltype = BifEnum::Tunnel::NONE; + + int hdr_len = sizeof(struct udphdr); + data += hdr_len; + + int datalen = (int)ntohs(uh->uh_ulen); + datalen = min(datalen, min(len, caplen)); + datalen -= hdr_len; + + if ( BifConst::Tunnel::udp_tunnel_allports || + udp_ports[ntohs(uh->uh_sport)] || + udp_ports[ntohs(uh->uh_dport)] ) + { + cand_ip_hdr = LookForIPHdr(data, datalen); + if (cand_ip_hdr) + { + tunneltype = (cand_ip_hdr->IP4_Hdr()) ? + BifEnum::Tunnel::IP4inUDP : BifEnum::Tunnel::IP6inUDP; + } + else if (datalen >= 8) + { + // Look for AYIAY tunnels + u_char id_byte = data[0]; + u_char sig_byte = data[1]; + u_char next_hdr = data[3]; + + // identity length field is high bits of id_byte. + // length in octets is 2 to the power of length field + int id_len = (1 << (id_byte>>4)); + + // signature length field is high bits of sig_byte + // length in octets 4 * length field + int sig_len = 4*(sig_byte>>4); + + datalen -= 8 + id_len + sig_len; + data += 8 + id_len + sig_len; + if (datalen <= 0) + return 0; + cand_ip_hdr = LookForIPHdr(data, datalen); + if (cand_ip_hdr) + { + hdr_len += 8 + id_len + sig_len; + tunneltype = (cand_ip_hdr->IP4_Hdr()) ? + BifEnum::Tunnel::IP4inAYIAY : BifEnum::Tunnel::IP6inAYIAY; + } + } + if (cand_ip_hdr) + { + TunnelInfo *tunnel_info = new TunnelInfo(); + tunnel_info->child = cand_ip_hdr; + tunnel_info->tunneltype = tunneltype; + tunnel_info->SetParentIPs(ip_hdr); + tunnel_info->SetParentPorts(uh); + tunnel_info->hdr_len = hdr_len + cand_ip_hdr->HdrLen(); + return tunnel_info; + }; + } + return 0; + } + +IP_Hdr* TunnelHandler::LookForIPHdr(const u_char *data, int datalen) + { + IP_Hdr *cand_ip_hdr = 0; + if (datalen < (int)sizeof(struct ip)) + return 0; + + const struct ip *ip4 = (const struct ip*)(data); + if (ip4->ip_v == 4) + cand_ip_hdr = new IP_Hdr((const struct ip*)ip4); + else if (ip4->ip_v == 6 && (datalen > (int)sizeof(struct ip6_hdr))) + cand_ip_hdr = new IP_Hdr((const struct ip6_hdr*)data); + + if (cand_ip_hdr) + { + switch (cand_ip_hdr->NextProto()) { + case IPPROTO_UDP: + case IPPROTO_TCP: + case IPPROTO_ICMP: + if ((int)cand_ip_hdr->TotalLen() != datalen) + { + delete cand_ip_hdr; + cand_ip_hdr = 0; + } + break; + default: + delete cand_ip_hdr; + cand_ip_hdr = 0; + break; + } // end switch + } + return cand_ip_hdr; + } diff --git a/src/TunnelHandler.h b/src/TunnelHandler.h index aa4cae0a39..31c9791a1c 100644 --- a/src/TunnelHandler.h +++ b/src/TunnelHandler.h @@ -3,6 +3,7 @@ #ifndef tunnelhandler_h #define tunnelhandler_h +#include #include "IP.h" #include "Conn.h" #include "Sessions.h" @@ -14,7 +15,7 @@ public: TunnelInfo() { child = 0; - tunneltype = BifEnum::NONE; + tunneltype = BifEnum::Tunnel::NONE; hdr_len = 0; parent.src_addr = parent.dst_addr = 0; parent.src_port = parent.dst_port = 0; @@ -30,30 +31,39 @@ public: parent.src_addr = ip_hdr->SrcAddr(); parent.dst_addr = ip_hdr->DstAddr(); } - void SetParentPorts(uint32 src_port, uint32 dst_port) + void SetParentPorts(const struct udphdr *uh) { - parent.src_port = src_port; - parent.dst_port = dst_port; + parent.src_port = uh->uh_sport; + parent.dst_port = uh->uh_dport; } RecordVal* GetRecordVal() const { - RecordVal *rv = new RecordVal(BifType::Record::tunnel_parent_t); + RecordVal *rv = new RecordVal(BifType::Record::Tunnel::parent_t); + TransportProto tproto; + switch(tunneltype) { + case BifEnum::Tunnel::IP6inIP: + case BifEnum::Tunnel::IP4inIP: + tproto = TRANSPORT_UNKNOWN; + break; + default: + tproto = TRANSPORT_UDP; + } // end switch RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal(parent.src_addr)); - id_val->Assign(1, new PortVal(ntohs(parent.src_port), TRANSPORT_UNKNOWN)); + id_val->Assign(1, new PortVal(ntohs(parent.src_port), tproto)); id_val->Assign(2, new AddrVal(parent.dst_addr)); - id_val->Assign(3, new PortVal(ntohs(parent.dst_port), TRANSPORT_UNKNOWN)); + id_val->Assign(3, new PortVal(ntohs(parent.dst_port), tproto)); rv->Assign(0, id_val); - rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::tunneltype_t)); + rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::tunneltype_t)); return rv; } IP_Hdr *child; ConnID parent; int hdr_len; - BifEnum::tunneltype_t tunneltype; + BifEnum::Tunnel::tunneltype_t tunneltype; }; class TunnelHandler { @@ -61,12 +71,16 @@ public: TunnelHandler(NetSessions *arg_s); ~TunnelHandler(); + // Main entry point. Returns a nil if not tunneled. TunnelInfo* DecapsulateTunnel(const IP_Hdr* ip_hdr, int len, int caplen, - /* need those for passing them back to NetSessions::Weird() */ + // need those for passing them back to NetSessions::Weird() const struct pcap_pkthdr* hdr, const u_char* const pkt); protected: NetSessions *s; + short udp_ports[65536]; // which UDP ports to decapsulate + IP_Hdr* LookForIPHdr(const u_char *data, int datalen); + TunnelInfo* HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen); }; diff --git a/src/const.bif b/src/const.bif index 825c21e7a5..447812a902 100644 --- a/src/const.bif +++ b/src/const.bif @@ -12,3 +12,7 @@ const NFS3::return_data: bool; const NFS3::return_data_max: count; const NFS3::return_data_first_only: bool; +const Tunnel::decapsulate_ip: bool; +const Tunnel::decapsulate_udp: bool; +const Tunnel::udp_tunnel_ports: any; +const Tunnel::udp_tunnel_allports: bool; diff --git a/src/types.bif b/src/types.bif index d44f177b82..35c4db0daf 100644 --- a/src/types.bif +++ b/src/types.bif @@ -166,11 +166,18 @@ enum ID %{ Unknown, %} -module GLOBAL; +module Tunnel; enum tunneltype_t %{ NONE, - IP6inIP, + IP6inIP, + IP4inIP, + IP6inUDP, + IP4inUDP, + IP6inAYIAY, + IP4inAYIAY, %} -type tunnel_parent_t: record; +type parent_t: record; + +module GLOBAL; From 5ed3ec2f38b4a8546fba55cfeace04615021b76c Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Sun, 7 Aug 2011 09:49:41 -0700 Subject: [PATCH 03/51] Finishing tunnel decapsulation support in C++ core. Policy script is next. --- policy/bro.init | 2 +- src/Sessions.cc | 1 - src/TunnelHandler.cc | 18 +++++++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/policy/bro.init b/policy/bro.init index 8be0ab754a..59acf746dd 100644 --- a/policy/bro.init +++ b/policy/bro.init @@ -86,7 +86,7 @@ export { type parent_t: record { cid: conn_id; tunnel_type: tunneltype_t; - }; + } &log; } # end export module GLOBAL; diff --git a/src/Sessions.cc b/src/Sessions.cc index 41a7f4c52d..9241b17005 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -135,7 +135,6 @@ NetSessions::NetSessions() tunnel_handler = new TunnelHandler(this); else tunnel_handler = 0; - printf("tunnel_handler: %p\n", tunnel_handler); } NetSessions::~NetSessions() diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index 3256894cd0..78428c700f 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -18,10 +18,22 @@ TunnelHandler::TunnelHandler(NetSessions *arg_s) { s = arg_s; + PortVal *pv = 0; + TableVal *udp_tunnel_ports = BifConst::Tunnel::udp_tunnel_ports->AsTableVal(); + // Find UDP ports we want to analyze. Store them in an array for faster + // lookup. for (int i=0; i< 65536; i++) - udp_ports[i] = 0; - udp_ports[3544] = 1; - udp_ports[5072] = 1; + { + Unref(pv); + pv = new PortVal(i, TRANSPORT_UDP); + if (udp_tunnel_ports->Lookup(pv, false)) + { + udp_ports[i] = 1; + } + else + udp_ports[i] = 0; + } + Unref(pv); } TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int caplen, From 32f37c9f6d151d73a47c2a0e558fcbd37b47f49c Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Sun, 7 Aug 2011 12:26:19 -0700 Subject: [PATCH 04/51] Documenting tunnel decapsulation. Haven't tested the autodoc output yet. --- scripts/base/bro.init | 17 +++++--- scripts/policy/frameworks/tunnel.bro | 61 ++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 scripts/policy/frameworks/tunnel.bro diff --git a/scripts/base/bro.init b/scripts/base/bro.init index cf34a763c5..a6b0ff3890 100644 --- a/scripts/base/bro.init +++ b/scripts/base/bro.init @@ -83,8 +83,14 @@ type AnalyzerID: count; module Tunnel; export { + ## Records the identity of a the parent of a tunneled connection. type parent_t: record { + ## The 4-tuple of the tunnel "connection". In case of an IP-in-IP + ## tunnel the ports will be set to 0. The direction (i.e., orig and + ## resp) of the parent are set according to the tunneled connection + ## and not according to the side that established the tunnel. cid: conn_id; + ## The type of tunnel. tunnel_type: tunneltype_t; } &log; } # end export @@ -1495,20 +1501,21 @@ const parse_udp_tunnels = F &redef; module Tunnel; export { - # Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) + ## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) const decapsulate_ip = F &redef; - # Whether to decapsulate URDP tunnels (e.g., Teredo, IPv4 in UDP) + ## Whether to decapsulate URDP tunnels (e.g., Teredo, IPv4 in UDP) const decapsulate_udp = F &redef; - # If decapsulating UDP: the set of ports for which to do so + ## If decapsulating UDP: the set of ports for which to do so. + ## Can be overridden by :bro:id:`Tunnel::udp_tunnel_allports` const udp_tunnel_ports: set[port] = { 3544/udp, # Teredo 5072/udp, # AYIAY } &redef; - # If udp_tunnel_allports is T udp_tunnel_ports is ignored and we - # check every UDP packet for tunnels. + ## If udp_tunnel_allports is T :bro:id:`udp_tunnel_ports` is ignored and we + ## check every UDP packet for tunnels. const udp_tunnel_allports = F &redef; } # end export module GLOBAL; diff --git a/scripts/policy/frameworks/tunnel.bro b/scripts/policy/frameworks/tunnel.bro new file mode 100644 index 0000000000..80e46c31a4 --- /dev/null +++ b/scripts/policy/frameworks/tunnel.bro @@ -0,0 +1,61 @@ +##! Handle tunneled connections. +##! +##! Bro can decapsulate IPinIP and IPinUDP tunnels, were "IP" can be either +##! IPv4 or IPv6. The most common case will be decapsulating Teredo, 6to4, +##! 6in4, and AYIAY. +##! +##! Decapsulation happens early in a packets processing, right after IP +##! defragmentation but before there is a connection context. The tunnel +##! headers are stripped from packet and the identity of the parent is +##! is stored as the ``tunnel_parent`` member of :bro:type:`connection`, +##! which is of type :bro:type:`parent_t`. +##! +##! *Limitation:* The decapsulated packets are not fed through the +##! defragmenter again. +##! +##! + +module Tunnel; + +redef use_connection_compressor = F; +redef Tunnel::decapsulate_ip = T; +redef Tunnel::decapsulate_udp = T; +redef Tunnel::udp_tunnel_allports = T; + +export { + redef enum Log::ID += { TUNNEL }; + + ## This record will be logged + type Info : record { + ## This is the time of the first record + ts: time &log; + ## The uid of the child connection, i.e. the connection in the tunnel + uid: string &log; + ## The connection id of the child + id: conn_id &log; + ## The child's transport protocol + proto: transport_proto &log; + ## The parent connection of IP-pair + parent: parent_t &log; + }; + global log_conn: event(rec: Info); +} + +event bro_init() + { + Log::create_stream(TUNNEL, [$columns=Info, $ev=log_conn]); + } + +event new_connection(c: connection) + { + if (c?$tunnel_parent) + { + local info: Info; + info$ts = c$start_time; + info$uid = c$uid; + info$id = c$id; + info$proto = get_port_transport_proto(c$id$resp_p); + info$parent = c$tunnel_parent; + Log::write(TUNNEL, info); + } + } From cd592203a0e3399ea8fdfe1288f51cce813db6d9 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Sun, 7 Aug 2011 13:55:46 -0700 Subject: [PATCH 05/51] Remvoing old tunnel code (encap_hdr_size and udp_tunnels). --- scripts/base/bro.init | 6 ----- src/Sessions.cc | 56 ------------------------------------------- 2 files changed, 62 deletions(-) diff --git a/scripts/base/bro.init b/scripts/base/bro.init index a6b0ff3890..2f83b99bf8 100644 --- a/scripts/base/bro.init +++ b/scripts/base/bro.init @@ -515,12 +515,6 @@ const packet_sort_window = 0 usecs &redef; # state accrual. const frag_timeout = 0.0 sec &redef; -# If positive, indicates the encapsulation header size that should -# be skipped over for each captured packet .... -const encap_hdr_size = 0 &redef; -# ... or just for the following UDP port. -const tunnel_port = 0/udp &redef; - # Whether to use the ConnSize analyzer to count the number of # packets and IP-level bytes transfered by each endpoint. If # true, these values are returned in the connection's endpoint diff --git a/src/Sessions.cc b/src/Sessions.cc index 9241b17005..fa0d573660 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -177,62 +177,6 @@ void NetSessions::DispatchPacket(double t, const struct pcap_pkthdr* hdr, ip_data = pkt + hdr_size + (ip_hdr->ip_hl << 2); } - if ( encap_hdr_size > 0 && ip_data ) - { - // We're doing tunnel encapsulation. Check whether there's - // a particular associated port. - // - // Should we discourage the use of encap_hdr_size for UDP - // tunnneling? It is probably better handled by enabling - // BifConst::parse_udp_tunnels instead of specifying a fixed - // encap_hdr_size. - if ( udp_tunnel_port > 0 ) - { - ASSERT(ip_hdr); - if ( ip_hdr->ip_p == IPPROTO_UDP ) - { - const struct udphdr* udp_hdr = - reinterpret_cast - (ip_data); - - if ( ntohs(udp_hdr->uh_dport) == udp_tunnel_port ) - { - // A match. - hdr_size += encap_hdr_size; - } - } - } - - else - // Blanket encapsulation - hdr_size += encap_hdr_size; - } - - // Check IP packets encapsulated through UDP tunnels. - // Specifying a udp_tunnel_port is optional but recommended (to avoid - // the cost of checking every UDP packet). - else if ( BifConst::parse_udp_tunnels && ip_data && ip_hdr->ip_p == IPPROTO_UDP ) - { - const struct udphdr* udp_hdr = - reinterpret_cast(ip_data); - - if ( udp_tunnel_port == 0 || // 0 matches any port - udp_tunnel_port == ntohs(udp_hdr->uh_dport) ) - { - const u_char* udp_data = - ip_data + sizeof(struct udphdr); - const struct ip* ip_encap = - reinterpret_cast(udp_data); - const int ip_encap_len = - ntohs(udp_hdr->uh_ulen) - sizeof(struct udphdr); - const int ip_encap_caplen = - hdr->caplen - (udp_data - pkt); - - if ( looks_like_IPv4_packet(ip_encap_len, ip_encap) ) - hdr_size = udp_data - pkt; - } - } - if ( src_ps->FilterType() == TYPE_FILTER_NORMAL ) NextPacket(t, hdr, pkt, hdr_size, pkt_elem); else From fe6a05e2ade5151db7d22b7b6d39c04182e77145 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Sun, 7 Aug 2011 15:33:50 -0700 Subject: [PATCH 06/51] Tunnel documentation tweaks. Checkpoint. Need to check cross-references once "make doc" works again. --- scripts/policy/frameworks/tunnel.bro | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/scripts/policy/frameworks/tunnel.bro b/scripts/policy/frameworks/tunnel.bro index 80e46c31a4..ebec2b0f06 100644 --- a/scripts/policy/frameworks/tunnel.bro +++ b/scripts/policy/frameworks/tunnel.bro @@ -2,7 +2,21 @@ ##! ##! Bro can decapsulate IPinIP and IPinUDP tunnels, were "IP" can be either ##! IPv4 or IPv6. The most common case will be decapsulating Teredo, 6to4, -##! 6in4, and AYIAY. +##! 6in4, and AYIAY. When this script is loaded, decapsulation will be +##! enabled. "tunnel.log" will log the "parent" for each tunneled +##! connection. The identity (and existence) of the tunnel connection +##! is otherwise lost. +##! +##! Currently handles: +##! +##! * IP6 in IP{4,6}. (IP4 in IP is easy to add, but omitted due to lack +##! of test cases. +##! * IP{4,6} in UDP. This decapsulates e.g., standard *Teredo* packets +##! (without authentication or origin indicator) +##! * IP{4,6} in AYIAY +##! * Only checks for UDP tunnels on Teredo's and AYIAY's default +##! ports. See :bro:id:`udp_tunnel_ports` and +##! :bro:id:`udp_tunnel_allports` ##! ##! Decapsulation happens early in a packets processing, right after IP ##! defragmentation but before there is a connection context. The tunnel @@ -11,13 +25,14 @@ ##! which is of type :bro:type:`parent_t`. ##! ##! *Limitation:* The decapsulated packets are not fed through the -##! defragmenter again. +##! defragmenter again and decapsulation happens only on the primary +##! path, i.e., it's not available for the secondary path. ##! ##! module Tunnel; -redef use_connection_compressor = F; +#redef use_connection_compressor = F; redef Tunnel::decapsulate_ip = T; redef Tunnel::decapsulate_udp = T; redef Tunnel::udp_tunnel_allports = T; From d0a67dc8bfc9bc21a164a17c57f3dcf65a08eedc Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Wed, 10 Aug 2011 13:47:02 -0700 Subject: [PATCH 07/51] Tweaking tunnel decapsulation. Changing names to comply with "Bro Scripting Conventions" Tweaking documentation. --- doc/scripts/DocSourcesList.cmake | 1 + scripts/base/init-bare.bro | 6 +++--- scripts/policy/frameworks/tunnel.bro | 16 ++++++++++++---- src/TunnelHandler.cc | 8 ++++---- src/TunnelHandler.h | 10 +++++----- src/types.bif | 16 ++++++++-------- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/doc/scripts/DocSourcesList.cmake b/doc/scripts/DocSourcesList.cmake index 54783f61b3..fbf93ce869 100644 --- a/doc/scripts/DocSourcesList.cmake +++ b/doc/scripts/DocSourcesList.cmake @@ -95,6 +95,7 @@ rest_target(${psd} policy/frameworks/dpd/detect-protocols.bro) rest_target(${psd} policy/frameworks/dpd/packet-segment-logging.bro) rest_target(${psd} policy/frameworks/software/version-changes.bro) rest_target(${psd} policy/frameworks/software/vulnerable.bro) +rest_target(${psd} policy/frameworks/tunnel.bro) rest_target(${psd} policy/integration/barnyard2/base.bro) rest_target(${psd} policy/integration/barnyard2/event.bro) rest_target(${psd} policy/integration/barnyard2/types.bro) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 2f83b99bf8..45357fde77 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -84,14 +84,14 @@ type AnalyzerID: count; module Tunnel; export { ## Records the identity of a the parent of a tunneled connection. - type parent_t: record { + type Parent: record { ## The 4-tuple of the tunnel "connection". In case of an IP-in-IP ## tunnel the ports will be set to 0. The direction (i.e., orig and ## resp) of the parent are set according to the tunneled connection ## and not according to the side that established the tunnel. cid: conn_id; ## The type of tunnel. - tunnel_type: tunneltype_t; + tunnel_type: Tunneltype; } &log; } # end export module GLOBAL; @@ -107,7 +107,7 @@ type connection: record { hot: count; # how hot; 0 = don't know or not hot history: string; uid: string; - tunnel_parent: Tunnel::parent_t &optional; + tunnel_parent: Tunnel::Parent &optional; }; type SYN_packet: record { diff --git a/scripts/policy/frameworks/tunnel.bro b/scripts/policy/frameworks/tunnel.bro index ebec2b0f06..a24bd6e1f6 100644 --- a/scripts/policy/frameworks/tunnel.bro +++ b/scripts/policy/frameworks/tunnel.bro @@ -22,7 +22,7 @@ ##! defragmentation but before there is a connection context. The tunnel ##! headers are stripped from packet and the identity of the parent is ##! is stored as the ``tunnel_parent`` member of :bro:type:`connection`, -##! which is of type :bro:type:`parent_t`. +##! which is of type :bro:type:`Tunnel::Parent`. ##! ##! *Limitation:* The decapsulated packets are not fed through the ##! defragmenter again and decapsulation happens only on the primary @@ -30,9 +30,12 @@ ##! ##! +@load base/protocols/conn + module Tunnel; #redef use_connection_compressor = F; +## enab redef Tunnel::decapsulate_ip = T; redef Tunnel::decapsulate_udp = T; redef Tunnel::udp_tunnel_allports = T; @@ -51,14 +54,19 @@ export { ## The child's transport protocol proto: transport_proto &log; ## The parent connection of IP-pair - parent: parent_t &log; + parent: Parent &log; + }; + global log_tunnel: event(rec: Info); + + redef record Conn::Info += { + ## If the connection is tunneled the type of tunnel + tunnel_type: Tunneltype &log &optional; }; - global log_conn: event(rec: Info); } event bro_init() { - Log::create_stream(TUNNEL, [$columns=Info, $ev=log_conn]); + Log::create_stream(TUNNEL, [$columns=Info, $ev=log_tunnel]); } event new_connection(c: connection) diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index 78428c700f..6b1f78e0c0 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -54,7 +54,7 @@ TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int // TODO: check if IP6 header makes sense tunnel_info = new TunnelInfo(); tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload()); - tunnel_info->tunneltype = BifEnum::Tunnel::IP6inIP; + tunnel_info->tunneltype = BifEnum::Tunnel::IP6_IN_IP; tunnel_info->hdr_len = tunnel_info->child->HdrLen(); tunnel_info->SetParentIPs(ip_hdr); return tunnel_info; @@ -86,7 +86,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) const u_char *data = ip_hdr->Payload(); const struct udphdr* uh = (const struct udphdr*)data; IP_Hdr *cand_ip_hdr = 0; - BifEnum::Tunnel::tunneltype_t tunneltype = BifEnum::Tunnel::NONE; + BifEnum::Tunnel::Tunneltype tunneltype = BifEnum::Tunnel::NONE; int hdr_len = sizeof(struct udphdr); data += hdr_len; @@ -103,7 +103,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) if (cand_ip_hdr) { tunneltype = (cand_ip_hdr->IP4_Hdr()) ? - BifEnum::Tunnel::IP4inUDP : BifEnum::Tunnel::IP6inUDP; + BifEnum::Tunnel::IP4_IN_UDP : BifEnum::Tunnel::IP6_IN_UDP; } else if (datalen >= 8) { @@ -129,7 +129,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) { hdr_len += 8 + id_len + sig_len; tunneltype = (cand_ip_hdr->IP4_Hdr()) ? - BifEnum::Tunnel::IP4inAYIAY : BifEnum::Tunnel::IP6inAYIAY; + BifEnum::Tunnel::IP4_IN_AYIAY : BifEnum::Tunnel::IP6_IN_AYIAY; } } if (cand_ip_hdr) diff --git a/src/TunnelHandler.h b/src/TunnelHandler.h index 31c9791a1c..d88e6ff2b4 100644 --- a/src/TunnelHandler.h +++ b/src/TunnelHandler.h @@ -39,11 +39,11 @@ public: RecordVal* GetRecordVal() const { - RecordVal *rv = new RecordVal(BifType::Record::Tunnel::parent_t); + RecordVal *rv = new RecordVal(BifType::Record::Tunnel::Parent); TransportProto tproto; switch(tunneltype) { - case BifEnum::Tunnel::IP6inIP: - case BifEnum::Tunnel::IP4inIP: + case BifEnum::Tunnel::IP6_IN_IP: + case BifEnum::Tunnel::IP4_IN_IP: tproto = TRANSPORT_UNKNOWN; break; default: @@ -56,14 +56,14 @@ public: id_val->Assign(2, new AddrVal(parent.dst_addr)); id_val->Assign(3, new PortVal(ntohs(parent.dst_port), tproto)); rv->Assign(0, id_val); - rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::tunneltype_t)); + rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::Tunneltype)); return rv; } IP_Hdr *child; ConnID parent; int hdr_len; - BifEnum::Tunnel::tunneltype_t tunneltype; + BifEnum::Tunnel::Tunneltype tunneltype; }; class TunnelHandler { diff --git a/src/types.bif b/src/types.bif index 35c4db0daf..5f1c4b850b 100644 --- a/src/types.bif +++ b/src/types.bif @@ -168,16 +168,16 @@ enum ID %{ module Tunnel; -enum tunneltype_t %{ +enum Tunneltype %{ NONE, - IP6inIP, - IP4inIP, - IP6inUDP, - IP4inUDP, - IP6inAYIAY, - IP4inAYIAY, + IP6_IN_IP, + IP4_IN_IP, + IP6_IN_UDP, + IP4_IN_UDP, + IP6_IN_AYIAY, + IP4_IN_AYIAY, %} -type parent_t: record; +type Parent: record; module GLOBAL; From 65921bc61da9a27dffeba46a8d6fe706cdc31e75 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Fri, 12 Aug 2011 21:42:47 -0700 Subject: [PATCH 08/51] Bugfix: an #ifdef BROv6 was missing in the tunnel code --- src/TunnelHandler.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index 6b1f78e0c0..4df3f489ad 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -102,6 +102,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) cand_ip_hdr = LookForIPHdr(data, datalen); if (cand_ip_hdr) { + // Found and IP hdr directly in the UDP payload tunneltype = (cand_ip_hdr->IP4_Hdr()) ? BifEnum::Tunnel::IP4_IN_UDP : BifEnum::Tunnel::IP6_IN_UDP; } @@ -155,8 +156,10 @@ IP_Hdr* TunnelHandler::LookForIPHdr(const u_char *data, int datalen) const struct ip *ip4 = (const struct ip*)(data); if (ip4->ip_v == 4) cand_ip_hdr = new IP_Hdr((const struct ip*)ip4); +#ifdef BROv6 else if (ip4->ip_v == 6 && (datalen > (int)sizeof(struct ip6_hdr))) cand_ip_hdr = new IP_Hdr((const struct ip6_hdr*)data); +#endif if (cand_ip_hdr) { From 08dc84a2504483a3b5827dbf65e7cc68bf9e9516 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Tue, 16 Aug 2011 20:41:36 -0700 Subject: [PATCH 09/51] Tunnel decapsulation bugfix when FlipRoles is called. If FlipRoles() is called the conn_val in Conn.cc gets Unref'ed and thus my tunnel_partent RecordVal was lost. Fixing this. --- src/Conn.cc | 9 ++++-- src/Conn.h | 5 +-- src/Sessions.cc | 8 ++--- src/TunnelHandler.cc | 4 +-- src/TunnelHandler.h | 75 ++++++++++++++++++++++++++++---------------- 5 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/Conn.cc b/src/Conn.cc index 67e337fda9..e3e56c5eef 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -15,6 +15,7 @@ #include "Timer.h" #include "PIA.h" #include "binpac.h" +#include "TunnelHandler.h" HashKey* ConnID::BuildConnKey() const { @@ -139,7 +140,7 @@ unsigned int Connection::external_connections = 0; IMPLEMENT_SERIAL(Connection, SER_CONNECTION); -Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent) +Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent* arg_tunnel_parent) { sessions = s; key = k; @@ -209,6 +210,9 @@ Connection::~Connection() Unref(conn_val); } + if ( tunnel_parent ) + delete tunnel_parent; + delete key; delete root_analyzer; delete conn_timer_mgr; @@ -372,7 +376,8 @@ RecordVal* Connection::BuildConnVal() char tmp[20]; conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62))); - conn_val->Assign(10, tunnel_parent); + if ( tunnel_parent ) + conn_val->Assign(10, tunnel_parent->GetRecordVal()); } if ( root_analyzer ) diff --git a/src/Conn.h b/src/Conn.h index e22c0b83ec..828ad66e7c 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -23,6 +23,7 @@ class RuleHdrTest; class Specific_RE_Matcher; class TransportLayerAnalyzer; class RuleEndpointState; +class TunnelParent; typedef enum { NUL_IN_LINE, @@ -86,7 +87,7 @@ class Analyzer; class Connection : public BroObj { public: - Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent); + Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent *arg_tunnel_parent); virtual ~Connection(); // Invoked when connection is about to be removed. Use Ref(this) @@ -335,7 +336,7 @@ protected: double inactivity_timeout; RecordVal* conn_val; LoginConn* login_conn; // either nil, or this - RecordVal* tunnel_parent; // nil if not tunneled + TunnelParent* tunnel_parent; // nil if not tunneled int suppress_event; // suppress certain events to once per conn. unsigned int installed_status_timer:1; diff --git a/src/Sessions.cc b/src/Sessions.cc index fa0d573660..34bfa360dd 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -1018,11 +1018,8 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, int src_h = ntohs(id->src_port); int dst_h = ntohs(id->dst_port); int flags = 0; - RecordVal *tunnel_parent = 0; + TunnelParent *tunnel_parent = 0; - if ( tunnel_info ) - tunnel_parent = tunnel_info->GetRecordVal(); - // Hmm... This is not great. TransportProto tproto; switch ( proto ) { @@ -1068,6 +1065,9 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, id = &flip_id; } + if ( tunnel_info ) + tunnel_parent = new TunnelParent(&(tunnel_info->parent)); + Connection* conn = new Connection(this, k, t, id, tunnel_parent); conn->SetTransport(tproto); dpm->BuildInitialAnalyzerTree(tproto, conn, data); diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index 4df3f489ad..a5ee9cae3c 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -54,7 +54,7 @@ TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int // TODO: check if IP6 header makes sense tunnel_info = new TunnelInfo(); tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload()); - tunnel_info->tunneltype = BifEnum::Tunnel::IP6_IN_IP; + tunnel_info->parent.tunneltype = BifEnum::Tunnel::IP6_IN_IP; tunnel_info->hdr_len = tunnel_info->child->HdrLen(); tunnel_info->SetParentIPs(ip_hdr); return tunnel_info; @@ -137,7 +137,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) { TunnelInfo *tunnel_info = new TunnelInfo(); tunnel_info->child = cand_ip_hdr; - tunnel_info->tunneltype = tunneltype; + tunnel_info->parent.tunneltype = tunneltype; tunnel_info->SetParentIPs(ip_hdr); tunnel_info->SetParentPorts(uh); tunnel_info->hdr_len = hdr_len + cand_ip_hdr->HdrLen(); diff --git a/src/TunnelHandler.h b/src/TunnelHandler.h index d88e6ff2b4..b5c69b7eff 100644 --- a/src/TunnelHandler.h +++ b/src/TunnelHandler.h @@ -4,37 +4,29 @@ #define tunnelhandler_h #include +#include "net_util.h" #include "IP.h" #include "Conn.h" #include "Sessions.h" #include "Val.h" - -class TunnelInfo { +class TunnelParent { public: - TunnelInfo() + TunnelParent() { - child = 0; tunneltype = BifEnum::Tunnel::NONE; - hdr_len = 0; - parent.src_addr = parent.dst_addr = 0; - parent.src_port = parent.dst_port = 0; - parent.is_one_way = 0; - } - ~TunnelInfo() - { - if (child) delete child; + src_port = dst_port = 0; + for (int i=0; iSrcAddr(); - parent.dst_addr = ip_hdr->DstAddr(); - } - void SetParentPorts(const struct udphdr *uh) - { - parent.src_port = uh->uh_sport; - parent.dst_port = uh->uh_dport; + tunneltype = other->tunneltype; + copy_addr(other->src_addr, src_addr); + copy_addr(other->dst_addr, dst_addr); + src_port = other->src_port; + dst_port = other->dst_port; } RecordVal* GetRecordVal() const @@ -51,21 +43,50 @@ public: } // end switch RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal(parent.src_addr)); - id_val->Assign(1, new PortVal(ntohs(parent.src_port), tproto)); - id_val->Assign(2, new AddrVal(parent.dst_addr)); - id_val->Assign(3, new PortVal(ntohs(parent.dst_port), tproto)); + id_val->Assign(0, new AddrVal(src_addr)); + id_val->Assign(1, new PortVal(ntohs(src_port), tproto)); + id_val->Assign(2, new AddrVal(dst_addr)); + id_val->Assign(3, new PortVal(ntohs(dst_port), tproto)); rv->Assign(0, id_val); rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::Tunneltype)); return rv; } - IP_Hdr *child; - ConnID parent; - int hdr_len; + uint32 src_addr[NUM_ADDR_WORDS]; + uint32 dst_addr[NUM_ADDR_WORDS]; + uint16 src_port; + uint16 dst_port; BifEnum::Tunnel::Tunneltype tunneltype; }; +class TunnelInfo { +public: + TunnelInfo() + { + child = 0; + hdr_len = 0; + } + ~TunnelInfo() + { + if (child) delete child; + } + + void SetParentIPs(const IP_Hdr *ip_hdr) + { + copy_addr(ip_hdr->SrcAddr(), parent.src_addr); + copy_addr(ip_hdr->DstAddr(), parent.dst_addr); + } + void SetParentPorts(const struct udphdr *uh) + { + parent.src_port = uh->uh_sport; + parent.dst_port = uh->uh_dport; + } + + IP_Hdr *child; + TunnelParent parent; + int hdr_len; +}; + class TunnelHandler { public: TunnelHandler(NetSessions *arg_s); From 4214d8d9057d491cb6066d0b4e579c83fbbfc4cb Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Wed, 17 Aug 2011 07:31:25 -0700 Subject: [PATCH 10/51] Fixing memleak in tunnel code. --- src/Sessions.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Sessions.cc b/src/Sessions.cc index 34bfa360dd..b6e19f4cf4 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -355,6 +355,12 @@ static bool looks_like_IPv4_packet(int len, const struct ip* ip_hdr) return false; } +static inline void delete_tunnel_info(TunnelInfo *ti) + { + if ( ti ) + delete ti; + } + void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, int hdr_size) @@ -438,6 +444,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, proto != IPPROTO_ICMP ) { dump_this_packet = 1; + delete_tunnel_info(tunnel_info); return; } @@ -449,6 +456,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, Weird("truncated_header", hdr, pkt); if ( f ) Remove(f); // ### + delete_tunnel_info(tunnel_info); return; } if ( caplen < min_hdr_len ) @@ -456,6 +464,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, Weird("internally_truncated_header", hdr, pkt); if ( f ) Remove(f); // ### + delete_tunnel_info(tunnel_info); return; } @@ -507,6 +516,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, default: Weird(fmt("unknown_protocol %d", proto), hdr, pkt); + delete_tunnel_info(tunnel_info); return; } @@ -536,6 +546,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( consistent < 0 ) { delete h; + delete_tunnel_info(tunnel_info); return; } @@ -558,7 +569,10 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } if ( ! conn ) + { + delete_tunnel_info(tunnel_info); return; + } int record_packet = 1; // whether to record the packet at all int record_content = 1; // whether to record its data From f3a92ec30b94be0fca8dfec5447e901b8847c7cc Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Tue, 23 Aug 2011 20:28:11 -0700 Subject: [PATCH 11/51] Minor fixes for possible leaks on uncommon code path or on initialization. --- src/Sessions.cc | 8 ++++++++ src/TunnelHandler.cc | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index b6e19f4cf4..382bd9c5b3 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -444,6 +444,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, proto != IPPROTO_ICMP ) { dump_this_packet = 1; + if ( f ) + Remove(t); delete_tunnel_info(tunnel_info); return; } @@ -516,6 +518,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, default: Weird(fmt("unknown_protocol %d", proto), hdr, pkt); + if ( f ) + Remove(f); delete_tunnel_info(tunnel_info); return; } @@ -546,6 +550,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( consistent < 0 ) { delete h; + if ( f ) + Remove(f); delete_tunnel_info(tunnel_info); return; } @@ -571,6 +577,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( ! conn ) { delete_tunnel_info(tunnel_info); + if ( f ) + Remove(f); return; } diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index a5ee9cae3c..a7fbd4ce29 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -24,7 +24,8 @@ TunnelHandler::TunnelHandler(NetSessions *arg_s) // lookup. for (int i=0; i< 65536; i++) { - Unref(pv); + if (pv) + Unref(pv); pv = new PortVal(i, TRANSPORT_UDP); if (udp_tunnel_ports->Lookup(pv, false)) { From 1936989422311d62bb08dc1466f6e82bea8409c8 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Tue, 23 Aug 2011 20:46:33 -0700 Subject: [PATCH 12/51] Fix compile error due to typo. --- src/Sessions.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index 382bd9c5b3..47696a1651 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -445,7 +445,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, { dump_this_packet = 1; if ( f ) - Remove(t); + Remove(f); delete_tunnel_info(tunnel_info); return; } From bcadb67731482b26e2b3c0b7103f1f51c1ca0de3 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Sat, 21 Apr 2012 14:42:20 -0400 Subject: [PATCH 13/51] First commit of binpac based AYIYA analyzer. - ayiya-analyzer.pac needs work to do something with the actual packet. - Lots more cleanup to do, but it parses the protocol at least. --- src/AYIYA.cc | 90 ++++++++++++++++++++++++++++++++++++++++++ src/AYIYA.h | 55 ++++++++++++++++++++++++++ src/Analyzer.cc | 11 ++++++ src/AnalyzerTags.h | 8 +++- src/CMakeLists.txt | 4 ++ src/ayiya-analyzer.pac | 25 ++++++++++++ src/ayiya-protocol.pac | 14 +++++++ src/ayiya.pac | 10 +++++ 8 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 src/AYIYA.cc create mode 100644 src/AYIYA.h create mode 100644 src/ayiya-analyzer.pac create mode 100644 src/ayiya-protocol.pac create mode 100644 src/ayiya.pac diff --git a/src/AYIYA.cc b/src/AYIYA.cc new file mode 100644 index 0000000000..d69db642b3 --- /dev/null +++ b/src/AYIYA.cc @@ -0,0 +1,90 @@ +#include "AYIYA.h" +#include "TCP_Reassembler.h" + +AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn) +: Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn) + { + interp = new binpac::AYIYA::AYIYA_Conn(this); + did_session_done = 0; + //ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer, + // network_time + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); + } + +AYIYA_Analyzer::~AYIYA_Analyzer() + { + delete interp; + } + +void AYIYA_Analyzer::Done() + { + Analyzer::Done(); + + if ( ! did_session_done ) + Event(udp_session_done); + } + +void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + interp->NewData(orig, data, data + len); + } + +//void AYIYA_Analyzer::ExpireTimer(double t) +// { +// // The - 1.0 in the following is to allow 1 second for the +// // common case of a single request followed by a single reply, +// // so we don't needlessly set the timer twice in that case. +// if ( t - Conn()->LastTime() >= Syslog_session_timeout - 1.0 || terminating ) +// { +// Event(connection_timeout); +// sessions->Remove(Conn()); +// } +// else +// ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer, +// t + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); +// } + +//Syslog_TCP_Analyzer_binpac::Syslog_TCP_Analyzer_binpac(Connection* conn) +//: TCP_ApplicationAnalyzer(AnalyzerTag::Syslog_TCP_BINPAC, conn) +// { +// interp = new binpac::Syslog_on_TCP::Syslog_TCP_Conn(this); +// } + +//Syslog_TCP_Analyzer_binpac::~Syslog_TCP_Analyzer_binpac() +// { +// delete interp; +// } + +//void Syslog_TCP_Analyzer_binpac::Done() +// { +// TCP_ApplicationAnalyzer::Done(); +// +// interp->FlowEOF(true); +// interp->FlowEOF(false); +// } + +//void Syslog_TCP_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp) +// { +// TCP_ApplicationAnalyzer::EndpointEOF(endp); +// interp->FlowEOF(endp->IsOrig()); +// } + +//void Syslog_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data, +// bool orig) +// { +// TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); +// +// assert(TCP()); +// +// if ( TCP()->IsPartial() || TCP()->HadGap(orig) ) +// // punt-on-partial or stop-on-gap. +// return; +// +// interp->NewData(orig, data, data + len); +// } + +//void Syslog_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig) +// { +// TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); +// interp->NewGap(orig, len); +// } diff --git a/src/AYIYA.h b/src/AYIYA.h new file mode 100644 index 0000000000..294eeca1ea --- /dev/null +++ b/src/AYIYA.h @@ -0,0 +1,55 @@ +#ifndef AYIYA_h +#define AYIYA_h + +#include "UDP.h" +#include "TCP.h" + +#include "ayiya_pac.h" + +class AYIYA_Analyzer : public Analyzer { +public: + AYIYA_Analyzer(Connection* conn); + virtual ~AYIYA_Analyzer(); + + virtual void Done(); + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static Analyzer* InstantiateAnalyzer(Connection* conn) + { return new AYIYA_Analyzer(conn); } + + static bool Available() + { return true; } + +protected: + friend class AnalyzerTimer; + void ExpireTimer(double t); + + int did_session_done; + + binpac::AYIYA::AYIYA_Conn* interp; +}; + +// #include "Syslog_tcp_pac.h" +// +//class Syslog_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer { +//public: +// Syslog_TCP_Analyzer_binpac(Connection* conn); +// virtual ~Syslog_TCP_Analyzer_binpac(); +// +// virtual void Done(); +// virtual void DeliverStream(int len, const u_char* data, bool orig); +// virtual void Undelivered(int seq, int len, bool orig); +// virtual void EndpointEOF(TCP_Reassembler* endp); +// +// static Analyzer* InstantiateAnalyzer(Connection* conn) +// { return new Syslog_TCP_Analyzer_binpac(conn); } +// +// static bool Available() +// { return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; } +// +//protected: +// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp; +//}; +// +#endif diff --git a/src/Analyzer.cc b/src/Analyzer.cc index 92ca3ecc50..70bb5567cc 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -4,6 +4,7 @@ #include "PIA.h" #include "Event.h" +#include "AYIYA.h" #include "BackDoor.h" #include "BitTorrent.h" #include "BitTorrentTracker.h" @@ -127,6 +128,16 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { Syslog_Analyzer_binpac::InstantiateAnalyzer, Syslog_Analyzer_binpac::Available, 0, false }, + //{ AnalyzerTag::6to4, "6to4", + // 6to4_Analyzer::InstantiateAnalyzer, + // 6to4_Anylzer::Available, 0, false }, + { AnalyzerTag::AYIYA, "AYIYA", + AYIYA_Analyzer::InstantiateAnalyzer, + AYIYA_Analyzer::Available, 0, false }, + //{ AnalyzerTag::Teredo, "Teredo", + // Teredo_Analyzer::InstantiateAnalyzer, + // Teredo_Analyzer::Available, 0, false }, + { AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer, File_Analyzer::Available, 0, false }, { AnalyzerTag::Backdoor, "BACKDOOR", diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index dc10a55f22..0f9794527e 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -33,11 +33,15 @@ namespace AnalyzerTag { DHCP_BINPAC, DNS_TCP_BINPAC, DNS_UDP_BINPAC, HTTP_BINPAC, SSL, SYSLOG_BINPAC, + // Decapsulation Analyzers + //6to4, + AYIYA, + //Teredo, + // Other File, Backdoor, InterConn, SteppingStone, TCPStats, ConnSize, - - + // Support-analyzers Contents, ContentLine, NVT, Zip, Contents_DNS, Contents_NCP, Contents_NetbiosSSN, Contents_Rlogin, Contents_Rsh, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a755fde64e..6cca13de16 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -186,6 +186,9 @@ endmacro(BINPAC_TARGET) binpac_target(binpac-lib.pac) binpac_target(binpac_bro-lib.pac) + +binpac_target(ayiya.pac + ayiya-protocol.pac ayiya-analyzer.pac) binpac_target(bittorrent.pac bittorrent-protocol.pac bittorrent-analyzer.pac) binpac_target(dce_rpc.pac @@ -277,6 +280,7 @@ set(bro_SRCS Anon.cc ARP.cc Attr.cc + AYIYA.cc BackDoor.cc Base64.cc BitTorrent.cc diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac new file mode 100644 index 0000000000..888cc575a5 --- /dev/null +++ b/src/ayiya-analyzer.pac @@ -0,0 +1,25 @@ + +connection AYIYA_Conn(bro_analyzer: BroAnalyzer) + { + upflow = AYIYA_Flow; + downflow = AYIYA_Flow; + }; + +flow AYIYA_Flow + { + datagram = PDU withcontext(connection, this); + + function process_ayiya(pdu: PDU): bool + %{ + connection()->bro_analyzer()->ProtocolConfirmation(); + + // Not sure what to do here. + printf("packet: %s\n", ${pdu.packet}.data()); + return true; + %} + + }; + +refine typeattr PDU += &let { + proc_ayiya = $context.flow.process_ayiya(this); +}; diff --git a/src/ayiya-protocol.pac b/src/ayiya-protocol.pac new file mode 100644 index 0000000000..25aca23fb9 --- /dev/null +++ b/src/ayiya-protocol.pac @@ -0,0 +1,14 @@ + +type PDU = record { + identity_byte: uint8; + signature_byte: uint8; + auth_and_op_crap: uint8; + next_header: uint8; + epoch: uint32; + identity: bytestring &length=identity_len; + signature: bytestring &length=signature_len; + packet: bytestring &restofdata; +} &let { + identity_len = (1 << (identity_byte >> 4)); + signature_len = (signature_byte >> 4) * 4; +} &byteorder = littleendian; \ No newline at end of file diff --git a/src/ayiya.pac b/src/ayiya.pac new file mode 100644 index 0000000000..58fa196c15 --- /dev/null +++ b/src/ayiya.pac @@ -0,0 +1,10 @@ +%include binpac.pac +%include bro.pac + +analyzer AYIYA withcontext { + connection: AYIYA_Conn; + flow: AYIYA_Flow; +}; + +%include ayiya-protocol.pac +%include ayiya-analyzer.pac From 69ab13c88ff8598e29692d7fc166a56f7a807f05 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Sat, 21 Apr 2012 15:10:30 -0400 Subject: [PATCH 14/51] Added some scripts for a tunnels framework. - The AYIYA analyzer is now enabled on it's default port. --- scripts/base/frameworks/tunnels/__load__.bro | 1 + scripts/base/frameworks/tunnels/main.bro | 8 ++++++++ scripts/base/init-default.bro | 1 + 3 files changed, 10 insertions(+) create mode 100644 scripts/base/frameworks/tunnels/__load__.bro create mode 100644 scripts/base/frameworks/tunnels/main.bro diff --git a/scripts/base/frameworks/tunnels/__load__.bro b/scripts/base/frameworks/tunnels/__load__.bro new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/frameworks/tunnels/__load__.bro @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro new file mode 100644 index 0000000000..901bee9a75 --- /dev/null +++ b/scripts/base/frameworks/tunnels/main.bro @@ -0,0 +1,8 @@ +module Tunnels; + +export { + +} + +const ports = { 5072/udp } &redef; +redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ports] }; diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 1cf125c3ab..ecaa19132c 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -29,6 +29,7 @@ @load base/frameworks/metrics @load base/frameworks/intel @load base/frameworks/reporter +@load base/frameworks/tunnels @load base/protocols/conn @load base/protocols/dns From dff3fabcea13d83caf68c985cac5ca8c049c657a Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Sat, 21 Apr 2012 15:25:19 -0400 Subject: [PATCH 15/51] Added a DPD signature for AYIYA, but it's crashing Bro. --- scripts/base/frameworks/dpd/dpd.sig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/base/frameworks/dpd/dpd.sig b/scripts/base/frameworks/dpd/dpd.sig index adda0ce54e..8408d7617a 100644 --- a/scripts/base/frameworks/dpd/dpd.sig +++ b/scripts/base/frameworks/dpd/dpd.sig @@ -149,3 +149,9 @@ signature dpd_ssl_client { payload /^(\x16\x03[\x00\x01\x02]..\x01...\x03[\x00\x01\x02]|...?\x01[\x00\x01\x02][\x02\x03]).*/ tcp-state originator } + +#signature dpd_ayiya { +# ip-proto = udp +# payload /^..\x11\x29/ +# enable "ayiya" +#} From e2da96941530a475e4573af1ddb96e23de05b658 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Sat, 21 Apr 2012 23:50:09 -0400 Subject: [PATCH 16/51] Return of Robin's old SOCKS analyzer/decapsulator and tunnel code checkpoint. - More discussion is needed to figure out how to integrate the SOCKS analyzer best. - Tunnels framework now logs for the SOCKS analyzer. --- scripts/base/frameworks/dpd/dpd.sig | 31 +++++ scripts/base/frameworks/tunnels/__load__.bro | 5 +- scripts/base/frameworks/tunnels/main.bro | 51 +++++++- scripts/base/init-default.bro | 1 + scripts/base/protocols/socks/__load__.bro | 1 + scripts/base/protocols/socks/main.bro | 116 +++++++++++++++++++ src/Analyzer.cc | 4 + src/AnalyzerTags.h | 1 + src/CMakeLists.txt | 3 + src/SOCKS.cc | 79 +++++++++++++ src/SOCKS.h | 45 +++++++ src/event.bif | 20 ++++ src/socks-analyzer.pac | 57 +++++++++ src/socks-protocol.pac | 34 ++++++ src/socks.pac | 24 ++++ 15 files changed, 468 insertions(+), 4 deletions(-) create mode 100644 scripts/base/protocols/socks/__load__.bro create mode 100644 scripts/base/protocols/socks/main.bro create mode 100644 src/SOCKS.cc create mode 100644 src/SOCKS.h create mode 100644 src/socks-analyzer.pac create mode 100644 src/socks-protocol.pac create mode 100644 src/socks.pac diff --git a/scripts/base/frameworks/dpd/dpd.sig b/scripts/base/frameworks/dpd/dpd.sig index 8408d7617a..f5d3651104 100644 --- a/scripts/base/frameworks/dpd/dpd.sig +++ b/scripts/base/frameworks/dpd/dpd.sig @@ -155,3 +155,34 @@ signature dpd_ssl_client { # payload /^..\x11\x29/ # enable "ayiya" #} + +signature dpd_socks_client { + ip-proto == tcp + # '32' is a rather arbitrary max length for the user name. + payload /^\x04[\x01\x02].{0,32}\x00/ + tcp-state originator +} + +signature dpd_socks_server { + ip-proto == tcp + requires-reverse-signature dpd_socks_client + payload /^\x00[\x5a\x5b\x5c\x5d]/ + tcp-state responder + enable "socks" +} + +signature dpd_socks_reverse_client { + ip-proto == tcp + # '32' is a rather arbitrary max length for the user name. + payload /^\x04[\x01\x02].{0,32}\x00/ + tcp-state responder +} + +signature dpd_socks_reverse_server { + ip-proto == tcp + requires-reverse-signature dpd_socks_client + payload /^\x00[\x5a\x5b\x5c\x5d]/ + tcp-state originator + enable "socks" +} + diff --git a/scripts/base/frameworks/tunnels/__load__.bro b/scripts/base/frameworks/tunnels/__load__.bro index d551be57d3..3def3511f5 100644 --- a/scripts/base/frameworks/tunnels/__load__.bro +++ b/scripts/base/frameworks/tunnels/__load__.bro @@ -1 +1,4 @@ -@load ./main \ No newline at end of file +@load ./main + +const ports = { 5072/udp } &redef; +redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ports] }; diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 901bee9a75..987939eb6e 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -1,8 +1,53 @@ module Tunnels; export { - + redef enum Log::ID += { LOG }; + + type Action: enum { + DISCOVER, + CLOSE, + }; + + type Info: record { + ts: time &log; + uid: string &log; + id: conn_id &log; + action: Action &log; + tunnel_type: string &log; + user: string &log &optional; + }; + + global register: function(c: connection, tunnel_type: string); + + global active: table[conn_id] of Tunnels::Info = table(); } -const ports = { 5072/udp } &redef; -redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ports] }; +event bro_init() &priority=5 + { + Log::create_stream(Tunnels::LOG, [$columns=Info]); + } + +function register(c: connection, tunnel_type: string) + { + local tunnel: Info; + tunnel$ts = network_time(); + tunnel$uid = c$uid; + tunnel$id = c$id; + tunnel$action = DISCOVER; + tunnel$tunnel_type = tunnel_type; + + active[c$id] = tunnel; + Log::write(LOG, tunnel); + } + +event connection_state_remove(c: connection) &priority=-5 + { + if ( c$id in active ) + { + local tunnel = active[c$id]; + tunnel$action=CLOSE; + Log::write(LOG, tunnel); + + delete active[c$id]; + } + } \ No newline at end of file diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index ecaa19132c..91011738d1 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -37,6 +37,7 @@ @load base/protocols/http @load base/protocols/irc @load base/protocols/smtp +@load base/protocols/socks @load base/protocols/ssh @load base/protocols/ssl @load base/protocols/syslog diff --git a/scripts/base/protocols/socks/__load__.bro b/scripts/base/protocols/socks/__load__.bro new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/protocols/socks/__load__.bro @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro new file mode 100644 index 0000000000..61f569d56c --- /dev/null +++ b/scripts/base/protocols/socks/main.bro @@ -0,0 +1,116 @@ +@load base/frameworks/tunnels + +module SOCKS; + +export { + type RequestType: enum { + CONNECTION = 1, + PORT = 2, + }; +} + +event socks_request(c: connection, request_type: count, dstaddr: addr, dstname: string, p: port, user: string) + { + Tunnels::register(c, "SOCKS"); + } + +# +#global output = open_log_file("socks"); +# +#type socks_conn: record { +# id: conn_id; +# t: time; +# req: socks_request_type &optional; +# dstaddr: addr &optional; +# dstname: string &optional; +# p: port &optional; +# user: string &optional; +# service: string &optional; +# variant: string &default = "SOCKS v4"; +# granted: string &default = "no-reply"; +#}; +# +# +#global conns: table[conn_id] of socks_conn; +#global proxies: set[addr] &read_expire = 24hrs; +# +#event socks_request(c: connection, t: socks_request_type, dstaddr: addr, dstname: string, p: port, user: string) +# { +# local id = c$id; +# +# local sc: socks_conn; +# sc$id = id; +# sc$t = c$start_time; +# sc$req = t; +# +# if ( dstaddr != 0.0.0.0 ) +# sc$dstaddr = dstaddr; +# +# if ( dstname != "" ) +# sc$dstname = dstname; +# +# if ( p != 0/tcp ) +# sc$p = p; +# +# if ( user != "" ) +# sc$user = user; +# +# conns[id] = sc; +# } +# +#event socks_reply(c: connection, granted: bool, dst: addr, p: port) +# { +# local id = c$id; +# local sc: socks_conn; +# +# if ( id in conns ) +# sc = conns[id]; +# else +# { +# sc$id = id; +# sc$t = c$start_time; +# conns[id] = sc; +# } +# +# sc$granted = granted ? "ok" : "denied"; +# +# local proxy = c$id$resp_h; +# +# if ( proxy !in proxies ) +# { +# NOTICE([$note=SOCKSProxy, $src=proxy, $sub=sc$variant, +# $msg=fmt("SOCKS proxy seen at %s (%s)", proxy, sc$variant)]); +# add proxies[proxy]; +# } +# } +# +#function print_conn(sc: socks_conn) +# { +# local req = ""; +# if ( sc?$req ) +# { +# if ( sc$req == SOCKS_CONNECTION ) +# req = "relay-to"; +# if ( sc$req == SOCKS_PORT ) +# req = "bind-port"; +# } +# +# local p = sc?$p ? fmt("%s", sc$p) : ""; +# +# local dest = sc?$dstaddr +# ? (fmt("%s:%s%s", sc$dstaddr, p, (sc?$dstname ? fmt(" (%s)", sc$dstname) : ""))) +# : (sc?$dstname ? fmt("%s:%s", sc$dstname, p) : ""); +# local user = sc?$user ? fmt(" (user %s)", sc?$user) : ""; +# +# local service = sc?$service ? fmt(" [%s]", sc$service) : ""; +# +# print output, fmt("%.6f %s %s %s %s-> %s%s", sc$t, id_string(sc$id), req, +# dest, user, sc$granted, service); +# } +# +#event connection_state_remove(c: connection) +# { +# if ( c$id in conns ) +# print_conn(conns[c$id]); +# } +# diff --git a/src/Analyzer.cc b/src/Analyzer.cc index 70bb5567cc..f731b36a70 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -34,6 +34,7 @@ #include "NFS.h" #include "Portmap.h" #include "POP3.h" +#include "SOCKS.h" #include "SSH.h" #include "SSL-binpac.h" #include "Syslog-binpac.h" @@ -134,6 +135,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { { AnalyzerTag::AYIYA, "AYIYA", AYIYA_Analyzer::InstantiateAnalyzer, AYIYA_Analyzer::Available, 0, false }, + { AnalyzerTag::SOCKS, "SOCKS", + SOCKS_Analyzer::InstantiateAnalyzer, + SOCKS_Analyzer::Available, 0, false }, //{ AnalyzerTag::Teredo, "Teredo", // Teredo_Analyzer::InstantiateAnalyzer, // Teredo_Analyzer::Available, 0, false }, diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index 0f9794527e..1b65d5219e 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -36,6 +36,7 @@ namespace AnalyzerTag { // Decapsulation Analyzers //6to4, AYIYA, + SOCKS, //Teredo, // Other diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6cca13de16..0481dd1bcd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -208,6 +208,8 @@ binpac_target(netflow.pac netflow-protocol.pac netflow-analyzer.pac) binpac_target(smb.pac smb-protocol.pac smb-pipe.pac smb-mailslot.pac) +binpac_target(socks.pac + socks-protocol.pac socks-analyzer.pac) binpac_target(ssl.pac ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac) binpac_target(syslog.pac @@ -379,6 +381,7 @@ set(bro_SRCS SmithWaterman.cc SMB.cc SMTP.cc + SOCKS.cc SSH.cc SSL-binpac.cc Scope.cc diff --git a/src/SOCKS.cc b/src/SOCKS.cc new file mode 100644 index 0000000000..880f4032e9 --- /dev/null +++ b/src/SOCKS.cc @@ -0,0 +1,79 @@ +#include "SOCKS.h" +#include "socks_pac.h" +#include "TCP_Reassembler.h" + +SOCKS_Analyzer::SOCKS_Analyzer(Connection* conn) +: TCP_ApplicationAnalyzer(AnalyzerTag::SOCKS, conn) + { + interp = new binpac::SOCKS::SOCKS_Conn(this); + orig_done = resp_done = false; + pia = 0; + } + +SOCKS_Analyzer::~SOCKS_Analyzer() + { + delete interp; + } + +void SOCKS_Analyzer::EndpointDone(bool orig) + { + if ( orig ) + orig_done = true; + else + resp_done = true; + } + +void SOCKS_Analyzer::Done() + { + TCP_ApplicationAnalyzer::Done(); + + interp->FlowEOF(true); + interp->FlowEOF(false); + } + +void SOCKS_Analyzer::EndpointEOF(TCP_Reassembler* endp) + { + TCP_ApplicationAnalyzer::EndpointEOF(endp); + interp->FlowEOF(endp->IsOrig()); + } + +void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) + { + TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); + + assert(TCP()); + + if ( TCP()->IsPartial() ) + // punt on partial. + return; + + if ( orig_done && resp_done ) + { + // Finished decapsulating tunnel layer. Now do standard processing + // with the rest of the conneciton. + // + // Note that we assume that no payload data arrives before both endpoints + // are done with there part of the SOCKS protocol. + + if ( ! pia ) + { + pia = new PIA_TCP(Conn()); + AddChildAnalyzer(pia); + pia->FirstPacket(true, 0); + pia->FirstPacket(false, 0); + } + + ForwardStream(len, data, orig); + } + else + { + interp->NewData(orig, data, data + len); + } + } + +void SOCKS_Analyzer::Undelivered(int seq, int len, bool orig) + { + TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + interp->NewGap(orig, len); + } + diff --git a/src/SOCKS.h b/src/SOCKS.h new file mode 100644 index 0000000000..4e18e59e76 --- /dev/null +++ b/src/SOCKS.h @@ -0,0 +1,45 @@ +#ifndef socks_h +#define socks_h + +// SOCKS v4 analyzer. + +#include "TCP.h" +#include "PIA.h" + +namespace binpac { + namespace SOCKS { + class SOCKS_Conn; + } +} + + +class SOCKS_Analyzer : public TCP_ApplicationAnalyzer { +public: + SOCKS_Analyzer(Connection* conn); + ~SOCKS_Analyzer(); + + void EndpointDone(bool orig); + + virtual void Done(); + virtual void DeliverStream(int len, const u_char* data, bool orig); + virtual void Undelivered(int seq, int len, bool orig); + virtual void EndpointEOF(TCP_Reassembler* endp); + + static Analyzer* InstantiateAnalyzer(Connection* conn) + { return new SOCKS_Analyzer(conn); } + + static bool Available() + { + return socks_request || socks_reply; + } + +protected: + + bool orig_done; + bool resp_done; + + PIA_TCP *pia; + binpac::SOCKS::SOCKS_Conn* interp; +}; + +#endif diff --git a/src/event.bif b/src/event.bif index 1ce8907f0b..296a910478 100644 --- a/src/event.bif +++ b/src/event.bif @@ -5976,6 +5976,26 @@ event syslog_message%(c: connection, facility: count, severity: count, msg: stri ## to the event. event signature_match%(state: signature_state, msg: string, data: string%); +## Generated when a SOCKS request is analyzed. +## +## c: The parent connection of the proxy. +## +## t: The type of the request. +## +## dstaddr: Address that the tunneled traffic should be sent to. +## +## dstname: DNS name of the host that the tunneled traffic should be sent to. +## +## p: The destination port for the proxied traffic. +## +## user: Username given for the SOCKS connection. +event socks_request%(c: connection, request_type: count, dstaddr: addr, dstname: string, p: port, user: string%); + +## Generated when a SOCKS reply is analyzed. +## +## +event socks_reply%(c: connection, granted: bool, dst: addr, p: port%); + ## Generated when a protocol analyzer finds an identification of a software ## used on a system. This is a protocol-independent event that is fed by ## different analyzers. For example, the HTTP analyzer reports user-agent and diff --git a/src/socks-analyzer.pac b/src/socks-analyzer.pac new file mode 100644 index 0000000000..4c7b6e7a1d --- /dev/null +++ b/src/socks-analyzer.pac @@ -0,0 +1,57 @@ + +%header{ +StringVal* array_to_string(vector *a); +%} + +%code{ +StringVal* array_to_string(vector *a) + { + int len = a->size(); + char tmp[len]; + char *s = tmp; + for ( vector::iterator i = a->begin(); i != a->end(); *s++ = *i++ ); + + while ( len > 0 && tmp[len-1] == '\0' ) + --len; + + return new StringVal(len, tmp); + } +%} + +refine connection SOCKS_Conn += { + function socks_request(cmd: uint8, dstaddr: uint32, dstname: uint8[], p: uint16, user: uint8[]): bool + %{ + BifEvent::generate_socks_request(bro_analyzer(), + bro_analyzer()->Conn(), + cmd, + new AddrVal(htonl(dstaddr)), + array_to_string(dstname), + new PortVal(p | TCP_PORT_MASK), + array_to_string(user)); + + static_cast(bro_analyzer())->EndpointDone(true); + + return true; + %} + + function socks_reply(granted: bool, dst: uint32, p: uint16): bool + %{ + BifEvent::generate_socks_reply(bro_analyzer(), + bro_analyzer()->Conn(), + granted, + new AddrVal(htonl(dst)), + new PortVal(p | TCP_PORT_MASK)); + + bro_analyzer()->ProtocolConfirmation(); + static_cast(bro_analyzer())->EndpointDone(false); + return true; + %} +}; + +refine typeattr SOCKS_Request += &let { + proc: bool = $context.connection.socks_request(command, addr, empty, port, user); +}; + +refine typeattr SOCKS_Reply += &let { + proc: bool = $context.connection.socks_reply((status == 0x5a), addr, port); +}; diff --git a/src/socks-protocol.pac b/src/socks-protocol.pac new file mode 100644 index 0000000000..677daeb175 --- /dev/null +++ b/src/socks-protocol.pac @@ -0,0 +1,34 @@ +type SOCKS_Message(is_orig: bool) = case is_orig of { + true -> request: SOCKS_Request; + false -> reply: SOCKS_Reply; +}; + +type SOCKS_Request = record { + version: uint8; + command: uint8; + port: uint16; + addr: uint32; + user: uint8[] &until($element == 0); + + host: case v4a of { + true -> name: uint8[] &until($element == 0); # v4a + false -> empty: uint8[] &length=0; + } &requires(v4a); + + # FIXME: Can this be non-zero? If so we need to keep it for the + # next analyzer. + rest: bytestring &restofdata; +} &byteorder = bigendian &let { + v4a: bool = (addr <= 0x000000ff); +}; + +type SOCKS_Reply = record { + zero: uint8; + status: uint8; + port: uint16; + addr: uint32; + + # FIXME: Can this be non-zero? If so we need to keep it for the + # next analyzer. + rest: bytestring &restofdata; +} &byteorder = bigendian; \ No newline at end of file diff --git a/src/socks.pac b/src/socks.pac new file mode 100644 index 0000000000..4f16582690 --- /dev/null +++ b/src/socks.pac @@ -0,0 +1,24 @@ +%include binpac.pac +%include bro.pac + +%extern{ +#include "SOCKS.h" +%} + +analyzer SOCKS withcontext { + connection: SOCKS_Conn; + flow: SOCKS_Flow; +}; + +connection SOCKS_Conn(bro_analyzer: BroAnalyzer) { + upflow = SOCKS_Flow(true); + downflow = SOCKS_Flow(false); +}; + +%include socks-protocol.pac + +flow SOCKS_Flow(is_orig: bool) { + datagram = SOCKS_Message(is_orig) withcontext(connection, this); +}; + +%include socks-analyzer.pac \ No newline at end of file From b51dd191d78d64bea0db2d6503c1a6350137ae62 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 23 Apr 2012 13:15:29 -0500 Subject: [PATCH 17/51] Refactor IP-in-IP tunnel support. UDP tunnel support removed for now, to be re-added in specific analyzers later, but IP-in-IP is now decapsulated recursively so nested tunnels can be seen and the inner packets get sent through the IP fragment reassembler if necessary. --- scripts/base/init-bare.bro | 36 ++-- scripts/policy/frameworks/tunnel.bro | 5 +- src/Conn.cc | 19 +- src/Conn.h | 8 +- src/NetVar.cc | 7 - src/NetVar.h | 3 - src/Sessions.cc | 102 +++++---- src/Sessions.h | 10 +- src/TunnelHandler.cc | 202 ++++-------------- src/TunnelHandler.h | 156 +++++++------- src/const.bif | 2 +- src/event.bif | 11 + src/types.bif | 10 +- .../Baseline/core.tunnels.ip-in-ip/output | 22 ++ testing/btest/Traces/tunnels/4in4.pcap | Bin 0 -> 106 bytes testing/btest/Traces/tunnels/4in6.pcap | Bin 0 -> 134 bytes testing/btest/Traces/tunnels/6in4.pcap | Bin 0 -> 126 bytes .../Traces/tunnels/6in6-tunnel-change.pcap | Bin 0 -> 268 bytes testing/btest/Traces/tunnels/6in6.pcap | Bin 0 -> 146 bytes testing/btest/Traces/tunnels/6in6in6.pcap | Bin 0 -> 186 bytes testing/btest/core/tunnels/ip-in-ip.test | 30 +++ 21 files changed, 300 insertions(+), 323 deletions(-) create mode 100644 testing/btest/Baseline/core.tunnels.ip-in-ip/output create mode 100644 testing/btest/Traces/tunnels/4in4.pcap create mode 100644 testing/btest/Traces/tunnels/4in6.pcap create mode 100644 testing/btest/Traces/tunnels/6in4.pcap create mode 100644 testing/btest/Traces/tunnels/6in6-tunnel-change.pcap create mode 100644 testing/btest/Traces/tunnels/6in6.pcap create mode 100644 testing/btest/Traces/tunnels/6in6in6.pcap create mode 100644 testing/btest/core/tunnels/ip-in-ip.test diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 7129d8eb68..88f0910d1c 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -179,19 +179,27 @@ type AnalyzerID: count; module Tunnel; export { - ## Records the identity of a the parent of a tunneled connection. - type Parent: record { - ## The 4-tuple of the tunnel "connection". In case of an IP-in-IP + ## Records the identity of an encapsulating parent of a tunneled connection. + type EncapsulatingConn: record { + ## The 4-tuple of the encapsulating "connection". In case of an IP-in-IP ## tunnel the ports will be set to 0. The direction (i.e., orig and - ## resp) of the parent are set according to the tunneled connection + ## resp) are set according to the first tunneled packet seen ## and not according to the side that established the tunnel. cid: conn_id; ## The type of tunnel. - tunnel_type: Tunneltype; + tunnel_type: Tunnel::Type; } &log; } # end export module GLOBAL; +## A type alias for a vector of encapsulating "connections", i.e for when +## there are tunnels within tunnels. +## +## .. todo:: We need this type definition only for declaring builtin functions +## via ``bifcl``. We should extend ``bifcl`` to understand composite types +## directly and then remove this alias. +type encapsulating_conns: vector of Tunnel::EncapsulatingConn; + ## Statistics about an endpoint. ## ## todo::Where is this used? @@ -239,8 +247,11 @@ type connection: record { ## used to tag and locate information associated with that connection. uid: string; ## If the connection is tunneled, this field contains information about - ## the encapsulating "connection". - tunnel_parent: Tunnel::Parent &optional; + ## the encapsulating "connection(s)" with the outermost one starting + ## at index zero. It's also always the first such enapsulation seen + ## for the connection unless the :bro:id:`tunnel_changed` event is handled + ## and re-assigns this field to the new encapsulation. + tunnel: encapsulating_conns &optional; }; ## Fields of a SYN packet. @@ -2616,16 +2627,10 @@ const record_all_packets = F &redef; ## .. bro:see:: conn_stats const ignore_keep_alive_rexmit = F &redef; -## Whether the analysis engine parses IP packets encapsulated in -## UDP tunnels. -## -## .. bro:see:: tunnel_port -const parse_udp_tunnels = F &redef; - module Tunnel; export { ## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) - const decapsulate_ip = F &redef; + const decapsulate_ip = T &redef; ## Whether to decapsulate UDP tunnels (e.g., Teredo, IPv4 in UDP) const decapsulate_udp = F &redef; @@ -2640,6 +2645,9 @@ export { ## If udp_tunnel_allports is T :bro:id:`udp_tunnel_ports` is ignored and we ## check every UDP packet for tunnels. const udp_tunnel_allports = F &redef; + + ## The maximum depth of a tunnel to decapsulate until giving up. + const max_depth: count = 2 &redef; } # end export module GLOBAL; diff --git a/scripts/policy/frameworks/tunnel.bro b/scripts/policy/frameworks/tunnel.bro index 98a860653c..fb9bf2f3f6 100644 --- a/scripts/policy/frameworks/tunnel.bro +++ b/scripts/policy/frameworks/tunnel.bro @@ -24,9 +24,8 @@ ##! is stored as the ``tunnel_parent`` member of :bro:type:`connection`, ##! which is of type :bro:type:`Tunnel::Parent`. ##! -##! *Limitation:* The decapsulated packets are not fed through the -##! defragmenter again and decapsulation happens only on the primary -##! path, i.e., it's not available for the secondary path. +##! *Limitation:* decapsulation happens only on the primary path, i.e. +##! it's not available for the secondary path. @load base/protocols/conn diff --git a/src/Conn.cc b/src/Conn.cc index c2008b1faa..80c026e781 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -112,7 +112,8 @@ unsigned int Connection::external_connections = 0; IMPLEMENT_SERIAL(Connection, SER_CONNECTION); -Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent* arg_tunnel_parent) +Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, + const Encapsulation& arg_encap) { sessions = s; key = k; @@ -156,7 +157,7 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, T uid = 0; // Will set later. - tunnel_parent = arg_tunnel_parent; + encapsulation = arg_encap; if ( conn_timer_mgr ) { @@ -182,7 +183,6 @@ Connection::~Connection() Unref(conn_val); } - delete tunnel_parent; delete key; delete root_analyzer; delete conn_timer_mgr; @@ -192,6 +192,15 @@ Connection::~Connection() --external_connections; } +void Connection::CheckEncapsulation(const Encapsulation& arg_encap) + { + if ( encapsulation != arg_encap ) + { + Event(tunnel_changed, 0, arg_encap.GetVectorVal()); + encapsulation = arg_encap; + } + } + void Connection::Done() { finished = 1; @@ -346,8 +355,8 @@ RecordVal* Connection::BuildConnVal() char tmp[20]; conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62))); - if ( tunnel_parent ) - conn_val->Assign(10, tunnel_parent->GetRecordVal()); + if ( encapsulation.Depth() > 0 ) + conn_val->Assign(10, encapsulation.GetVectorVal()); } if ( root_analyzer ) diff --git a/src/Conn.h b/src/Conn.h index 99af34a07a..9cdb746b7c 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -13,6 +13,7 @@ #include "RuleMatcher.h" #include "AnalyzerTags.h" #include "IPAddr.h" +#include "TunnelHandler.h" class Connection; class ConnectionTimer; @@ -51,9 +52,12 @@ class Analyzer; class Connection : public BroObj { public: - Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent *arg_tunnel_parent); + Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, + const Encapsulation& arg_encap); virtual ~Connection(); + void CheckEncapsulation(const Encapsulation& arg_encap); + // Invoked when connection is about to be removed. Use Ref(this) // inside Done to keep the connection object around (though it'll // no longer be accessible from the dictionary of active @@ -276,7 +280,7 @@ protected: double inactivity_timeout; RecordVal* conn_val; LoginConn* login_conn; // either nil, or this - TunnelParent* tunnel_parent; // nil if not tunneled + Encapsulation encapsulation; // tunnels int suppress_event; // suppress certain events to once per conn. unsigned int installed_status_timer:1; diff --git a/src/NetVar.cc b/src/NetVar.cc index 59cc1cc633..390598bb99 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -30,9 +30,6 @@ int partial_connection_ok; int tcp_SYN_ack_ok; int tcp_match_undelivered; -int encap_hdr_size; -int udp_tunnel_port; - double frag_timeout; double tcp_SYN_timeout; @@ -322,10 +319,6 @@ void init_net_var() tcp_SYN_ack_ok = opt_internal_int("tcp_SYN_ack_ok"); tcp_match_undelivered = opt_internal_int("tcp_match_undelivered"); - encap_hdr_size = opt_internal_int("encap_hdr_size"); - - udp_tunnel_port = opt_internal_int("udp_tunnel_port") & ~UDP_PORT_MASK; - frag_timeout = opt_internal_double("frag_timeout"); tcp_SYN_timeout = opt_internal_double("tcp_SYN_timeout"); diff --git a/src/NetVar.h b/src/NetVar.h index 425ea93e09..f5c17f64aa 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -33,9 +33,6 @@ extern int partial_connection_ok; extern int tcp_SYN_ack_ok; extern int tcp_match_undelivered; -extern int encap_hdr_size; -extern int udp_tunnel_port; - extern double frag_timeout; extern double tcp_SYN_timeout; diff --git a/src/Sessions.cc b/src/Sessions.cc index 7d829b602b..769bd68f52 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -126,12 +126,6 @@ NetSessions::NetSessions() arp_analyzer = new ARP_Analyzer(); else arp_analyzer = 0; - - - if ( BifConst::Tunnel::decapsulate_ip || BifConst::Tunnel::decapsulate_udp ) - tunnel_handler = new TunnelHandler(this); - else - tunnel_handler = 0; } NetSessions::~NetSessions() @@ -185,6 +179,8 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, if ( record_all_packets ) DumpPacket(hdr, pkt); + Encapsulation encapsulation; + if ( pkt_elem && pkt_elem->IPHdr() ) // Fast path for "normal" IP packets if an IP_Hdr is // already extracted when doing PacketSort. Otherwise @@ -192,7 +188,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, // difference here is that header extraction in // PacketSort does not generate Weird events. - DoNextPacket(t, hdr, pkt_elem->IPHdr(), pkt, hdr_size); + DoNextPacket(t, hdr, pkt_elem->IPHdr(), pkt, hdr_size, encapsulation); else { @@ -217,7 +213,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, if ( ip->ip_v == 4 ) { IP_Hdr ip_hdr(ip, false); - DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); + DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, encapsulation); } else if ( ip->ip_v == 6 ) @@ -229,7 +225,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, } IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false, caplen); - DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size); + DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, encapsulation); } else if ( ARP_Analyzer::IsARP(pkt, hdr_size) ) @@ -351,7 +347,7 @@ int NetSessions::CheckConnectionTag(Connection* conn) void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size) + int hdr_size, Encapsulation& encapsulation) { uint32 caplen = hdr->caplen - hdr_size; const struct ip* ip4 = ip_hdr->IP4_Hdr(); @@ -458,24 +454,10 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } #endif - TunnelInfo *tunnel_info = 0; - if ( tunnel_handler ) - { - tunnel_info = tunnel_handler->DecapsulateTunnel(ip_hdr, len, caplen, hdr, pkt); - if (tunnel_info) - { - ip4 = tunnel_info->child->IP4_Hdr(); - ip_hdr = tunnel_info->child; - len -= tunnel_info->hdr_len; - caplen -= tunnel_info->hdr_len; - } - } - int proto = ip_hdr->NextProto(); if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) ) { - delete tunnel_info; Remove(f); return; } @@ -540,9 +522,51 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, break; } + case IPPROTO_IP: + case IPPROTO_IPV4: + case IPPROTO_IPV6: + { + if ( ! BifConst::Tunnel::decapsulate_ip ) + { + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "ip_tunnel"); + Remove(f); + return; + } + + if ( encapsulation.Depth() >= BifConst::Tunnel::max_depth ) + { + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "tunnel_depth"); + Remove(f); + return; + } + + IP_Hdr* inner_ip; + if ( proto == IPPROTO_IPV6 ) + inner_ip = new IP_Hdr((const struct ip6_hdr*) data, false, caplen); + else + inner_ip = new IP_Hdr((const struct ip*) data, false); + + struct pcap_pkthdr fake_hdr; + fake_hdr.caplen = fake_hdr.len = caplen; + fake_hdr.ts = hdr->ts; + + EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), + ip_hdr->IP4_Hdr() ? + ( proto == IPPROTO_IPV6 ? + BifEnum::Tunnel::IP6_IN_IP4 : BifEnum::Tunnel::IP4_IN_IP4 ) : + ( proto == IPPROTO_IPV6 ? + BifEnum::Tunnel::IP6_IN_IP6 : BifEnum::Tunnel::IP4_IN_IP6 )); + encapsulation.Add(ec); + + DoNextPacket(t, &fake_hdr, inner_ip, data, 0, encapsulation); + + delete inner_ip; + Remove(f); + return; + } + default: Weird(fmt("unknown_protocol_%d", proto), hdr, pkt); - delete tunnel_info; Remove(f); return; } @@ -558,7 +582,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, conn = (Connection*) d->Lookup(h); if ( ! conn ) { - conn = NewConn(h, t, &id, data, proto, tunnel_info); + conn = NewConn(h, t, &id, data, proto, encapsulation); if ( conn ) d->Insert(h, conn); } @@ -569,7 +593,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( consistent < 0 ) { delete h; - delete tunnel_info; Remove(f); return; } @@ -580,18 +603,20 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, conn->Event(connection_reused, 0); Remove(conn); - conn = NewConn(h, t, &id, data, proto, tunnel_info); + conn = NewConn(h, t, &id, data, proto, encapsulation); if ( conn ) d->Insert(h, conn); } else + { delete h; + conn->CheckEncapsulation(encapsulation); + } } if ( ! conn ) { delete h; - delete tunnel_info; Remove(f); return; } @@ -618,8 +643,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, record_packet, record_content, hdr, pkt, hdr_size); - delete tunnel_info; - if ( f ) { // Above we already recorded the fragment in its entirety. @@ -651,11 +674,19 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, case IPPROTO_UDP: min_hdr_len = sizeof(struct udphdr); break; + case IPPROTO_IP: + case IPPROTO_IPV4: + min_hdr_len = sizeof(struct ip); + break; + case IPPROTO_IPV6: + min_hdr_len = sizeof(struct ip6_hdr); + break; case IPPROTO_ICMP: case IPPROTO_ICMPV6: default: // Use for all other packets. min_hdr_len = ICMP_MINLEN; + break; } if ( len < min_hdr_len ) @@ -962,14 +993,14 @@ void NetSessions::GetStats(SessionStats& s) const } Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, - const u_char* data, int proto, TunnelInfo* tunnel_info) + const u_char* data, int proto, + const Encapsulation& encapsulation) { // FIXME: This should be cleaned up a bit, it's too protocol-specific. // But I'm not yet sure what the right abstraction for these things is. int src_h = ntohs(id->src_port); int dst_h = ntohs(id->dst_port); int flags = 0; - TunnelParent *tunnel_parent = 0; // Hmm... This is not great. TransportProto tproto = TRANSPORT_UNKNOWN; @@ -1019,10 +1050,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, id = &flip_id; } - if ( tunnel_info ) - tunnel_parent = new TunnelParent(&(tunnel_info->parent)); - - Connection* conn = new Connection(this, k, t, id, tunnel_parent); + Connection* conn = new Connection(this, k, t, id, encapsulation); conn->SetTransport(tproto); dpm->BuildInitialAnalyzerTree(tproto, conn, data); diff --git a/src/Sessions.h b/src/Sessions.h index edbb7a8ffd..e1afbeec5a 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -14,6 +14,7 @@ struct pcap_pkthdr; +class Encapsulation; class Connection; class ConnID; class OSFingerprint; @@ -26,9 +27,6 @@ class Discarder; class SteppingStoneManager; class PacketFilter; -class TunnelHandler; -class TunnelInfo; - class PacketSortElement; struct SessionStats { @@ -145,7 +143,7 @@ protected: friend class TimerMgrExpireTimer; Connection* NewConn(HashKey* k, double t, const ConnID* id, - const u_char* data, int proto, TunnelInfo *tunnel_info); + const u_char* data, int proto, const Encapsulation& encapsulation); // Check whether the tag of the current packet is consistent with // the given connection. Returns: @@ -178,7 +176,7 @@ protected: void DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size); + int hdr_size, Encapsulation& encapsulation); void NextPacketSecondary(double t, const struct pcap_pkthdr* hdr, const u_char* const pkt, int hdr_size, @@ -216,8 +214,6 @@ protected: int num_packets_processed; PacketProfiler* pkt_profiler; - TunnelHandler *tunnel_handler; - // We may use independent timer managers for different sets of related // activity. The managers are identified by an unique tag. typedef std::map TimerMgrMap; diff --git a/src/TunnelHandler.cc b/src/TunnelHandler.cc index 9debf79d9c..4923b36f3d 100644 --- a/src/TunnelHandler.cc +++ b/src/TunnelHandler.cc @@ -1,178 +1,52 @@ -// $Id: Sessions.cc 7075 2010-09-13 02:39:38Z vern $ -// // See the file "COPYING" in the main distribution directory for copyright. - -#include "config.h" - -#include - -#include -#include - #include "TunnelHandler.h" -#include "Conn.h" -#include "Sessions.h" - -TunnelHandler::TunnelHandler(NetSessions *arg_s) +RecordVal* EncapsulatingConn::GetRecordVal() const { - s = arg_s; - PortVal *pv = 0; - TableVal *udp_tunnel_ports = BifConst::Tunnel::udp_tunnel_ports->AsTableVal(); - // Find UDP ports we want to analyze. Store them in an array for faster - // lookup. - for ( int i = 0; i< 65536; i++ ) - { - if ( pv ) - Unref(pv); - pv = new PortVal(i, TRANSPORT_UDP); - if ( udp_tunnel_ports->Lookup(pv, false) ) - udp_ports[i] = 1; - else - udp_ports[i] = 0; - } - Unref(pv); - } - -TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int caplen, - const struct pcap_pkthdr* hdr, const u_char* const pkt) - { - TunnelInfo *tunnel_info = 0; - - switch ( ip_hdr->NextProto() ) { - case IPPROTO_IPV6: /* 6in4 and 6to4 */ - if ( BifConst::Tunnel::decapsulate_ip ) - { - if ( len < (int)sizeof(struct ip6_hdr) || - caplen < (int)sizeof(struct ip6_hdr) ) - { - s->Weird("truncated_header", hdr, pkt); - return 0; - } - // TODO: check if IP6 header makes sense - tunnel_info = new TunnelInfo(); - tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload(), false, caplen); - tunnel_info->parent.tunneltype = BifEnum::Tunnel::IP6_IN_IP; - tunnel_info->hdr_len = tunnel_info->child->HdrLen(); - tunnel_info->SetParentIPs(ip_hdr); - return tunnel_info; - } - break; - // TODO: IP in IP. Find test traces first. IP proto 0 and/or 4 - case IPPROTO_UDP: - if ( BifConst::Tunnel::decapsulate_udp ) - { - if ( len < (int)sizeof(struct udphdr) || - caplen < (int)sizeof(struct udphdr) ) - // No weird here. Main packet processing will raise it. - return 0; - return HandleUDP(ip_hdr, len, caplen); - } - + RecordVal *rv = + new RecordVal(BifType::Record::Tunnel::EncapsulatingConn); + TransportProto tproto; + switch ( type ) { + case BifEnum::Tunnel::IP6_IN_IP4: + case BifEnum::Tunnel::IP4_IN_IP4: + case BifEnum::Tunnel::IP6_IN_IP6: + case BifEnum::Tunnel::IP4_IN_IP6: + tproto = TRANSPORT_UNKNOWN; break; default: + tproto = TRANSPORT_UDP; break; - } /* end switch */ - return 0; + } // end switch + + RecordVal* id_val = new RecordVal(conn_id); + id_val->Assign(0, new AddrVal(src_addr)); + id_val->Assign(1, new PortVal(ntohs(src_port), tproto)); + id_val->Assign(2, new AddrVal(dst_addr)); + id_val->Assign(3, new PortVal(ntohs(dst_port), tproto)); + rv->Assign(0, id_val); + rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type)); + return rv; } -TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen) +bool operator==(const Encapsulation& e1, const Encapsulation& e2) { - // We already know we that we have a valid UDP header - const u_char *data = ip_hdr->Payload(); - const struct udphdr* uh = (const struct udphdr*)data; - IP_Hdr *cand_ip_hdr = 0; - BifEnum::Tunnel::Tunneltype tunneltype = BifEnum::Tunnel::NONE; - - int hdr_len = sizeof(struct udphdr); - data += hdr_len; - - int datalen = (int)ntohs(uh->uh_ulen); - datalen = min(datalen, min(len, caplen)); - datalen -= hdr_len; - - if ( BifConst::Tunnel::udp_tunnel_allports || - udp_ports[ntohs(uh->uh_sport)] || - udp_ports[ntohs(uh->uh_dport)] ) - { - cand_ip_hdr = LookForIPHdr(data, datalen); - if ( cand_ip_hdr ) + if ( e1.conns ) + if ( e2.conns ) { - // Found and IP hdr directly in the UDP payload - tunneltype = (cand_ip_hdr->IP4_Hdr()) ? - BifEnum::Tunnel::IP4_IN_UDP : BifEnum::Tunnel::IP6_IN_UDP; + if ( e1.conns->size() != e2.conns->size() ) + return false; + else + for ( size_t i = 0; i < e1.conns->size(); ++i ) + if ( (*e1.conns)[i] != (*e2.conns)[i] ) + return false; + return true; } - else if ( datalen >= 8 ) - { - // Look for AYIAY tunnels - u_char id_byte = data[0]; - u_char sig_byte = data[1]; - u_char next_hdr = data[3]; - - // identity length field is high bits of id_byte. - // length in octets is 2 to the power of length field - int id_len = (1 << (id_byte>>4)); - - // signature length field is high bits of sig_byte - // length in octets 4 * length field - int sig_len = 4*(sig_byte>>4); - - datalen -= 8 + id_len + sig_len; - data += 8 + id_len + sig_len; - if ( datalen <= 0 ) - return 0; - cand_ip_hdr = LookForIPHdr(data, datalen); - if ( cand_ip_hdr ) - { - hdr_len += 8 + id_len + sig_len; - tunneltype = (cand_ip_hdr->IP4_Hdr()) ? - BifEnum::Tunnel::IP4_IN_AYIAY : BifEnum::Tunnel::IP6_IN_AYIAY; - } - } - if ( cand_ip_hdr ) - { - TunnelInfo *tunnel_info = new TunnelInfo(); - tunnel_info->child = cand_ip_hdr; - tunnel_info->parent.tunneltype = tunneltype; - tunnel_info->SetParentIPs(ip_hdr); - tunnel_info->SetParentPorts(uh); - tunnel_info->hdr_len = hdr_len + cand_ip_hdr->HdrLen(); - return tunnel_info; - }; - } - return 0; - } - -IP_Hdr* TunnelHandler::LookForIPHdr(const u_char *data, int datalen) - { - IP_Hdr *cand_ip_hdr = 0; - if (datalen < (int)sizeof(struct ip)) - return 0; - - const struct ip *ip4 = (const struct ip*)(data); - if ( ip4->ip_v == 4 ) - cand_ip_hdr = new IP_Hdr((const struct ip*)ip4, false); - else if ( ip4->ip_v == 6 && (datalen > (int)sizeof(struct ip6_hdr)) ) - cand_ip_hdr = new IP_Hdr((const struct ip6_hdr*)data, false, datalen); - - if ( cand_ip_hdr ) - { - switch ( cand_ip_hdr->NextProto() ) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_ICMP: - if ( (int)cand_ip_hdr->TotalLen() != datalen ) - { - delete cand_ip_hdr; - cand_ip_hdr = 0; - } - break; - default: - delete cand_ip_hdr; - cand_ip_hdr = 0; - break; - } // end switch - } - return cand_ip_hdr; + else + return false; + else + if ( e2.conns ) + return false; + else + return true; } diff --git a/src/TunnelHandler.h b/src/TunnelHandler.h index 9f3f3614e7..21e491cdc9 100644 --- a/src/TunnelHandler.h +++ b/src/TunnelHandler.h @@ -3,105 +3,109 @@ #ifndef tunnelhandler_h #define tunnelhandler_h -#include -#include "net_util.h" -#include "IP.h" +#include "config.h" +#include "NetVar.h" #include "IPAddr.h" -#include "Conn.h" -#include "Sessions.h" #include "Val.h" +#include -class TunnelParent { +class EncapsulatingConn { public: - TunnelParent() + EncapsulatingConn() + : src_port(0), dst_port(0), type(BifEnum::Tunnel::NONE) {} + + EncapsulatingConn(const IPAddr& s, const IPAddr& d, + BifEnum::Tunnel::Type t) + : src_addr(s), dst_addr(d), src_port(0), dst_port(0), type(t) {} + + EncapsulatingConn(const IPAddr& s, const IPAddr& d, uint16 sp, uint16 dp, + BifEnum::Tunnel::Type t) + : src_addr(s), dst_addr(d), src_port(sp), dst_port(dp), type(t) {} + + EncapsulatingConn(const EncapsulatingConn& other) + : src_addr(other.src_addr), dst_addr(other.dst_addr), + src_port(other.src_port), dst_port(other.dst_port), + type(other.type) {} + + ~EncapsulatingConn() {} + + RecordVal* GetRecordVal() const; + + friend bool operator==(const EncapsulatingConn& ec1, + const EncapsulatingConn& ec2) { - tunneltype = BifEnum::Tunnel::NONE; - src_port = dst_port = 0; + return ec1.type == ec2.type && ec1.src_addr == ec2.src_addr && + ec1.src_port == ec2.src_port && ec1.dst_port == ec2.dst_port; } - TunnelParent(TunnelParent *other) + friend bool operator!=(const EncapsulatingConn& ec1, + const EncapsulatingConn& ec2) { - tunneltype = other->tunneltype; - src_addr = other->src_addr; - dst_addr = other->dst_addr; - src_port = other->src_port; - dst_port = other->dst_port; - } - - RecordVal* GetRecordVal() const - { - RecordVal *rv = new RecordVal(BifType::Record::Tunnel::Parent); - TransportProto tproto; - switch ( tunneltype ) { - case BifEnum::Tunnel::IP6_IN_IP: - case BifEnum::Tunnel::IP4_IN_IP: - tproto = TRANSPORT_UNKNOWN; - break; - default: - tproto = TRANSPORT_UDP; - } // end switch - - RecordVal* id_val = new RecordVal(conn_id); - id_val->Assign(0, new AddrVal(src_addr)); - id_val->Assign(1, new PortVal(ntohs(src_port), tproto)); - id_val->Assign(2, new AddrVal(dst_addr)); - id_val->Assign(3, new PortVal(ntohs(dst_port), tproto)); - rv->Assign(0, id_val); - rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::Tunneltype)); - return rv; + return ! ( ec1 == ec2 ); } IPAddr src_addr; IPAddr dst_addr; uint16 src_port; uint16 dst_port; - BifEnum::Tunnel::Tunneltype tunneltype; + BifEnum::Tunnel::Type type; }; -class TunnelInfo { +class Encapsulation { public: - TunnelInfo() + Encapsulation() : conns(0) {} + + Encapsulation(const Encapsulation& other) { - child = 0; - hdr_len = 0; - } - ~TunnelInfo() - { - if (child) delete child; + if ( other.conns ) + conns = new vector(*(other.conns)); + else + conns = 0; } - void SetParentIPs(const IP_Hdr *ip_hdr) + Encapsulation& operator=(const Encapsulation& other) { - parent.src_addr = ip_hdr->SrcAddr(); - parent.dst_addr = ip_hdr->DstAddr(); - } - void SetParentPorts(const struct udphdr *uh) - { - parent.src_port = uh->uh_sport; - parent.dst_port = uh->uh_dport; + if ( this == &other ) return *this; + delete conns; + if ( other.conns ) + conns = new vector(*(other.conns)); + else + conns = 0; + return *this; } - IP_Hdr *child; - TunnelParent parent; - int hdr_len; + ~Encapsulation() { delete conns; } + + void Add(const EncapsulatingConn& c) + { + if ( ! conns ) + conns = new vector(); + conns->push_back(c); + } + + size_t Depth() const + { + return conns ? conns->size() : 0; + } + + VectorVal* GetVectorVal() const + { + VectorVal* vv = new VectorVal(new VectorType( + BifType::Record::Tunnel::EncapsulatingConn->Ref())); + if ( conns ) + for ( size_t i = 0; i < conns->size(); ++i ) + vv->Assign(i, (*conns)[i].GetRecordVal(), 0); + return vv; + } + + friend bool operator==(const Encapsulation& e1, const Encapsulation& e2); + + friend bool operator!=(const Encapsulation& e1, const Encapsulation& e2) + { + return ! ( e1 == e2 ); + } + + vector* conns; }; -class TunnelHandler { -public: - TunnelHandler(NetSessions *arg_s); - ~TunnelHandler(); - - // Main entry point. Returns a nil if not tunneled. - TunnelInfo* DecapsulateTunnel(const IP_Hdr* ip_hdr, int len, int caplen, - // need those for passing them back to NetSessions::Weird() - const struct pcap_pkthdr* hdr, const u_char* const pkt); - -protected: - NetSessions *s; - short udp_ports[65536]; // which UDP ports to decapsulate - IP_Hdr* LookForIPHdr(const u_char *data, int datalen); - TunnelInfo* HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen); -}; - - #endif diff --git a/src/const.bif b/src/const.bif index 0ebd210a95..b622d52ff3 100644 --- a/src/const.bif +++ b/src/const.bif @@ -4,7 +4,6 @@ const ignore_keep_alive_rexmit: bool; const skip_http_data: bool; -const parse_udp_tunnels: bool; const use_conn_size_analyzer: bool; const report_gaps_for_partial: bool; @@ -16,3 +15,4 @@ const Tunnel::decapsulate_ip: bool; const Tunnel::decapsulate_udp: bool; const Tunnel::udp_tunnel_ports: any; const Tunnel::udp_tunnel_allports: bool; +const Tunnel::max_depth: count; diff --git a/src/event.bif b/src/event.bif index 1ce8907f0b..b92354e632 100644 --- a/src/event.bif +++ b/src/event.bif @@ -141,6 +141,17 @@ event dns_mapping_altered%(dm: dns_mapping, old_addrs: addr_set, new_addrs: addr ## event. event new_connection%(c: connection%); +## Generated for a connection whose tunneling has changed. This could +## be from a previously seen connection now being encapsulated in a tunnel, +## or from the outer encapsulation changing. Note that the connection's +## *tunnel* field is NOT automatically assigned to the new encapsulation value +## internally after this event is raised. +## +## c: The connection whose tunnel/encapsulation changed. +## +## e: The new encapsulation. +event tunnel_changed%(c: connection, e: encapsulating_conns%); + ## Generated when reassembly starts for a TCP connection. The event is raised ## at the moment when Bro's TCP analyzer enables stream reassembly for a ## connection. diff --git a/src/types.bif b/src/types.bif index 0017c4b6ff..60f8631a23 100644 --- a/src/types.bif +++ b/src/types.bif @@ -170,16 +170,18 @@ enum ID %{ module Tunnel; -enum Tunneltype %{ +enum Type %{ NONE, - IP6_IN_IP, - IP4_IN_IP, + IP6_IN_IP4, + IP4_IN_IP4, + IP6_IN_IP6, + IP4_IN_IP6, IP6_IN_UDP, IP4_IN_UDP, IP6_IN_AYIAY, IP4_IN_AYIAY, %} -type Parent: record; +type EncapsulatingConn: record; module GLOBAL; diff --git a/testing/btest/Baseline/core.tunnels.ip-in-ip/output b/testing/btest/Baseline/core.tunnels.ip-in-ip/output new file mode 100644 index 0000000000..7ed712aec8 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.ip-in-ip/output @@ -0,0 +1,22 @@ +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6], [cid=[orig_h=babe::beef, orig_p=0/unknown, resp_h=dead::babe, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=1.2.3.4, orig_p=0/unknown, resp_h=5.6.7.8, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP4]] +new_connection: tunnel + conn_id: [orig_h=70.55.213.211, orig_p=31337/tcp, resp_h=192.88.99.1, resp_p=80/tcp] + encap: [[cid=[orig_h=2002:4637:d5d3::4637:d5d3, orig_p=0/unknown, resp_h=2001:4860:0:2001::68, resp_p=0/unknown], tunnel_type=Tunnel::IP4_IN_IP6]] +new_connection: tunnel + conn_id: [orig_h=10.0.0.1, orig_p=30000/udp, resp_h=10.0.0.2, resp_p=13000/udp] + encap: [[cid=[orig_h=1.2.3.4, orig_p=0/unknown, resp_h=5.6.7.8, resp_p=0/unknown], tunnel_type=Tunnel::IP4_IN_IP4]] +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] +tunnel_changed: + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + old: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] + new: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] diff --git a/testing/btest/Traces/tunnels/4in4.pcap b/testing/btest/Traces/tunnels/4in4.pcap new file mode 100644 index 0000000000000000000000000000000000000000..b0d89eeddac2cc9c5ef25313c7d7d1f7f5f0c383 GIT binary patch literal 106 zcmca|c+)~A1{MYw_+QV!zzF0-O`GapvWA<%3CIRv27%ihm)@V)b7I=11sn{n3=Ae9 qWezM^n;4mxSysJNrB<& H5e5bT)BYSs literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/6in4.pcap b/testing/btest/Traces/tunnels/6in4.pcap new file mode 100644 index 0000000000000000000000000000000000000000..2d0cd5c8c79476a337a9ea4e00b0c09989b370a7 GIT binary patch literal 126 zcmca|c+)~A1{MYw_+QV!zzF1sOq=Teq@9f+49Esy27%ihm)@V)b7I=11sn{n3=AG1 yWe%EIm5fZxEUawo90?#*Jc17Q)`A!?uzET6D6AV1fmm+`wWOGd;A)Eib XMK)pIdsP0Ze+eLIqHS)x5D5eTP+LeQ literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/6in6.pcap b/testing/btest/Traces/tunnels/6in6.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ff8aa607bb022bd189b553aad153cb3f32fe5b57 GIT binary patch literal 146 zcmca|c+)~A1{MYw_+QV!zzF2rubAksRLa7T1!RNpe=vZkYP*{NVwh+;C@`}80BUAu wdeHd)U(o;msQg*kV0Ao#4)@lAG{C^V_ox2B*dTh>zET6D6AV1fmm+`w0Hb6myZ`_I literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tunnels/6in6in6.pcap b/testing/btest/Traces/tunnels/6in6in6.pcap new file mode 100644 index 0000000000000000000000000000000000000000..192524aa788e7e099648f6dc2fc7b452c97525ed GIT binary patch literal 186 zcmca|c+)~A1{MYw_+QV!zzF2b?3wD{{g0Dj5|9nT|G@yFs_kw9h!Lad@b4`|1VZk6 zkIFywF99TBqUo?}A4CO&-1q+8T4esNeF-2gkDvpp_`dh2{-LTXH848Cz|(vw0tf)T C4=c6+ literal 0 HcmV?d00001 diff --git a/testing/btest/core/tunnels/ip-in-ip.test b/testing/btest/core/tunnels/ip-in-ip.test new file mode 100644 index 0000000000..f526575d48 --- /dev/null +++ b/testing/btest/core/tunnels/ip-in-ip.test @@ -0,0 +1,30 @@ +# @TEST-EXEC: bro -b -r $TRACES/tunnels/6in6.pcap %INPUT >>output 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/tunnels/6in6in6.pcap %INPUT >>output 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/tunnels/6in4.pcap %INPUT >>output 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/tunnels/4in6.pcap %INPUT >>output 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/tunnels/4in4.pcap %INPUT >>output 2>&1 +# @TEST-EXEC: bro -b -r $TRACES/tunnels/6in6-tunnel-change.pcap %INPUT >>output 2>&1 +# @TEST-EXEC: btest-diff output + +event new_connection(c: connection) + { + if ( c?$tunnel ) + { + print "new_connection: tunnel"; + print fmt(" conn_id: %s", c$id); + print fmt(" encap: %s", c$tunnel); + } + else + { + print "new_connection: no tunnel"; + } + } + +event tunnel_changed(c: connection, e: encapsulating_conns) + { + print "tunnel_changed:"; + print fmt(" conn_id: %s", c$id); + if ( c?$tunnel ) + print fmt(" old: %s", c$tunnel); + print fmt(" new: %s", e); + } From 5ce00bda8a5ee2233e25b3d2a445527e4de31b2e Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 23 Apr 2012 13:24:02 -0500 Subject: [PATCH 18/51] Rename TunnelHandler.{cc,h} to Tunnels.{cc,h}. --- src/CMakeLists.txt | 2 +- src/Conn.cc | 2 +- src/Conn.h | 2 +- src/Sessions.cc | 2 +- src/{TunnelHandler.cc => Tunnels.cc} | 2 +- src/{TunnelHandler.h => Tunnels.h} | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) rename src/{TunnelHandler.cc => Tunnels.cc} (97%) rename src/{TunnelHandler.h => Tunnels.h} (98%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a755fde64e..503bd0298e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -394,7 +394,7 @@ set(bro_SRCS Timer.cc Traverse.cc Trigger.cc - TunnelHandler.cc + Tunnels.cc Type.cc UDP.cc Val.cc diff --git a/src/Conn.cc b/src/Conn.cc index 80c026e781..55cfb3b3cb 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -13,7 +13,7 @@ #include "Timer.h" #include "PIA.h" #include "binpac.h" -#include "TunnelHandler.h" +#include "Tunnels.h" void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer, int arg_do_expire) diff --git a/src/Conn.h b/src/Conn.h index 9cdb746b7c..67300601ce 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -13,7 +13,7 @@ #include "RuleMatcher.h" #include "AnalyzerTags.h" #include "IPAddr.h" -#include "TunnelHandler.h" +#include "Tunnels.h" class Connection; class ConnectionTimer; diff --git a/src/Sessions.cc b/src/Sessions.cc index 769bd68f52..326306c2fd 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -30,7 +30,7 @@ #include "DPM.h" #include "PacketSort.h" -#include "TunnelHandler.h" +#include "Tunnels.h" // These represent NetBIOS services on ephemeral ports. They're numbered // so that we can use a single int to hold either an actual TCP/UDP server diff --git a/src/TunnelHandler.cc b/src/Tunnels.cc similarity index 97% rename from src/TunnelHandler.cc rename to src/Tunnels.cc index 4923b36f3d..950e94628e 100644 --- a/src/TunnelHandler.cc +++ b/src/Tunnels.cc @@ -1,6 +1,6 @@ // See the file "COPYING" in the main distribution directory for copyright. -#include "TunnelHandler.h" +#include "Tunnels.h" RecordVal* EncapsulatingConn::GetRecordVal() const { diff --git a/src/TunnelHandler.h b/src/Tunnels.h similarity index 98% rename from src/TunnelHandler.h rename to src/Tunnels.h index 21e491cdc9..d4dfee8f97 100644 --- a/src/TunnelHandler.h +++ b/src/Tunnels.h @@ -1,7 +1,7 @@ // See the file "COPYING" in the main distribution directory for copyright. -#ifndef tunnelhandler_h -#define tunnelhandler_h +#ifndef TUNNELS_H +#define TUNNELS_H #include "config.h" #include "NetVar.h" From 2a79fe95ec1b7514382e0de8b94fb0f5c4ea2af1 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 24 Apr 2012 01:05:35 -0400 Subject: [PATCH 19/51] Another tunneling checkpoint. - AYIYA works. - AYIYA analyzed connections are still labelled wrong in conn.log (logged as syslog) - Some clean up for left over code. - Small refactoring to pass packets back from analyzers to core. - $uid is now optional in conn logs since ip-in-ip tunnel parent's won't have an actual connection. --- scripts/base/frameworks/tunnels/main.bro | 2 +- scripts/base/init-bare.bro | 16 +----- scripts/base/protocols/conn/main.bro | 12 +++++ src/AYIYA.cc | 63 ------------------------ src/AYIYA.h | 27 +--------- src/Analyzer.cc | 3 -- src/AnalyzerTags.h | 1 - src/Conn.h | 4 +- src/Sessions.h | 8 +-- src/ayiya-analyzer.pac | 33 +++++++++++-- src/const.bif | 3 -- src/types.bif | 3 +- 12 files changed, 53 insertions(+), 122 deletions(-) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 987939eb6e..952f382e56 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -10,7 +10,7 @@ export { type Info: record { ts: time &log; - uid: string &log; + uid: string &log &optional; id: conn_id &log; action: Action &log; tunnel_type: string &log; diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 88f0910d1c..45ec94baa8 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2631,21 +2631,7 @@ module Tunnel; export { ## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) const decapsulate_ip = T &redef; - - ## Whether to decapsulate UDP tunnels (e.g., Teredo, IPv4 in UDP) - const decapsulate_udp = F &redef; - - ## If decapsulating UDP: the set of ports for which to do so. - ## Can be overridden by :bro:id:`Tunnel::udp_tunnel_allports` - const udp_tunnel_ports: set[port] = { - 3544/udp, # Teredo - 5072/udp, # AYIAY - } &redef; - - ## If udp_tunnel_allports is T :bro:id:`udp_tunnel_ports` is ignored and we - ## check every UDP packet for tunnels. - const udp_tunnel_allports = F &redef; - + ## The maximum depth of a tunnel to decapsulate until giving up. const max_depth: count = 2 &redef; } # end export diff --git a/scripts/base/protocols/conn/main.bro b/scripts/base/protocols/conn/main.bro index 34ec12fa56..e4dbb28790 100644 --- a/scripts/base/protocols/conn/main.bro +++ b/scripts/base/protocols/conn/main.bro @@ -101,6 +101,9 @@ export { resp_pkts: count &log &optional; ## Number IP level bytes the responder sent. See ``orig_pkts``. resp_ip_bytes: count &log &optional; + ## If this connection was over a tunnel, indicate the + ## `uid` value for the parent connection or connections. + parents: vector of string &log &optional; }; ## Event that can be handled to access the :bro:type:`Conn::Info` @@ -190,6 +193,15 @@ function set_conn(c: connection, eoc: bool) c$conn$ts=c$start_time; c$conn$uid=c$uid; c$conn$id=c$id; + if ( ! c$conn?$parents && c?$tunnel ) + { + c$conn$parents = vector(); + for ( i in c$tunnel ) + { + # TODO: maybe we should be storing uid's in the $tunnel field? + #c$conn$parents[|c$conn$parents|] = lookup_connection(c$tunnel[i]$cid)$uid; + } + } c$conn$proto=get_port_transport_proto(c$id$resp_p); if( |Site::local_nets| > 0 ) c$conn$local_orig=Site::is_local_addr(c$id$orig_h); diff --git a/src/AYIYA.cc b/src/AYIYA.cc index d69db642b3..c70af87fa8 100644 --- a/src/AYIYA.cc +++ b/src/AYIYA.cc @@ -1,13 +1,10 @@ #include "AYIYA.h" -#include "TCP_Reassembler.h" AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn) { interp = new binpac::AYIYA::AYIYA_Conn(this); did_session_done = 0; - //ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer, - // network_time + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); } AYIYA_Analyzer::~AYIYA_Analyzer() @@ -28,63 +25,3 @@ void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int s Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); interp->NewData(orig, data, data + len); } - -//void AYIYA_Analyzer::ExpireTimer(double t) -// { -// // The - 1.0 in the following is to allow 1 second for the -// // common case of a single request followed by a single reply, -// // so we don't needlessly set the timer twice in that case. -// if ( t - Conn()->LastTime() >= Syslog_session_timeout - 1.0 || terminating ) -// { -// Event(connection_timeout); -// sessions->Remove(Conn()); -// } -// else -// ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer, -// t + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE); -// } - -//Syslog_TCP_Analyzer_binpac::Syslog_TCP_Analyzer_binpac(Connection* conn) -//: TCP_ApplicationAnalyzer(AnalyzerTag::Syslog_TCP_BINPAC, conn) -// { -// interp = new binpac::Syslog_on_TCP::Syslog_TCP_Conn(this); -// } - -//Syslog_TCP_Analyzer_binpac::~Syslog_TCP_Analyzer_binpac() -// { -// delete interp; -// } - -//void Syslog_TCP_Analyzer_binpac::Done() -// { -// TCP_ApplicationAnalyzer::Done(); -// -// interp->FlowEOF(true); -// interp->FlowEOF(false); -// } - -//void Syslog_TCP_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp) -// { -// TCP_ApplicationAnalyzer::EndpointEOF(endp); -// interp->FlowEOF(endp->IsOrig()); -// } - -//void Syslog_TCP_Analyzer_binpac::DeliverStream(int len, const u_char* data, -// bool orig) -// { -// TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); -// -// assert(TCP()); -// -// if ( TCP()->IsPartial() || TCP()->HadGap(orig) ) -// // punt-on-partial or stop-on-gap. -// return; -// -// interp->NewData(orig, data, data + len); -// } - -//void Syslog_TCP_Analyzer_binpac::Undelivered(int seq, int len, bool orig) -// { -// TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); -// interp->NewGap(orig, len); -// } diff --git a/src/AYIYA.h b/src/AYIYA.h index 294eeca1ea..f7c67ced5b 100644 --- a/src/AYIYA.h +++ b/src/AYIYA.h @@ -1,9 +1,6 @@ #ifndef AYIYA_h #define AYIYA_h -#include "UDP.h" -#include "TCP.h" - #include "ayiya_pac.h" class AYIYA_Analyzer : public Analyzer { @@ -19,7 +16,7 @@ public: { return new AYIYA_Analyzer(conn); } static bool Available() - { return true; } + { return BifConst::Tunnel::decapsulate_ip; } protected: friend class AnalyzerTimer; @@ -30,26 +27,4 @@ protected: binpac::AYIYA::AYIYA_Conn* interp; }; -// #include "Syslog_tcp_pac.h" -// -//class Syslog_TCP_Analyzer_binpac : public TCP_ApplicationAnalyzer { -//public: -// Syslog_TCP_Analyzer_binpac(Connection* conn); -// virtual ~Syslog_TCP_Analyzer_binpac(); -// -// virtual void Done(); -// virtual void DeliverStream(int len, const u_char* data, bool orig); -// virtual void Undelivered(int seq, int len, bool orig); -// virtual void EndpointEOF(TCP_Reassembler* endp); -// -// static Analyzer* InstantiateAnalyzer(Connection* conn) -// { return new Syslog_TCP_Analyzer_binpac(conn); } -// -// static bool Available() -// { return (Syslog_request || Syslog_full_request) && FLAGS_use_binpac; } -// -//protected: -// binpac::Syslog_on_TCP::Syslog_TCP_Conn* interp; -//}; -// #endif diff --git a/src/Analyzer.cc b/src/Analyzer.cc index f731b36a70..f9570d707f 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -129,9 +129,6 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { Syslog_Analyzer_binpac::InstantiateAnalyzer, Syslog_Analyzer_binpac::Available, 0, false }, - //{ AnalyzerTag::6to4, "6to4", - // 6to4_Analyzer::InstantiateAnalyzer, - // 6to4_Anylzer::Available, 0, false }, { AnalyzerTag::AYIYA, "AYIYA", AYIYA_Analyzer::InstantiateAnalyzer, AYIYA_Analyzer::Available, 0, false }, diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index 1b65d5219e..05de68f2b3 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -34,7 +34,6 @@ namespace AnalyzerTag { HTTP_BINPAC, SSL, SYSLOG_BINPAC, // Decapsulation Analyzers - //6to4, AYIYA, SOCKS, //Teredo, diff --git a/src/Conn.h b/src/Conn.h index 67300601ce..7f998c9d9a 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -245,7 +245,9 @@ public: void SetTransport(TransportProto arg_proto) { proto = arg_proto; } void SetUID(uint64 arg_uid) { uid = arg_uid; } - + + Encapsulation* GetEncapsulation() { return &encapsulation; } + protected: Connection() { persistent = 0; } diff --git a/src/Sessions.h b/src/Sessions.h index e1afbeec5a..fb76d29831 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -131,6 +131,10 @@ public: return tcp_conns.Length() + udp_conns.Length() + icmp_conns.Length(); } + + void DoNextPacket(double t, const struct pcap_pkthdr* hdr, + const IP_Hdr* ip_hdr, const u_char* const pkt, + int hdr_size, Encapsulation& encapsulation); unsigned int ConnectionMemoryUsage(); unsigned int ConnectionMemoryUsageConnVals(); @@ -174,10 +178,6 @@ protected: const u_char* const pkt, int hdr_size, PacketSortElement* pkt_elem); - void DoNextPacket(double t, const struct pcap_pkthdr* hdr, - const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size, Encapsulation& encapsulation); - void NextPacketSecondary(double t, const struct pcap_pkthdr* hdr, const u_char* const pkt, int hdr_size, const PktSrc* src_ps); diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 888cc575a5..3834ccc3b6 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -11,10 +11,37 @@ flow AYIYA_Flow function process_ayiya(pdu: PDU): bool %{ - connection()->bro_analyzer()->ProtocolConfirmation(); + Connection *c = connection()->bro_analyzer()->Conn(); - // Not sure what to do here. - printf("packet: %s\n", ${pdu.packet}.data()); + if ( c->GetEncapsulation()->Depth() >= BifConst::Tunnel::max_depth ) + { + reporter->Weird(c->OrigAddr(), c->RespAddr(), "tunnel_depth"); + // TODO: this should stop this analyzer instance + return false; + } + + IP_Hdr* inner_ip; + if ( ${pdu.next_header} == IPPROTO_IPV6 ) + inner_ip = new IP_Hdr((const struct ip6_hdr*) ${pdu.packet}.data(), false, ${pdu.packet}.length()); + else + inner_ip = new IP_Hdr((const struct ip*) ${pdu.packet}.data(), false); + + if ( inner_ip != 0) + connection()->bro_analyzer()->ProtocolConfirmation(); + else + connection()->bro_analyzer()->ProtocolViolation("ayiya_tunnel_non_ip"); + + struct pcap_pkthdr fake_hdr; + fake_hdr.caplen = fake_hdr.len = ${pdu.packet}.length(); + // Not sure what to do with this timestamp. + //fake_hdr.ts = network_time(); + + EncapsulatingConn ec(c->OrigAddr(), c->RespAddr(), BifEnum::Tunnel::AYIYA); + c->GetEncapsulation()->Add(ec); + + sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, *c->GetEncapsulation()); + + delete inner_ip; return true; %} diff --git a/src/const.bif b/src/const.bif index b622d52ff3..db5fbbd2cb 100644 --- a/src/const.bif +++ b/src/const.bif @@ -12,7 +12,4 @@ const NFS3::return_data_max: count; const NFS3::return_data_first_only: bool; const Tunnel::decapsulate_ip: bool; -const Tunnel::decapsulate_udp: bool; -const Tunnel::udp_tunnel_ports: any; -const Tunnel::udp_tunnel_allports: bool; const Tunnel::max_depth: count; diff --git a/src/types.bif b/src/types.bif index 60f8631a23..526198b2f5 100644 --- a/src/types.bif +++ b/src/types.bif @@ -178,8 +178,7 @@ enum Type %{ IP4_IN_IP6, IP6_IN_UDP, IP4_IN_UDP, - IP6_IN_AYIAY, - IP4_IN_AYIAY, + AYIYA, %} type EncapsulatingConn: record; From a4af69461066e4353c3a06ff0cb5a52e3dcd7745 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 24 Apr 2012 01:17:45 -0400 Subject: [PATCH 20/51] AYIYA analyzer ignores non-packet forwarding packets now. --- src/ayiya-analyzer.pac | 6 ++++++ src/ayiya-protocol.pac | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 3834ccc3b6..763077c6a8 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -20,6 +20,12 @@ flow AYIYA_Flow return false; } + if ( ${pdu.op} != 1 ) + { + // 1 is the "forward" command. + return false; + } + IP_Hdr* inner_ip; if ( ${pdu.next_header} == IPPROTO_IPV6 ) inner_ip = new IP_Hdr((const struct ip6_hdr*) ${pdu.packet}.data(), false, ${pdu.packet}.length()); diff --git a/src/ayiya-protocol.pac b/src/ayiya-protocol.pac index 25aca23fb9..7801708c7d 100644 --- a/src/ayiya-protocol.pac +++ b/src/ayiya-protocol.pac @@ -1,14 +1,16 @@ type PDU = record { - identity_byte: uint8; - signature_byte: uint8; - auth_and_op_crap: uint8; - next_header: uint8; - epoch: uint32; - identity: bytestring &length=identity_len; - signature: bytestring &length=signature_len; - packet: bytestring &restofdata; + identity_byte: uint8; + signature_byte: uint8; + auth_and_op: uint8; + next_header: uint8; + epoch: uint32; + identity: bytestring &length=identity_len; + signature: bytestring &length=signature_len; + packet: bytestring &restofdata; } &let { identity_len = (1 << (identity_byte >> 4)); signature_len = (signature_byte >> 4) * 4; + auth = auth_and_op >> 4; + op = auth_and_op & 0xF; } &byteorder = littleendian; \ No newline at end of file From 85bb5deb9207395273598aad6840b8eb4bf93d7b Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 24 Apr 2012 11:40:05 -0500 Subject: [PATCH 21/51] Fix AYIYA analyzer from modifying parent connection's encapsulation. --- src/Conn.h | 3 ++- src/ayiya-analyzer.pac | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Conn.h b/src/Conn.h index 7f998c9d9a..9abc75ff68 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -246,7 +246,8 @@ public: void SetUID(uint64 arg_uid) { uid = arg_uid; } - Encapsulation* GetEncapsulation() { return &encapsulation; } + const Encapsulation& GetEncapsulation() const + { return encapsulation; } protected: diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 763077c6a8..0530207c20 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -13,7 +13,7 @@ flow AYIYA_Flow %{ Connection *c = connection()->bro_analyzer()->Conn(); - if ( c->GetEncapsulation()->Depth() >= BifConst::Tunnel::max_depth ) + if ( c->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth ) { reporter->Weird(c->OrigAddr(), c->RespAddr(), "tunnel_depth"); // TODO: this should stop this analyzer instance @@ -42,10 +42,13 @@ flow AYIYA_Flow // Not sure what to do with this timestamp. //fake_hdr.ts = network_time(); - EncapsulatingConn ec(c->OrigAddr(), c->RespAddr(), BifEnum::Tunnel::AYIYA); - c->GetEncapsulation()->Add(ec); + Encapsulation encap(c->GetEncapsulation()); + EncapsulatingConn ec(c->OrigAddr(), c->RespAddr(), + c->OrigPort(), c->RespPort(), + BifEnum::Tunnel::AYIYA); + encap.Add(ec); - sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, *c->GetEncapsulation()); + sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, encap); delete inner_ip; return true; From 4d86f38be0d76ef812fb5a40d66984a75227dfbf Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 24 Apr 2012 14:12:42 -0500 Subject: [PATCH 22/51] Remove invalid IP-in-IP encapsulated protocol value. --- src/Sessions.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index 326306c2fd..dbf6f1c22a 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -522,7 +522,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, break; } - case IPPROTO_IP: case IPPROTO_IPV4: case IPPROTO_IPV6: { @@ -674,7 +673,6 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, case IPPROTO_UDP: min_hdr_len = sizeof(struct udphdr); break; - case IPPROTO_IP: case IPPROTO_IPV4: min_hdr_len = sizeof(struct ip); break; From bd01525a86b9bfbbc0dc5475439b7acfdb09ae10 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 24 Apr 2012 14:25:47 -0500 Subject: [PATCH 23/51] Remove Tunnel::decapsulate_ip option. Setting Tunnel::max_depth to zero effectively disables tunnel decapsulation. --- scripts/base/init-bare.bro | 4 +--- src/AYIYA.h | 2 +- src/Sessions.cc | 7 ------- src/const.bif | 1 - 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 45ec94baa8..a04063b55a 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2629,10 +2629,8 @@ const ignore_keep_alive_rexmit = F &redef; module Tunnel; export { - ## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) - const decapsulate_ip = T &redef; - ## The maximum depth of a tunnel to decapsulate until giving up. + ## Setting this to zero will disable tunnel decapsulation. const max_depth: count = 2 &redef; } # end export module GLOBAL; diff --git a/src/AYIYA.h b/src/AYIYA.h index f7c67ced5b..bf1fb0bf2c 100644 --- a/src/AYIYA.h +++ b/src/AYIYA.h @@ -16,7 +16,7 @@ public: { return new AYIYA_Analyzer(conn); } static bool Available() - { return BifConst::Tunnel::decapsulate_ip; } + { return BifConst::Tunnel::max_depth > 0; } protected: friend class AnalyzerTimer; diff --git a/src/Sessions.cc b/src/Sessions.cc index dbf6f1c22a..cb2b5633ca 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -525,13 +525,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, case IPPROTO_IPV4: case IPPROTO_IPV6: { - if ( ! BifConst::Tunnel::decapsulate_ip ) - { - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "ip_tunnel"); - Remove(f); - return; - } - if ( encapsulation.Depth() >= BifConst::Tunnel::max_depth ) { reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "tunnel_depth"); diff --git a/src/const.bif b/src/const.bif index db5fbbd2cb..09ce769261 100644 --- a/src/const.bif +++ b/src/const.bif @@ -11,5 +11,4 @@ const NFS3::return_data: bool; const NFS3::return_data_max: count; const NFS3::return_data_first_only: bool; -const Tunnel::decapsulate_ip: bool; const Tunnel::max_depth: count; From 2235647ab7af0aafcf1ee8c54000e4485dee3ab1 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 24 Apr 2012 17:30:37 -0400 Subject: [PATCH 24/51] Some improvements to the AYIYA analyzer. - Reenabled AYIYA dpd sigs. --- scripts/base/frameworks/dpd/dpd.sig | 10 +++++----- src/ayiya-analyzer.pac | 16 +++++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/scripts/base/frameworks/dpd/dpd.sig b/scripts/base/frameworks/dpd/dpd.sig index f5d3651104..b1fb9e6f19 100644 --- a/scripts/base/frameworks/dpd/dpd.sig +++ b/scripts/base/frameworks/dpd/dpd.sig @@ -150,11 +150,11 @@ signature dpd_ssl_client { tcp-state originator } -#signature dpd_ayiya { -# ip-proto = udp -# payload /^..\x11\x29/ -# enable "ayiya" -#} +signature dpd_ayiya { + ip-proto = udp + payload /^..\x11\x29/ + enable "ayiya" +} signature dpd_socks_client { ip-proto == tcp diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 0530207c20..856d22c417 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -15,8 +15,7 @@ flow AYIYA_Flow if ( c->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth ) { - reporter->Weird(c->OrigAddr(), c->RespAddr(), "tunnel_depth"); - // TODO: this should stop this analyzer instance + reporter->Weird(c, "tunnel_depth"); return false; } @@ -29,13 +28,16 @@ flow AYIYA_Flow IP_Hdr* inner_ip; if ( ${pdu.next_header} == IPPROTO_IPV6 ) inner_ip = new IP_Hdr((const struct ip6_hdr*) ${pdu.packet}.data(), false, ${pdu.packet}.length()); - else + else if ( ${pdu.next_header} == IPPROTO_IPV4 ) inner_ip = new IP_Hdr((const struct ip*) ${pdu.packet}.data(), false); - - if ( inner_ip != 0) - connection()->bro_analyzer()->ProtocolConfirmation(); else - connection()->bro_analyzer()->ProtocolViolation("ayiya_tunnel_non_ip"); + { + reporter->Weird(c, "ayiya_tunnel_non_ip"); + return false; + } + + if ( inner_ip != 0 ) + connection()->bro_analyzer()->ProtocolConfirmation(); struct pcap_pkthdr fake_hdr; fake_hdr.caplen = fake_hdr.len = ${pdu.packet}.length(); From b8e1604ab571bd84a598fb57f6ad450731a64a56 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 26 Apr 2012 12:29:59 -0500 Subject: [PATCH 25/51] Make tunnels always identifiable by UID, tunnel.log now gets populated. conn.log now sets a field indicating all the parent tunnel UIDs over which a connection operated and cross reference the UIDs found in the tunnel.log. Also some renaming of tunnel related types at the scripting layer. --- doc/scripts/DocSourcesList.cmake | 3 +- scripts/base/frameworks/tunnels/main.bro | 134 ++++++++++++++---- scripts/base/init-bare.bro | 7 +- scripts/base/protocols/conn/main.bro | 24 ++-- scripts/base/protocols/socks/main.bro | 2 +- scripts/policy/frameworks/tunnel.bro | 83 ----------- src/Conn.cc | 10 -- src/Conn.h | 12 +- src/Sessions.cc | 6 +- src/Tunnels.cc | 32 ++++- src/Tunnels.h | 27 ++-- src/ayiya-analyzer.pac | 10 +- src/event.bif | 2 +- src/types.bif | 9 +- .../Baseline/core.print-bpf-filters/conn.log | 6 +- .../Baseline/core.print-bpf-filters/output | 8 +- .../Baseline/core.tunnels.ip-in-ip/output | 16 +-- .../btest/Baseline/core.vlan-mpls/conn.log | 10 +- .../canonified_loaded_scripts.log | 4 + .../conn.log | 14 +- .../conn.log | 16 +-- testing/btest/core/tunnels/ip-in-ip.test | 2 +- 22 files changed, 224 insertions(+), 213 deletions(-) delete mode 100644 scripts/policy/frameworks/tunnel.bro diff --git a/doc/scripts/DocSourcesList.cmake b/doc/scripts/DocSourcesList.cmake index e6ed45502a..a35d6894d1 100644 --- a/doc/scripts/DocSourcesList.cmake +++ b/doc/scripts/DocSourcesList.cmake @@ -53,6 +53,7 @@ rest_target(${psd} base/frameworks/packet-filter/netstats.bro) rest_target(${psd} base/frameworks/reporter/main.bro) rest_target(${psd} base/frameworks/signatures/main.bro) rest_target(${psd} base/frameworks/software/main.bro) +rest_target(${psd} base/frameworks/tunnels/main.bro) rest_target(${psd} base/protocols/conn/contents.bro) rest_target(${psd} base/protocols/conn/inactivity.bro) rest_target(${psd} base/protocols/conn/main.bro) @@ -71,6 +72,7 @@ rest_target(${psd} base/protocols/irc/main.bro) rest_target(${psd} base/protocols/smtp/entities-excerpt.bro) rest_target(${psd} base/protocols/smtp/entities.bro) rest_target(${psd} base/protocols/smtp/main.bro) +rest_target(${psd} base/protocols/socks/main.bro) rest_target(${psd} base/protocols/ssh/main.bro) rest_target(${psd} base/protocols/ssl/consts.bro) rest_target(${psd} base/protocols/ssl/main.bro) @@ -97,7 +99,6 @@ rest_target(${psd} policy/frameworks/metrics/http-example.bro) rest_target(${psd} policy/frameworks/metrics/ssl-example.bro) rest_target(${psd} policy/frameworks/software/version-changes.bro) rest_target(${psd} policy/frameworks/software/vulnerable.bro) -rest_target(${psd} policy/frameworks/tunnel.bro) rest_target(${psd} policy/integration/barnyard2/main.bro) rest_target(${psd} policy/integration/barnyard2/types.bro) rest_target(${psd} policy/misc/analysis-groups.bro) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 952f382e56..df978d9510 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -1,53 +1,127 @@ -module Tunnels; +module Tunnel; export { + ## The tunnel logging stream identifier. redef enum Log::ID += { LOG }; - + + ## Types of interesting activity that can occur with a tunnel. type Action: enum { + ## A new tunnel (encapsulating "connection") has been seen. DISCOVER, + ## A tunnel connection has closed. CLOSE, + ## No new connections over a tunnel happened in the past day. + EXPIRE, }; - + + ## The record type which contains column fields of the tunnel log. type Info: record { - ts: time &log; - uid: string &log &optional; - id: conn_id &log; - action: Action &log; - tunnel_type: string &log; - user: string &log &optional; + ## Time at which some tunnel activity occurred. + ts: time &log; + ## The unique identifier for the tunnel, which may correspond + ## to a :bro:type:`connection`'s *uid* field for non-IP-in-IP tunnels. + uid: string &log &optional; + ## The tunnel "connection" 4-tuple of endpoint addresses/ports. + ## For an IP tunnel, the ports will be 0. + id: conn_id &log; + ## The type of activity that occurred. + action: Action &log; + ## The type of tunnel. + tunnel_type: Tunnel::Type &log; + user: string &log &optional; }; - - global register: function(c: connection, tunnel_type: string); - - global active: table[conn_id] of Tunnels::Info = table(); + + ## Logs all tunnels in an ecapsulation chain with action + ## :bro:see:`Tunnel::DISCOVER` that aren't already in the + ## :bro:id:`Tunnel::active` table and adds them if not. + global register_all: function(ecv: EncapsulatingConnVector); + + ## Logs a single tunnel "connection" with action + ## :bro:see:`Tunnel::DISCOVER` if it's not already in the + ## :bro:id:`Tunnel::active` table and adds it if not. + global register: function(ec: EncapsulatingConn); + + ## Logs a single tunnel "connection" with action + ## :bro:see:`Tunnel::EXPIRE` and removes it from the + ## :bro:id:`Tunnel::active` table. + ## + ## t: A table of tunnels. + ## + ## idx: The index of the tunnel table corresponding to the tunnel to expire. + ## + ## Returns: 0secs, which when this function is used as an + ## :bro:attr:`&expire_func`, indicates to remove the element at + ## *idx* immediately. + global expire: function(t: table[conn_id] of Info, idx: conn_id): interval; + + ## Removes a single tunnel from the :bro:id:`Tunnel::active` table + ## and logs the closing/expiration of the tunnel. + ## + ## tunnel: The tunnel which has closed or expired. + ## + ## action: The specific reason for the tunnel ending. + global close: function(tunnel: Info, action: Action); + + ## Currently active tunnels. That is, tunnels for which new, encapsulated + ## connections have been seen in the last day. + global active: table[conn_id] of Info = table() &synchronized &read_expire=24hrs &expire_func=expire; } event bro_init() &priority=5 { - Log::create_stream(Tunnels::LOG, [$columns=Info]); + Log::create_stream(Tunnel::LOG, [$columns=Info]); } -function register(c: connection, tunnel_type: string) +function register_all(ecv: EncapsulatingConnVector) { - local tunnel: Info; + for ( i in ecv ) + register(ecv[i]); + } + +function register(ec: EncapsulatingConn) + { + if ( ec$cid !in active ) + { + local tunnel: Info; + tunnel$ts = network_time(); + tunnel$uid = ec$uid; + tunnel$id = ec$cid; + tunnel$action = DISCOVER; + tunnel$tunnel_type = ec$tunnel_type; + active[ec$cid] = tunnel; + Log::write(LOG, tunnel); + } + } + +function close(tunnel: Info, action: Action) + { + tunnel$action = action; tunnel$ts = network_time(); - tunnel$uid = c$uid; - tunnel$id = c$id; - tunnel$action = DISCOVER; - tunnel$tunnel_type = tunnel_type; - - active[c$id] = tunnel; Log::write(LOG, tunnel); + delete active[tunnel$id]; + } + +function expire(t: table[conn_id] of Info, idx: conn_id): interval + { + close(t[idx], EXPIRE); + return 0secs; + } + +event new_connection(c: connection) &priority=5 + { + if ( c?$tunnel ) + register_all(c$tunnel); + } + +event tunnel_changed(c: connection, e: EncapsulatingConnVector) &priority=5 + { + if ( c?$tunnel ) + register_all(c$tunnel); + register_all(e); } event connection_state_remove(c: connection) &priority=-5 { if ( c$id in active ) - { - local tunnel = active[c$id]; - tunnel$action=CLOSE; - Log::write(LOG, tunnel); - - delete active[c$id]; - } - } \ No newline at end of file + close(active[c$id], CLOSE); + } diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index a04063b55a..59075de439 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -188,6 +188,9 @@ export { cid: conn_id; ## The type of tunnel. tunnel_type: Tunnel::Type; + ## A globally unique identifier that, for non-IP-in-IP tunnels, + ## cross-references the *uid* field of :bro:type:`connection`. + uid: string &optional; } &log; } # end export module GLOBAL; @@ -198,7 +201,7 @@ module GLOBAL; ## .. todo:: We need this type definition only for declaring builtin functions ## via ``bifcl``. We should extend ``bifcl`` to understand composite types ## directly and then remove this alias. -type encapsulating_conns: vector of Tunnel::EncapsulatingConn; +type EncapsulatingConnVector: vector of Tunnel::EncapsulatingConn; ## Statistics about an endpoint. ## @@ -251,7 +254,7 @@ type connection: record { ## at index zero. It's also always the first such enapsulation seen ## for the connection unless the :bro:id:`tunnel_changed` event is handled ## and re-assigns this field to the new encapsulation. - tunnel: encapsulating_conns &optional; + tunnel: EncapsulatingConnVector &optional; }; ## Fields of a SYN packet. diff --git a/scripts/base/protocols/conn/main.bro b/scripts/base/protocols/conn/main.bro index e4dbb28790..03e2cfaf71 100644 --- a/scripts/base/protocols/conn/main.bro +++ b/scripts/base/protocols/conn/main.bro @@ -102,8 +102,9 @@ export { ## Number IP level bytes the responder sent. See ``orig_pkts``. resp_ip_bytes: count &log &optional; ## If this connection was over a tunnel, indicate the - ## `uid` value for the parent connection or connections. - parents: vector of string &log &optional; + ## *uid* values for any encapsulating parent connections + ## used over the lifetime of this inner connection. + parents: set[string] &log; }; ## Event that can be handled to access the :bro:type:`Conn::Info` @@ -193,15 +194,8 @@ function set_conn(c: connection, eoc: bool) c$conn$ts=c$start_time; c$conn$uid=c$uid; c$conn$id=c$id; - if ( ! c$conn?$parents && c?$tunnel ) - { - c$conn$parents = vector(); - for ( i in c$tunnel ) - { - # TODO: maybe we should be storing uid's in the $tunnel field? - #c$conn$parents[|c$conn$parents|] = lookup_connection(c$tunnel[i]$cid)$uid; - } - } + if ( c?$tunnel && |c$tunnel| > 0 ) + add c$conn$parents[c$tunnel[|c$tunnel|-1]$uid]; c$conn$proto=get_port_transport_proto(c$id$resp_p); if( |Site::local_nets| > 0 ) c$conn$local_orig=Site::is_local_addr(c$id$orig_h); @@ -239,6 +233,14 @@ event content_gap(c: connection, is_orig: bool, seq: count, length: count) &prio c$conn$missed_bytes = c$conn$missed_bytes + length; } + +event tunnel_changed(c: connection, e: EncapsulatingConnVector) &priority=5 + { + set_conn(c, F); + if ( |e| > 0 ) + add c$conn$parents[e[|e|-1]$uid]; + c$tunnel = e; + } event connection_state_remove(c: connection) &priority=5 { diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro index 61f569d56c..bd27f4fb85 100644 --- a/scripts/base/protocols/socks/main.bro +++ b/scripts/base/protocols/socks/main.bro @@ -11,7 +11,7 @@ export { event socks_request(c: connection, request_type: count, dstaddr: addr, dstname: string, p: port, user: string) { - Tunnels::register(c, "SOCKS"); + Tunnel::register([$cid=c$id, $tunnel_type=Tunnel::SOCKS, $uid=c$uid]); } # diff --git a/scripts/policy/frameworks/tunnel.bro b/scripts/policy/frameworks/tunnel.bro deleted file mode 100644 index fb9bf2f3f6..0000000000 --- a/scripts/policy/frameworks/tunnel.bro +++ /dev/null @@ -1,83 +0,0 @@ -##! Handle tunneled connections. -##! -##! Bro can decapsulate IPinIP and IPinUDP tunnels, were "IP" can be either -##! IPv4 or IPv6. The most common case will be decapsulating Teredo, 6to4, -##! 6in4, and AYIAY. When this script is loaded, decapsulation will be -##! enabled. "tunnel.log" will log the "parent" for each tunneled -##! connection. The identity (and existence) of the tunnel connection -##! is otherwise lost. -##! -##! Currently handles: -##! -##! * IP6 in IP{4,6}. (IP4 in IP is easy to add, but omitted due to lack -##! of test cases. -##! * IP{4,6} in UDP. This decapsulates e.g., standard *Teredo* packets -##! (without authentication or origin indicator) -##! * IP{4,6} in AYIAY -##! * Only checks for UDP tunnels on Teredo's and AYIAY's default -##! ports. See :bro:id:`udp_tunnel_ports` and -##! :bro:id:`udp_tunnel_allports` -##! -##! Decapsulation happens early in a packets processing, right after IP -##! defragmentation but before there is a connection context. The tunnel -##! headers are stripped from packet and the identity of the parent is -##! is stored as the ``tunnel_parent`` member of :bro:type:`connection`, -##! which is of type :bro:type:`Tunnel::Parent`. -##! -##! *Limitation:* decapsulation happens only on the primary path, i.e. -##! it's not available for the secondary path. - -@load base/protocols/conn - -module Tunnel; - -redef Tunnel::decapsulate_ip = T; -redef Tunnel::decapsulate_udp = T; -redef Tunnel::udp_tunnel_allports = T; - -export { - ## The Tunnel logging stream identifier. - redef enum Log::ID += { LOG }; - - ## This record describing a tunneled connection will be logged. - type Info : record { - ## This is the time of the first record - ts: time &log; - ## The uid of the child connection, i.e. the connection in the tunnel - uid: string &log; - ## The connection id of the child - id: conn_id &log; - ## The child's transport protocol - proto: transport_proto &log; - ## The parent connection of IP-pair - parent: Parent &log; - }; - - ## Event that can be handled to access the :bro:type:`Tunnel::Info` - ## record as it is sent on to the logging framework. - global log_tunnel: event(rec: Info); - - redef record Conn::Info += { - ## If the connection is tunneled, the type of tunnel. - tunnel_type: Tunneltype &log &optional; - }; -} - -event bro_init() - { - Log::create_stream(Tunnel::LOG, [$columns=Info, $ev=log_tunnel]); - } - -event new_connection(c: connection) - { - if (c?$tunnel_parent) - { - local info: Info; - info$ts = c$start_time; - info$uid = c$uid; - info$id = c$id; - info$proto = get_port_transport_proto(c$id$resp_p); - info$parent = c$tunnel_parent; - Log::write(Tunnel::LOG, info); - } - } diff --git a/src/Conn.cc b/src/Conn.cc index 55cfb3b3cb..6333f98f3e 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -13,7 +13,6 @@ #include "Timer.h" #include "PIA.h" #include "binpac.h" -#include "Tunnels.h" void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer, int arg_do_expire) @@ -192,15 +191,6 @@ Connection::~Connection() --external_connections; } -void Connection::CheckEncapsulation(const Encapsulation& arg_encap) - { - if ( encapsulation != arg_encap ) - { - Event(tunnel_changed, 0, arg_encap.GetVectorVal()); - encapsulation = arg_encap; - } - } - void Connection::Done() { finished = 1; diff --git a/src/Conn.h b/src/Conn.h index 9abc75ff68..d5622efe03 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -23,7 +23,6 @@ class RuleHdrTest; class Specific_RE_Matcher; class TransportLayerAnalyzer; class RuleEndpointState; -class TunnelParent; typedef enum { NUL_IN_LINE, @@ -56,7 +55,14 @@ public: const Encapsulation& arg_encap); virtual ~Connection(); - void CheckEncapsulation(const Encapsulation& arg_encap); + void CheckEncapsulation(const Encapsulation& arg_encap) + { + if ( encapsulation != arg_encap ) + { + Event(tunnel_changed, 0, arg_encap.GetVectorVal()); + encapsulation = arg_encap; + } + } // Invoked when connection is about to be removed. Use Ref(this) // inside Done to keep the connection object around (though it'll @@ -245,6 +251,8 @@ public: void SetTransport(TransportProto arg_proto) { proto = arg_proto; } void SetUID(uint64 arg_uid) { uid = arg_uid; } + + uint64 GetUID() const { return uid; } const Encapsulation& GetEncapsulation() const { return encapsulation; } diff --git a/src/Sessions.cc b/src/Sessions.cc index cb2b5633ca..fa6faba85c 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -543,11 +543,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, fake_hdr.ts = hdr->ts; EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - ip_hdr->IP4_Hdr() ? - ( proto == IPPROTO_IPV6 ? - BifEnum::Tunnel::IP6_IN_IP4 : BifEnum::Tunnel::IP4_IN_IP4 ) : - ( proto == IPPROTO_IPV6 ? - BifEnum::Tunnel::IP6_IN_IP6 : BifEnum::Tunnel::IP4_IN_IP6 )); + BifEnum::Tunnel::IP); encapsulation.Add(ec); DoNextPacket(t, &fake_hdr, inner_ip, data, 0, encapsulation); diff --git a/src/Tunnels.cc b/src/Tunnels.cc index 950e94628e..7ae87912d7 100644 --- a/src/Tunnels.cc +++ b/src/Tunnels.cc @@ -1,6 +1,20 @@ // See the file "COPYING" in the main distribution directory for copyright. #include "Tunnels.h" +#include "util.h" +#include "Conn.h" + +EncapsulatingConn::EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t) + : src_addr(c->OrigAddr()), dst_addr(c->RespAddr()), + src_port(c->OrigPort()), dst_port(c->RespPort()), + type(t), uid(c->GetUID()) + { + if ( ! uid ) + { + uid = calculate_unique_id(); + c->SetUID(uid); + } + } RecordVal* EncapsulatingConn::GetRecordVal() const { @@ -8,15 +22,17 @@ RecordVal* EncapsulatingConn::GetRecordVal() const new RecordVal(BifType::Record::Tunnel::EncapsulatingConn); TransportProto tproto; switch ( type ) { - case BifEnum::Tunnel::IP6_IN_IP4: - case BifEnum::Tunnel::IP4_IN_IP4: - case BifEnum::Tunnel::IP6_IN_IP6: - case BifEnum::Tunnel::IP4_IN_IP6: - tproto = TRANSPORT_UNKNOWN; - break; - default: + case BifEnum::Tunnel::AYIYA: + case BifEnum::Tunnel::TEREDO: tproto = TRANSPORT_UDP; break; + case BifEnum::Tunnel::SOCKS: + tproto = TRANSPORT_TCP; + break; + case BifEnum::Tunnel::IP: + default: + tproto = TRANSPORT_UNKNOWN; + break; } // end switch RecordVal* id_val = new RecordVal(conn_id); @@ -26,6 +42,8 @@ RecordVal* EncapsulatingConn::GetRecordVal() const id_val->Assign(3, new PortVal(ntohs(dst_port), tproto)); rv->Assign(0, id_val); rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type)); + char tmp[20]; + rv->Assign(2, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62))); return rv; } diff --git a/src/Tunnels.h b/src/Tunnels.h index d4dfee8f97..e6e3de6d76 100644 --- a/src/Tunnels.h +++ b/src/Tunnels.h @@ -9,25 +9,27 @@ #include "Val.h" #include +class Connection; + class EncapsulatingConn { public: - EncapsulatingConn() - : src_port(0), dst_port(0), type(BifEnum::Tunnel::NONE) {} - EncapsulatingConn(const IPAddr& s, const IPAddr& d, BifEnum::Tunnel::Type t) - : src_addr(s), dst_addr(d), src_port(0), dst_port(0), type(t) {} + : src_addr(s), dst_addr(d), src_port(0), dst_port(0), type(t) + { + uid = calculate_unique_id(); + } - EncapsulatingConn(const IPAddr& s, const IPAddr& d, uint16 sp, uint16 dp, - BifEnum::Tunnel::Type t) - : src_addr(s), dst_addr(d), src_port(sp), dst_port(dp), type(t) {} + EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t); EncapsulatingConn(const EncapsulatingConn& other) : src_addr(other.src_addr), dst_addr(other.dst_addr), src_port(other.src_port), dst_port(other.dst_port), - type(other.type) {} + type(other.type), uid(other.uid) + {} - ~EncapsulatingConn() {} + ~EncapsulatingConn() + {} RecordVal* GetRecordVal() const; @@ -35,7 +37,8 @@ public: const EncapsulatingConn& ec2) { return ec1.type == ec2.type && ec1.src_addr == ec2.src_addr && - ec1.src_port == ec2.src_port && ec1.dst_port == ec2.dst_port; + ec1.src_port == ec2.src_port && ec1.dst_port == ec2.dst_port && + ec1.uid == ec2.uid; } friend bool operator!=(const EncapsulatingConn& ec1, @@ -49,11 +52,13 @@ public: uint16 src_port; uint16 dst_port; BifEnum::Tunnel::Type type; + uint64 uid; }; class Encapsulation { public: - Encapsulation() : conns(0) {} + Encapsulation() : conns(0) + {} Encapsulation(const Encapsulation& other) { diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 856d22c417..1a91cb1229 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -36,18 +36,14 @@ flow AYIYA_Flow return false; } - if ( inner_ip != 0 ) - connection()->bro_analyzer()->ProtocolConfirmation(); + connection()->bro_analyzer()->ProtocolConfirmation(); struct pcap_pkthdr fake_hdr; fake_hdr.caplen = fake_hdr.len = ${pdu.packet}.length(); - // Not sure what to do with this timestamp. - //fake_hdr.ts = network_time(); + fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; Encapsulation encap(c->GetEncapsulation()); - EncapsulatingConn ec(c->OrigAddr(), c->RespAddr(), - c->OrigPort(), c->RespPort(), - BifEnum::Tunnel::AYIYA); + EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA); encap.Add(ec); sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, encap); diff --git a/src/event.bif b/src/event.bif index 07fde79cfa..4f586c4f79 100644 --- a/src/event.bif +++ b/src/event.bif @@ -150,7 +150,7 @@ event new_connection%(c: connection%); ## c: The connection whose tunnel/encapsulation changed. ## ## e: The new encapsulation. -event tunnel_changed%(c: connection, e: encapsulating_conns%); +event tunnel_changed%(c: connection, e: EncapsulatingConnVector%); ## Generated when reassembly starts for a TCP connection. The event is raised ## at the moment when Bro's TCP analyzer enables stream reassembly for a diff --git a/src/types.bif b/src/types.bif index 526198b2f5..444c33eee9 100644 --- a/src/types.bif +++ b/src/types.bif @@ -172,13 +172,10 @@ enum ID %{ module Tunnel; enum Type %{ NONE, - IP6_IN_IP4, - IP4_IN_IP4, - IP6_IN_IP6, - IP4_IN_IP6, - IP6_IN_UDP, - IP4_IN_UDP, + IP, AYIYA, + TEREDO, + SOCKS, %} type EncapsulatingConn: record; diff --git a/testing/btest/Baseline/core.print-bpf-filters/conn.log b/testing/btest/Baseline/core.print-bpf-filters/conn.log index 5ce968d5e6..ca81844a4a 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/conn.log +++ b/testing/btest/Baseline/core.print-bpf-filters/conn.log @@ -3,6 +3,6 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes -#types time string addr port addr port enum string interval count count string bool count string count count count count -1128727435.450898 UWkUyAuUGXf 141.42.64.125 56730 125.190.109.199 80 tcp http 1.733303 98 9417 SF - 0 ShADdFaf 12 730 10 9945 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1128727435.450898 UWkUyAuUGXf 141.42.64.125 56730 125.190.109.199 80 tcp http 1.733303 98 9417 SF - 0 ShADdFaf 12 730 10 9945 (empty) diff --git a/testing/btest/Baseline/core.print-bpf-filters/output b/testing/btest/Baseline/core.print-bpf-filters/output index a2bf430fb4..b4a52965cb 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/output +++ b/testing/btest/Baseline/core.print-bpf-filters/output @@ -5,7 +5,7 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1328294052.330721 - ip or not ip T T +1335456050.312960 - ip or not ip T T #separator \x09 #set_separator , #empty_field (empty) @@ -13,7 +13,7 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1328294052.542418 - ((((((((((((((((((((((((port 53) or (tcp port 989)) or (tcp port 443)) or (port 6669)) or (udp and port 5353)) or (port 6668)) or (udp and port 5355)) or (tcp port 22)) or (tcp port 995)) or (port 21)) or (tcp port 25 or tcp port 587)) or (port 6667)) or (tcp port 614)) or (tcp port 990)) or (udp port 137)) or (tcp port 993)) or (tcp port 5223)) or (port 514)) or (tcp port 585)) or (tcp port 992)) or (tcp port 563)) or (tcp port 994)) or (tcp port 636)) or (tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888))) or (port 6666) T T +1335456050.557822 - ((((((((((((((((((((((((port 53) or (tcp port 989)) or (tcp port 443)) or (port 6669)) or (udp and port 5353)) or (port 6668)) or (udp and port 5355)) or (tcp port 22)) or (tcp port 995)) or (port 21)) or (tcp port 25 or tcp port 587)) or (port 6667)) or (tcp port 614)) or (tcp port 990)) or (udp port 137)) or (tcp port 993)) or (tcp port 5223)) or (port 514)) or (tcp port 585)) or (tcp port 992)) or (tcp port 563)) or (tcp port 994)) or (tcp port 636)) or (tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888))) or (port 6666) T T #separator \x09 #set_separator , #empty_field (empty) @@ -21,7 +21,7 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1328294052.748480 - port 42 T T +1335456050.805695 - port 42 T T #separator \x09 #set_separator , #empty_field (empty) @@ -29,4 +29,4 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1328294052.952845 - port 56730 T T +1335456051.042953 - port 56730 T T diff --git a/testing/btest/Baseline/core.tunnels.ip-in-ip/output b/testing/btest/Baseline/core.tunnels.ip-in-ip/output index 7ed712aec8..4c8738290f 100644 --- a/testing/btest/Baseline/core.tunnels.ip-in-ip/output +++ b/testing/btest/Baseline/core.tunnels.ip-in-ip/output @@ -1,22 +1,22 @@ new_connection: tunnel conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] - encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] + encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] new_connection: tunnel conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] - encap: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6], [cid=[orig_h=babe::beef, orig_p=0/unknown, resp_h=dead::babe, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] + encap: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf], [cid=[orig_h=babe::beef, orig_p=0/unknown, resp_h=dead::babe, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=arKYeMETxOg]] new_connection: tunnel conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] - encap: [[cid=[orig_h=1.2.3.4, orig_p=0/unknown, resp_h=5.6.7.8, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP4]] + encap: [[cid=[orig_h=1.2.3.4, orig_p=0/unknown, resp_h=5.6.7.8, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] new_connection: tunnel conn_id: [orig_h=70.55.213.211, orig_p=31337/tcp, resp_h=192.88.99.1, resp_p=80/tcp] - encap: [[cid=[orig_h=2002:4637:d5d3::4637:d5d3, orig_p=0/unknown, resp_h=2001:4860:0:2001::68, resp_p=0/unknown], tunnel_type=Tunnel::IP4_IN_IP6]] + encap: [[cid=[orig_h=2002:4637:d5d3::4637:d5d3, orig_p=0/unknown, resp_h=2001:4860:0:2001::68, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] new_connection: tunnel conn_id: [orig_h=10.0.0.1, orig_p=30000/udp, resp_h=10.0.0.2, resp_p=13000/udp] - encap: [[cid=[orig_h=1.2.3.4, orig_p=0/unknown, resp_h=5.6.7.8, resp_p=0/unknown], tunnel_type=Tunnel::IP4_IN_IP4]] + encap: [[cid=[orig_h=1.2.3.4, orig_p=0/unknown, resp_h=5.6.7.8, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] new_connection: tunnel conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] - encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] + encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] tunnel_changed: conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] - old: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] - new: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP6_IN_IP6]] + old: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] + new: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=k6kgXLOoSKl]] diff --git a/testing/btest/Baseline/core.vlan-mpls/conn.log b/testing/btest/Baseline/core.vlan-mpls/conn.log index f3c958ea99..20903d1db8 100644 --- a/testing/btest/Baseline/core.vlan-mpls/conn.log +++ b/testing/btest/Baseline/core.vlan-mpls/conn.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes -#types time string addr port addr port enum string interval count count string bool count string count count count count -952109346.874907 UWkUyAuUGXf 10.1.2.1 11001 10.34.0.1 23 tcp - 2.102560 26 0 SH - 0 SADF 11 470 0 0 -1128727435.450898 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 tcp http 1.733303 98 9417 SF - 0 ShADdFaf 12 730 10 9945 -1278600802.069419 k6kgXLOoSKl 10.20.80.1 50343 10.0.0.15 80 tcp - 0.004152 9 3429 SF - 0 ShADadfF 7 381 7 3801 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +952109346.874907 UWkUyAuUGXf 10.1.2.1 11001 10.34.0.1 23 tcp - 2.102560 26 0 SH - 0 SADF 11 470 0 0 (empty) +1128727435.450898 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 tcp http 1.733303 98 9417 SF - 0 ShADdFaf 12 730 10 9945 (empty) +1278600802.069419 k6kgXLOoSKl 10.20.80.1 50343 10.0.0.15 80 tcp - 0.004152 9 3429 SF - 0 ShADadfF 7 381 7 3801 (empty) diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 92deb62edb..88a85fc827 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -61,6 +61,8 @@ scripts/base/init-default.bro scripts/base/frameworks/intel/./main.bro scripts/base/frameworks/reporter/__load__.bro scripts/base/frameworks/reporter/./main.bro + scripts/base/frameworks/tunnels/__load__.bro + scripts/base/frameworks/tunnels/./main.bro scripts/base/protocols/conn/__load__.bro scripts/base/protocols/conn/./main.bro scripts/base/protocols/conn/./contents.bro @@ -85,6 +87,8 @@ scripts/base/init-default.bro scripts/base/protocols/smtp/./main.bro scripts/base/protocols/smtp/./entities.bro scripts/base/protocols/smtp/./entities-excerpt.bro + scripts/base/protocols/socks/__load__.bro + scripts/base/protocols/socks/./main.bro scripts/base/protocols/ssh/__load__.bro scripts/base/protocols/ssh/./main.bro scripts/base/protocols/ssl/__load__.bro diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log index bcb05ef415..5704153b07 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes -#types time string addr port addr port enum string interval count count string bool count string count count count count -1329843175.736107 arKYeMETxOg 141.142.220.235 37604 199.233.217.249 56666 tcp ftp-data 0.112432 0 342 SF - 0 ShAdfFa 4 216 4 562 -1329843179.871641 k6kgXLOoSKl 141.142.220.235 59378 199.233.217.249 56667 tcp ftp-data 0.111218 0 77 SF - 0 ShAdfFa 4 216 4 297 -1329843194.151526 nQcgTWjvg4c 199.233.217.249 61920 141.142.220.235 33582 tcp ftp-data 0.056211 342 0 SF - 0 ShADaFf 5 614 3 164 -1329843197.783443 j4u32Pc5bif 199.233.217.249 61918 141.142.220.235 37835 tcp ftp-data 0.056005 77 0 SF - 0 ShADaFf 5 349 3 164 -1329843161.968492 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 tcp ftp 38.055625 180 3146 SF - 0 ShAdDfFa 38 2164 25 4458 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1329843175.736107 arKYeMETxOg 141.142.220.235 37604 199.233.217.249 56666 tcp ftp-data 0.112432 0 342 SF - 0 ShAdfFa 4 216 4 562 (empty) +1329843179.871641 k6kgXLOoSKl 141.142.220.235 59378 199.233.217.249 56667 tcp ftp-data 0.111218 0 77 SF - 0 ShAdfFa 4 216 4 297 (empty) +1329843194.151526 nQcgTWjvg4c 199.233.217.249 61920 141.142.220.235 33582 tcp ftp-data 0.056211 342 0 SF - 0 ShADaFf 5 614 3 164 (empty) +1329843197.783443 j4u32Pc5bif 199.233.217.249 61918 141.142.220.235 37835 tcp ftp-data 0.056005 77 0 SF - 0 ShADaFf 5 349 3 164 (empty) +1329843161.968492 UWkUyAuUGXf 141.142.220.235 50003 199.233.217.249 21 tcp ftp 38.055625 180 3146 SF - 0 ShAdDfFa 38 2164 25 4458 (empty) diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log index c4a515710d..e3d458bae7 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log @@ -3,11 +3,11 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes -#types time string addr port addr port enum string interval count count string bool count string count count count count -1329327783.316897 arKYeMETxOg 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49186 2001:470:4867:99::21 57086 tcp ftp-data 0.219721 0 342 SF - 0 ShAdfFa 5 372 4 642 -1329327786.524332 k6kgXLOoSKl 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49187 2001:470:4867:99::21 57087 tcp ftp-data 0.217501 0 43 SF - 0 ShAdfFa 5 372 4 343 -1329327787.289095 nQcgTWjvg4c 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49188 2001:470:4867:99::21 57088 tcp ftp-data 0.217941 0 77 SF - 0 ShAdfFa 5 372 4 377 -1329327795.571921 j4u32Pc5bif 2001:470:4867:99::21 55785 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49189 tcp ftp-data 0.109813 77 0 SF - 0 ShADFaf 5 449 4 300 -1329327777.822004 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 tcp ftp 26.658219 310 3448 SF - 0 ShAdDfFa 57 4426 34 5908 -1329327800.017649 TEfuqmmG4bh 2001:470:4867:99::21 55647 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49190 tcp ftp-data 0.109181 342 0 SF - 0 ShADFaf 5 714 4 300 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1329327783.316897 arKYeMETxOg 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49186 2001:470:4867:99::21 57086 tcp ftp-data 0.219721 0 342 SF - 0 ShAdfFa 5 372 4 642 (empty) +1329327786.524332 k6kgXLOoSKl 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49187 2001:470:4867:99::21 57087 tcp ftp-data 0.217501 0 43 SF - 0 ShAdfFa 5 372 4 343 (empty) +1329327787.289095 nQcgTWjvg4c 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49188 2001:470:4867:99::21 57088 tcp ftp-data 0.217941 0 77 SF - 0 ShAdfFa 5 372 4 377 (empty) +1329327795.571921 j4u32Pc5bif 2001:470:4867:99::21 55785 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49189 tcp ftp-data 0.109813 77 0 SF - 0 ShADFaf 5 449 4 300 (empty) +1329327777.822004 UWkUyAuUGXf 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49185 2001:470:4867:99::21 21 tcp ftp 26.658219 310 3448 SF - 0 ShAdDfFa 57 4426 34 5908 (empty) +1329327800.017649 TEfuqmmG4bh 2001:470:4867:99::21 55647 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49190 tcp ftp-data 0.109181 342 0 SF - 0 ShADFaf 5 714 4 300 (empty) diff --git a/testing/btest/core/tunnels/ip-in-ip.test b/testing/btest/core/tunnels/ip-in-ip.test index f526575d48..38f4610445 100644 --- a/testing/btest/core/tunnels/ip-in-ip.test +++ b/testing/btest/core/tunnels/ip-in-ip.test @@ -20,7 +20,7 @@ event new_connection(c: connection) } } -event tunnel_changed(c: connection, e: encapsulating_conns) +event tunnel_changed(c: connection, e: EncapsulatingConnVector) { print "tunnel_changed:"; print fmt(" conn_id: %s", c$id); From 44c4d41d0d16017d8dae51c66954f2528a882fc8 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 26 Apr 2012 12:53:20 -0500 Subject: [PATCH 26/51] Add summary documentation to tunnels/main.bro. --- scripts/base/frameworks/tunnels/main.bro | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index df978d9510..b40aa519f9 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -1,3 +1,10 @@ +##! This script handles the tracking/logging of tunnels (e.g. Teredo, +##! AYIYA, or IP-in-IP such as 6to4 where "IP" is either IPv4 or IPv6). +##! +##! For any connection that occurs over a tunnel, information about its +##! its encapsulating tunnels is also found in the *tunnel* field of +##! :bro:type:`connection`. + module Tunnel; export { From 8791ac7337d729d0296eeacb136822e83bec6df7 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 26 Apr 2012 13:05:53 -0500 Subject: [PATCH 27/51] Fix AYIYA analyzer tag. --- src/AYIYA.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AYIYA.cc b/src/AYIYA.cc index c70af87fa8..ef845a5368 100644 --- a/src/AYIYA.cc +++ b/src/AYIYA.cc @@ -1,7 +1,7 @@ #include "AYIYA.h" AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn) -: Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn) +: Analyzer(AnalyzerTag::AYIYA, conn) { interp = new binpac::AYIYA::AYIYA_Conn(this); did_session_done = 0; From 064c5dddb82528ed24a4e38fde2865f739539a56 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 27 Apr 2012 10:28:46 -0500 Subject: [PATCH 28/51] Fix for IP tunnel UID persistence. --- scripts/base/frameworks/tunnels/main.bro | 2 +- scripts/base/init-bare.bro | 2 +- src/Conn.cc | 1 + src/Sessions.cc | 20 +++++++++-- src/Sessions.h | 5 +++ src/Tunnels.h | 12 ++++++- .../core.tunnels.ip-tunnel-uid/output | 33 ++++++++++++++++++ .../btest/Traces/tunnels/ping6-in-ipv4.pcap | Bin 0 -> 1524 bytes testing/btest/core/tunnels/ip-tunnel-uid.test | 33 ++++++++++++++++++ 9 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Baseline/core.tunnels.ip-tunnel-uid/output create mode 100644 testing/btest/Traces/tunnels/ping6-in-ipv4.pcap create mode 100644 testing/btest/core/tunnels/ip-tunnel-uid.test diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index b40aa519f9..743098cd6d 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -27,7 +27,7 @@ export { ts: time &log; ## The unique identifier for the tunnel, which may correspond ## to a :bro:type:`connection`'s *uid* field for non-IP-in-IP tunnels. - uid: string &log &optional; + uid: string &log; ## The tunnel "connection" 4-tuple of endpoint addresses/ports. ## For an IP tunnel, the ports will be 0. id: conn_id &log; diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 59075de439..cc798ecdc5 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -190,7 +190,7 @@ export { tunnel_type: Tunnel::Type; ## A globally unique identifier that, for non-IP-in-IP tunnels, ## cross-references the *uid* field of :bro:type:`connection`. - uid: string &optional; + uid: string; } &log; } # end export module GLOBAL; diff --git a/src/Conn.cc b/src/Conn.cc index 6333f98f3e..0e34903bed 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -13,6 +13,7 @@ #include "Timer.h" #include "PIA.h" #include "binpac.h" +#include "Tunnels.h" void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer, int arg_do_expire) diff --git a/src/Sessions.cc b/src/Sessions.cc index fa6faba85c..d3d5d294bc 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -542,9 +542,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, fake_hdr.caplen = fake_hdr.len = caplen; fake_hdr.ts = hdr->ts; - EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - BifEnum::Tunnel::IP); - encapsulation.Add(ec); + IPPair tunnel_idx; + if ( ip_hdr->SrcAddr() < ip_hdr->DstAddr() ) + tunnel_idx = IPPair(ip_hdr->SrcAddr(), ip_hdr->DstAddr()); + else + tunnel_idx = IPPair(ip_hdr->DstAddr(), ip_hdr->SrcAddr()); + + IPTunnelMap::const_iterator it = ip_tunnels.find(tunnel_idx); + + if ( it == ip_tunnels.end() ) + { + EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), + BifEnum::Tunnel::IP); + ip_tunnels[tunnel_idx] = ec; + encapsulation.Add(ec); + } + else + encapsulation.Add(it->second); DoNextPacket(t, &fake_hdr, inner_ip, data, 0, encapsulation); diff --git a/src/Sessions.h b/src/Sessions.h index fb76d29831..54ff74ded9 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -11,6 +11,8 @@ #include "PacketFilter.h" #include "Stats.h" #include "NetVar.h" +#include "Tunnels.h" +#include struct pcap_pkthdr; @@ -202,6 +204,9 @@ protected: PDict(Connection) udp_conns; PDict(Connection) icmp_conns; PDict(FragReassembler) fragments; + typedef pair IPPair; + typedef std::map IPTunnelMap; + IPTunnelMap ip_tunnels; ARP_Analyzer* arp_analyzer; diff --git a/src/Tunnels.h b/src/Tunnels.h index e6e3de6d76..b8d693ea59 100644 --- a/src/Tunnels.h +++ b/src/Tunnels.h @@ -13,6 +13,10 @@ class Connection; class EncapsulatingConn { public: + EncapsulatingConn() + : src_port(0), dst_port(0), type(BifEnum::Tunnel::NONE), uid(0) + {} + EncapsulatingConn(const IPAddr& s, const IPAddr& d, BifEnum::Tunnel::Type t) : src_addr(s), dst_addr(d), src_port(0), dst_port(0), type(t) @@ -36,7 +40,13 @@ public: friend bool operator==(const EncapsulatingConn& ec1, const EncapsulatingConn& ec2) { - return ec1.type == ec2.type && ec1.src_addr == ec2.src_addr && + if ( ec1.type != ec2.type ) + return false; + if ( ec1.type == BifEnum::Tunnel::IP ) + return ec1.uid == ec2.uid && + ((ec1.src_addr == ec2.src_addr && ec1.dst_addr == ec2.dst_addr) || + (ec1.src_addr == ec2.dst_addr && ec1.dst_addr == ec2.src_addr)); + return ec1.src_addr == ec2.src_addr && ec1.dst_addr == ec2.dst_addr && ec1.src_port == ec2.src_port && ec1.dst_port == ec2.dst_port && ec1.uid == ec2.uid; } diff --git a/testing/btest/Baseline/core.tunnels.ip-tunnel-uid/output b/testing/btest/Baseline/core.tunnels.ip-tunnel-uid/output new file mode 100644 index 0000000000..afb5837b23 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.ip-tunnel-uid/output @@ -0,0 +1,33 @@ +new_connection: tunnel + conn_id: [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + encap: [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +NEW_PACKET: + [orig_h=2001:db8:0:1::1, orig_p=128/icmp, resp_h=2001:db8:0:1::2, resp_p=129/icmp] + [[cid=[orig_h=10.0.0.1, orig_p=0/unknown, resp_h=10.0.0.2, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] diff --git a/testing/btest/Traces/tunnels/ping6-in-ipv4.pcap b/testing/btest/Traces/tunnels/ping6-in-ipv4.pcap new file mode 100644 index 0000000000000000000000000000000000000000..5e0995f80e0fd05ca0d03a58b6d99abd524097a5 GIT binary patch literal 1524 zcmca|c+)~A1{MZ5P+(wS1ai6`CU`u}XJ=>wvO)L|qZ1R5WB`#I46Y0e6%3pV4F5Hk z2XX;505MYnP!)rXm4gB!?+zdfWC#c_qVbs;80z{Z?to;Nm|0la*f}`4xOsT__yq)o zghfQf#3dx9q-A8~8Z-Z6ckn#JRFGBju}=6SCJT2o)oz%LmSCe zm|?{O4l6&>!^*%87*@g>output 2>&1 +# @TEST-EXEC: btest-diff output + +event new_connection(c: connection) + { + if ( c?$tunnel ) + { + print "new_connection: tunnel"; + print fmt(" conn_id: %s", c$id); + print fmt(" encap: %s", c$tunnel); + } + else + { + print "new_connection: no tunnel"; + } + } + +event tunnel_changed(c: connection, e: EncapsulatingConnVector) + { + print "tunnel_changed:"; + print fmt(" conn_id: %s", c$id); + if ( c?$tunnel ) + print fmt(" old: %s", c$tunnel); + print fmt(" new: %s", e); + } + +event new_packet(c: connection, p: pkt_hdr) + { + print "NEW_PACKET:"; + print fmt(" %s", c$id); + if ( c?$tunnel ) + print fmt(" %s", c$tunnel); + } From 8cd36f158bfa12ff593c12aae314670e709af2b3 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 25 May 2012 12:37:35 -0500 Subject: [PATCH 29/51] Add Teredo tunnel decapsulation. Also fix header truncation check for IPv6 No Next header and add an "ipv6_no_next" weird for such packets that aren't tunneled over Teredo (which it calls "bubbles" and are used to create mappings in NATs). --- scripts/base/frameworks/dpd/dpd.sig | 6 + scripts/base/frameworks/tunnels/__load__.bro | 3 - scripts/base/frameworks/tunnels/main.bro | 8 ++ src/AYIYA.cc | 5 +- src/AYIYA.h | 3 +- src/Analyzer.cc | 7 +- src/AnalyzerTags.h | 2 +- src/CMakeLists.txt | 1 + src/Sessions.cc | 16 +++ src/Teredo.cc | 126 +++++++++++++++++++ src/Teredo.h | 63 ++++++++++ src/Tunnels.h | 5 + src/ayiya-protocol.pac | 2 +- src/event.bif | 5 +- 14 files changed, 236 insertions(+), 16 deletions(-) create mode 100644 src/Teredo.cc create mode 100644 src/Teredo.h diff --git a/scripts/base/frameworks/dpd/dpd.sig b/scripts/base/frameworks/dpd/dpd.sig index b1fb9e6f19..305383809d 100644 --- a/scripts/base/frameworks/dpd/dpd.sig +++ b/scripts/base/frameworks/dpd/dpd.sig @@ -156,6 +156,12 @@ signature dpd_ayiya { enable "ayiya" } +signature dpd_teredo { + ip-proto = udp + payload /^(\x00\x00)|(\x00\x01)|([\x60-\x6f])/ + enable "teredo" +} + signature dpd_socks_client { ip-proto == tcp # '32' is a rather arbitrary max length for the user name. diff --git a/scripts/base/frameworks/tunnels/__load__.bro b/scripts/base/frameworks/tunnels/__load__.bro index 3def3511f5..a10fe855df 100644 --- a/scripts/base/frameworks/tunnels/__load__.bro +++ b/scripts/base/frameworks/tunnels/__load__.bro @@ -1,4 +1 @@ @load ./main - -const ports = { 5072/udp } &redef; -redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ports] }; diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 743098cd6d..4076e79cd5 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -74,6 +74,14 @@ export { global active: table[conn_id] of Info = table() &synchronized &read_expire=24hrs &expire_func=expire; } +const ayiya_ports = { 5072/udp }; +redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ayiya_ports] }; + +const teredo_ports = { 3544/udp }; +redef dpd_config += { [ANALYZER_TEREDO] = [$ports = teredo_ports] }; + +redef likely_server_ports += { ayiya_ports, teredo_ports }; + event bro_init() &priority=5 { Log::create_stream(Tunnel::LOG, [$columns=Info]); diff --git a/src/AYIYA.cc b/src/AYIYA.cc index ef845a5368..c525a73b6c 100644 --- a/src/AYIYA.cc +++ b/src/AYIYA.cc @@ -4,7 +4,6 @@ AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::AYIYA, conn) { interp = new binpac::AYIYA::AYIYA_Conn(this); - did_session_done = 0; } AYIYA_Analyzer::~AYIYA_Analyzer() @@ -15,9 +14,7 @@ AYIYA_Analyzer::~AYIYA_Analyzer() void AYIYA_Analyzer::Done() { Analyzer::Done(); - - if ( ! did_session_done ) - Event(udp_session_done); + Event(udp_session_done); } void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) diff --git a/src/AYIYA.h b/src/AYIYA.h index bf1fb0bf2c..2122cafee6 100644 --- a/src/AYIYA.h +++ b/src/AYIYA.h @@ -16,14 +16,13 @@ public: { return new AYIYA_Analyzer(conn); } static bool Available() + // TODO: specific option to turn off AYIYA analysis { return BifConst::Tunnel::max_depth > 0; } protected: friend class AnalyzerTimer; void ExpireTimer(double t); - int did_session_done; - binpac::AYIYA::AYIYA_Conn* interp; }; diff --git a/src/Analyzer.cc b/src/Analyzer.cc index c72af2a44a..9e30da0066 100644 --- a/src/Analyzer.cc +++ b/src/Analyzer.cc @@ -38,6 +38,7 @@ #include "SSH.h" #include "SSL.h" #include "Syslog-binpac.h" +#include "Teredo.h" #include "ConnSizeAnalyzer.h" // Keep same order here as in AnalyzerTag definition! @@ -135,9 +136,9 @@ const Analyzer::Config Analyzer::analyzer_configs[] = { { AnalyzerTag::SOCKS, "SOCKS", SOCKS_Analyzer::InstantiateAnalyzer, SOCKS_Analyzer::Available, 0, false }, - //{ AnalyzerTag::Teredo, "Teredo", - // Teredo_Analyzer::InstantiateAnalyzer, - // Teredo_Analyzer::Available, 0, false }, + { AnalyzerTag::Teredo, "TEREDO", + Teredo_Analyzer::InstantiateAnalyzer, + Teredo_Analyzer::Available, 0, false }, { AnalyzerTag::File, "FILE", File_Analyzer::InstantiateAnalyzer, File_Analyzer::Available, 0, false }, diff --git a/src/AnalyzerTags.h b/src/AnalyzerTags.h index 05de68f2b3..c77c229458 100644 --- a/src/AnalyzerTags.h +++ b/src/AnalyzerTags.h @@ -36,7 +36,7 @@ namespace AnalyzerTag { // Decapsulation Analyzers AYIYA, SOCKS, - //Teredo, + Teredo, // Other File, Backdoor, InterConn, SteppingStone, TCPStats, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50875cbcca..7d74aee1ce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -397,6 +397,7 @@ set(bro_SRCS TCP_Endpoint.cc TCP_Reassembler.cc Telnet.cc + Teredo.cc Timer.cc Traverse.cc Trigger.cc diff --git a/src/Sessions.cc b/src/Sessions.cc index d3d5d294bc..704bb62a25 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -567,6 +567,19 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } + case IPPROTO_NONE: + { + if ( encapsulation.LastType() == BifEnum::Tunnel::TEREDO ) + { + // TODO: raise bubble packet event + } + else + Weird("ipv6_no_next", hdr, pkt); + + Remove(f); + return; + } + default: Weird(fmt("unknown_protocol_%d", proto), hdr, pkt); Remove(f); @@ -682,6 +695,9 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, case IPPROTO_IPV6: min_hdr_len = sizeof(struct ip6_hdr); break; + case IPPROTO_NONE: + min_hdr_len = 0; + break; case IPPROTO_ICMP: case IPPROTO_ICMPV6: default: diff --git a/src/Teredo.cc b/src/Teredo.cc new file mode 100644 index 0000000000..39ecef286f --- /dev/null +++ b/src/Teredo.cc @@ -0,0 +1,126 @@ +#include "Teredo.h" +#include "IP.h" +#include "Reporter.h" + +void Teredo_Analyzer::Done() + { + Analyzer::Done(); + Event(udp_session_done); + } + +bool TeredoEncapsulation::DoParse(const u_char* data, int& len, + bool found_origin, bool found_auth) + { + if ( len < 2 ) + { + reporter->Weird(conn, "truncated_Teredo"); + } + + uint16 tag = ntohs((*((const uint16*)data))); + + if ( tag == 0 ) + { + // Origin Indication + if ( found_origin ) + // can't have multiple origin indications + return false; + + if ( len < 8 ) + { + reporter->Weird(conn, "truncated_Teredo_origin_indication"); + return false; + } + + origin_indication = data; + len -= 8; + data += 8; + return DoParse(data, len, true, found_auth); + } + else if ( tag == 1 ) + { + // Authentication + if ( found_origin || found_auth ) + // can't have multiple authentication headers and can't come after + // an origin indication + return false; + + if ( len < 4 ) + { + reporter->Weird(conn, "truncated_Teredo_authentication"); + return false; + } + + uint8 id_len = data[2]; + uint8 au_len = data[3]; + uint16 tot_len = 4 + id_len + au_len + 8 + 1; + + if ( len < tot_len ) + { + reporter->Weird(conn, "truncated_Teredo_authentication"); + return false; + } + + auth = data; + len -= tot_len; + data += tot_len; + return DoParse(data, len, found_origin, true); + } + else if ( ((tag & 0xf000)>>12) == 6 ) + { + // IPv6 + if ( len < 40 ) + { + reporter->Weird(conn, "truncated_IPv6_in_Teredo"); + return false; + } + + if ( len - 40 != ntohs(((const struct ip6_hdr*)data)->ip6_plen) ) + { + reporter->Weird(conn, "Teredo_payload_len_mismatch"); + return false; + } + + inner_ip = data; + return true; + } + + return false; + } + +void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + + if ( Conn()->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth ) + { + reporter->Weird(Conn(), "tunnel_depth"); + return; + } + + TeredoEncapsulation te(Conn()); + + if ( ! te.Parse(data, len) ) + { + ProtocolViolation("Invalid Teredo encapsulation", (const char*)data, + len); + return; + } + + IP_Hdr inner_ip((const struct ip6_hdr*) te.InnerIP(), false, len); + + ProtocolConfirmation(); + + // TODO: raise Teredo-specific events + + struct pcap_pkthdr fake_hdr; + fake_hdr.caplen = fake_hdr.len = len; + fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; + + Encapsulation encap(Conn()->GetEncapsulation()); + EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO); + encap.Add(ec); + + sessions->DoNextPacket(network_time, &fake_hdr, &inner_ip, te.InnerIP(), 0, + encap); + } diff --git a/src/Teredo.h b/src/Teredo.h new file mode 100644 index 0000000000..0662099233 --- /dev/null +++ b/src/Teredo.h @@ -0,0 +1,63 @@ +#ifndef Teredo_h +#define Teredo_h + +#include "Analyzer.h" +#include "NetVar.h" + +class Teredo_Analyzer : public Analyzer { +public: + Teredo_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::Teredo, conn) + {} + + virtual ~Teredo_Analyzer() + {} + + virtual void Done(); + + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + static Analyzer* InstantiateAnalyzer(Connection* conn) + { return new Teredo_Analyzer(conn); } + + static bool Available() + //TODO: specific option to turn off Teredo analysis? + { return BifConst::Tunnel::max_depth > 0; } + +protected: + friend class AnalyzerTimer; + void ExpireTimer(double t); +}; + +class TeredoEncapsulation { +public: + TeredoEncapsulation(Connection* c) + : inner_ip(0), origin_indication(0), auth(0), conn(c) + {} + + /** + * Returns whether input data parsed as a valid Teredo encapsulation type. + * If it was valid, the len argument is decremented appropriately. + */ + bool Parse(const u_char* data, int& len) + { return DoParse(data, len, false, false); } + + const u_char* InnerIP() const + { return inner_ip; } + + const u_char* OriginIndication() const + { return origin_indication; } + + const u_char* Authentication() const + { return auth; } + +protected: + bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au); + + const u_char* inner_ip; + const u_char* origin_indication; + const u_char* auth; + Connection* conn; +}; + +#endif diff --git a/src/Tunnels.h b/src/Tunnels.h index b8d693ea59..0f9c4f4107 100644 --- a/src/Tunnels.h +++ b/src/Tunnels.h @@ -103,6 +103,11 @@ public: return conns ? conns->size() : 0; } + BifEnum::Tunnel::Type LastType() const + { + return conns ? (*conns)[conns->size()-1].type : BifEnum::Tunnel::NONE; + } + VectorVal* GetVectorVal() const { VectorVal* vv = new VectorVal(new VectorType( diff --git a/src/ayiya-protocol.pac b/src/ayiya-protocol.pac index 7801708c7d..328d44ece7 100644 --- a/src/ayiya-protocol.pac +++ b/src/ayiya-protocol.pac @@ -13,4 +13,4 @@ type PDU = record { signature_len = (signature_byte >> 4) * 4; auth = auth_and_op >> 4; op = auth_and_op & 0xF; -} &byteorder = littleendian; \ No newline at end of file +} &byteorder = littleendian; diff --git a/src/event.bif b/src/event.bif index 94ee923240..7e428aabdd 100644 --- a/src/event.bif +++ b/src/event.bif @@ -765,8 +765,9 @@ event udp_reply%(u: connection%); event udp_contents%(u: connection, is_orig: bool, contents: string%); ## Generated when a UDP session for a supported protocol has finished. Some of -## Bro's application-layer UDP analyzers flag the end of a session by raising this -## event. Currently, the analyzers for DNS, NTP, Netbios, and Syslog support this. +## Bro's application-layer UDP analyzers flag the end of a session by raising +## this event. Currently, the analyzers for DNS, NTP, Netbios, Syslog, AYIYA, +## and Teredo support this. ## ## u: The connection record for the corresponding UDP flow. ## From 9851591317c822a763795f63365bbfab16a65d83 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 4 Jun 2012 16:14:30 -0500 Subject: [PATCH 30/51] Tunnel support performance optimization. Looks better to allocate Encapsulation objects on-demand when tunnels are discovered rather than always have an automatic, empty one for every packet. --- src/Conn.cc | 37 +++++++++++++++++++++--- src/Conn.h | 15 +++------- src/Sessions.cc | 64 +++++++++++++++++++++++++++--------------- src/Sessions.h | 7 +++-- src/Teredo.cc | 19 ++++++------- src/Tunnels.h | 8 ++++++ src/ayiya-analyzer.pac | 25 +++++++---------- 7 files changed, 110 insertions(+), 65 deletions(-) diff --git a/src/Conn.cc b/src/Conn.cc index 53abcc26eb..ec62a1b944 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -113,7 +113,7 @@ unsigned int Connection::external_connections = 0; IMPLEMENT_SERIAL(Connection, SER_CONNECTION); Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, - uint32 flow, const Encapsulation& arg_encap) + uint32 flow, const Encapsulation* arg_encap) { sessions = s; key = k; @@ -161,7 +161,10 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, uid = 0; // Will set later. - encapsulation = arg_encap; + if ( arg_encap ) + encapsulation = new Encapsulation(arg_encap); + else + encapsulation = 0; if ( conn_timer_mgr ) { @@ -190,12 +193,38 @@ Connection::~Connection() delete key; delete root_analyzer; delete conn_timer_mgr; + delete encapsulation; --current_connections; if ( conn_timer_mgr ) --external_connections; } +void Connection::CheckEncapsulation(const Encapsulation* arg_encap) + { + if ( encapsulation && arg_encap ) + { + if ( *encapsulation != *arg_encap ) + { + Event(tunnel_changed, 0, arg_encap->GetVectorVal()); + delete encapsulation; + encapsulation = new Encapsulation(arg_encap); + } + } + else if ( encapsulation ) + { + Encapsulation empty; + Event(tunnel_changed, 0, empty.GetVectorVal()); + delete encapsulation; + encapsulation = new Encapsulation(arg_encap); + } + else if ( arg_encap ) + { + Event(tunnel_changed, 0, arg_encap->GetVectorVal()); + encapsulation = new Encapsulation(arg_encap); + } + } + void Connection::Done() { finished = 1; @@ -352,8 +381,8 @@ RecordVal* Connection::BuildConnVal() char tmp[20]; conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62))); - if ( encapsulation.Depth() > 0 ) - conn_val->Assign(10, encapsulation.GetVectorVal()); + if ( encapsulation && encapsulation->Depth() > 0 ) + conn_val->Assign(10, encapsulation->GetVectorVal()); } if ( root_analyzer ) diff --git a/src/Conn.h b/src/Conn.h index b7911b84fb..f2efa2971d 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -52,17 +52,10 @@ class Analyzer; class Connection : public BroObj { public: Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, - uint32 flow, const Encapsulation& arg_encap); + uint32 flow, const Encapsulation* arg_encap); virtual ~Connection(); - void CheckEncapsulation(const Encapsulation& arg_encap) - { - if ( encapsulation != arg_encap ) - { - Event(tunnel_changed, 0, arg_encap.GetVectorVal()); - encapsulation = arg_encap; - } - } + void CheckEncapsulation(const Encapsulation* arg_encap); // Invoked when connection is about to be removed. Use Ref(this) // inside Done to keep the connection object around (though it'll @@ -254,7 +247,7 @@ public: uint64 GetUID() const { return uid; } - const Encapsulation& GetEncapsulation() const + const Encapsulation* GetEncapsulation() const { return encapsulation; } void CheckFlowLabel(bool is_orig, uint32 flow_label); @@ -294,7 +287,7 @@ protected: double inactivity_timeout; RecordVal* conn_val; LoginConn* login_conn; // either nil, or this - Encapsulation encapsulation; // tunnels + const Encapsulation* encapsulation; // tunnels int suppress_event; // suppress certain events to once per conn. unsigned int installed_status_timer:1; diff --git a/src/Sessions.cc b/src/Sessions.cc index 56df65d6af..5c825218d5 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -179,8 +179,6 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, if ( record_all_packets ) DumpPacket(hdr, pkt); - Encapsulation encapsulation; - if ( pkt_elem && pkt_elem->IPHdr() ) // Fast path for "normal" IP packets if an IP_Hdr is // already extracted when doing PacketSort. Otherwise @@ -188,7 +186,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, // difference here is that header extraction in // PacketSort does not generate Weird events. - DoNextPacket(t, hdr, pkt_elem->IPHdr(), pkt, hdr_size, encapsulation); + DoNextPacket(t, hdr, pkt_elem->IPHdr(), pkt, hdr_size, 0); else { @@ -213,7 +211,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, if ( ip->ip_v == 4 ) { IP_Hdr ip_hdr(ip, false); - DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, encapsulation); + DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0); } else if ( ip->ip_v == 6 ) @@ -225,7 +223,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr, } IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false, caplen); - DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, encapsulation); + DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size, 0); } else if ( ARP_Analyzer::IsARP(pkt, hdr_size) ) @@ -347,7 +345,7 @@ int NetSessions::CheckConnectionTag(Connection* conn) void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size, Encapsulation& encapsulation) + int hdr_size, const Encapsulation* encapsulation) { uint32 caplen = hdr->caplen - hdr_size; const struct ip* ip4 = ip_hdr->IP4_Hdr(); @@ -525,23 +523,19 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, case IPPROTO_IPV4: case IPPROTO_IPV6: { - if ( encapsulation.Depth() >= BifConst::Tunnel::max_depth ) + if ( encapsulation && + encapsulation->Depth() >= BifConst::Tunnel::max_depth ) { reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "tunnel_depth"); Remove(f); return; } - IP_Hdr* inner_ip; - if ( proto == IPPROTO_IPV6 ) - inner_ip = new IP_Hdr((const struct ip6_hdr*) data, false, caplen); - else - inner_ip = new IP_Hdr((const struct ip*) data, false); - - struct pcap_pkthdr fake_hdr; - fake_hdr.caplen = fake_hdr.len = caplen; - fake_hdr.ts = hdr->ts; + Encapsulation* outer = new Encapsulation(encapsulation); + // Look up to see if we've already seen this IP tunnel, identified + // by the pair of IP addresses, so that we can always associate the + // same UID with it. IPPair tunnel_idx; if ( ip_hdr->SrcAddr() < ip_hdr->DstAddr() ) tunnel_idx = IPPair(ip_hdr->SrcAddr(), ip_hdr->DstAddr()); @@ -555,21 +549,22 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), BifEnum::Tunnel::IP); ip_tunnels[tunnel_idx] = ec; - encapsulation.Add(ec); + outer->Add(ec); } else - encapsulation.Add(it->second); + outer->Add(it->second); - DoNextPacket(t, &fake_hdr, inner_ip, data, 0, encapsulation); + DoNextInnerPacket(t, hdr, caplen, data, proto, outer); - delete inner_ip; + delete outer; Remove(f); return; } case IPPROTO_NONE: { - if ( encapsulation.LastType() == BifEnum::Tunnel::TEREDO ) + if ( encapsulation && + encapsulation->LastType() == BifEnum::Tunnel::TEREDO ) { // TODO: raise bubble packet event } @@ -680,6 +675,31 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } } +void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, + int caplen, const u_char* pkt, int proto, + const Encapsulation* outer_encap) + { + IP_Hdr* inner_ip = 0; + + if ( proto == IPPROTO_IPV6 ) + inner_ip = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen); + else if ( proto == IPPROTO_IPV4 ) + inner_ip = new IP_Hdr((const struct ip*) pkt, false); + else + reporter->InternalError("Bad IP protocol version in DoNextInnerPacket"); + + struct pcap_pkthdr fake_hdr; + fake_hdr.caplen = fake_hdr.len = caplen; + if ( hdr ) + fake_hdr.ts = hdr->ts; + else + fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; + + DoNextPacket(t, &fake_hdr, inner_ip, pkt, 0, outer_encap); + + delete inner_ip; + } + bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, const struct pcap_pkthdr* h, const u_char* p) { @@ -1013,7 +1033,7 @@ void NetSessions::GetStats(SessionStats& s) const Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, const u_char* data, int proto, uint32 flow_label, - const Encapsulation& encapsulation) + const Encapsulation* encapsulation) { // FIXME: This should be cleaned up a bit, it's too protocol-specific. // But I'm not yet sure what the right abstraction for these things is. diff --git a/src/Sessions.h b/src/Sessions.h index e2bc0d704e..45c1e0750a 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -136,7 +136,10 @@ public: void DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size, Encapsulation& encapsulation); + int hdr_size, const Encapsulation* encapsulation); + + void DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, int caplen, + const u_char* pkt, int proto, const Encapsulation* outer_encap); unsigned int ConnectionMemoryUsage(); unsigned int ConnectionMemoryUsageConnVals(); @@ -150,7 +153,7 @@ protected: Connection* NewConn(HashKey* k, double t, const ConnID* id, const u_char* data, int proto, uint32 flow_lable, - const Encapsulation& encapsulation); + const Encapsulation* encapsulation); // Check whether the tag of the current packet is consistent with // the given connection. Returns: diff --git a/src/Teredo.cc b/src/Teredo.cc index 39ecef286f..08eb7d0d2b 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -92,7 +92,9 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - if ( Conn()->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth ) + const Encapsulation* e = Conn()->GetEncapsulation(); + + if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) { reporter->Weird(Conn(), "tunnel_depth"); return; @@ -107,20 +109,15 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, return; } - IP_Hdr inner_ip((const struct ip6_hdr*) te.InnerIP(), false, len); - ProtocolConfirmation(); // TODO: raise Teredo-specific events - struct pcap_pkthdr fake_hdr; - fake_hdr.caplen = fake_hdr.len = len; - fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; - - Encapsulation encap(Conn()->GetEncapsulation()); + Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO); - encap.Add(ec); + outer->Add(ec); - sessions->DoNextPacket(network_time, &fake_hdr, &inner_ip, te.InnerIP(), 0, - encap); + sessions->DoNextInnerPacket(network_time, 0, len, te.InnerIP(), + IPPROTO_IPV6, outer); + delete outer; } diff --git a/src/Tunnels.h b/src/Tunnels.h index 0f9c4f4107..3365c8d0ca 100644 --- a/src/Tunnels.h +++ b/src/Tunnels.h @@ -78,6 +78,14 @@ public: conns = 0; } + Encapsulation(const Encapsulation* other) + { + if ( other && other->conns ) + conns = new vector(*(other->conns)); + else + conns = 0; + } + Encapsulation& operator=(const Encapsulation& other) { if ( this == &other ) return *this; diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 1a91cb1229..2fb787a4e5 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -12,8 +12,9 @@ flow AYIYA_Flow function process_ayiya(pdu: PDU): bool %{ Connection *c = connection()->bro_analyzer()->Conn(); + const Encapsulation* e = c->GetEncapsulation(); - if ( c->GetEncapsulation().Depth() >= BifConst::Tunnel::max_depth ) + if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) { reporter->Weird(c, "tunnel_depth"); return false; @@ -25,12 +26,8 @@ flow AYIYA_Flow return false; } - IP_Hdr* inner_ip; - if ( ${pdu.next_header} == IPPROTO_IPV6 ) - inner_ip = new IP_Hdr((const struct ip6_hdr*) ${pdu.packet}.data(), false, ${pdu.packet}.length()); - else if ( ${pdu.next_header} == IPPROTO_IPV4 ) - inner_ip = new IP_Hdr((const struct ip*) ${pdu.packet}.data(), false); - else + if ( ${pdu.next_header} != IPPROTO_IPV6 && + ${pdu.next_header} != IPPROTO_IPV4 ) { reporter->Weird(c, "ayiya_tunnel_non_ip"); return false; @@ -38,17 +35,15 @@ flow AYIYA_Flow connection()->bro_analyzer()->ProtocolConfirmation(); - struct pcap_pkthdr fake_hdr; - fake_hdr.caplen = fake_hdr.len = ${pdu.packet}.length(); - fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; - - Encapsulation encap(c->GetEncapsulation()); + Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA); - encap.Add(ec); + outer->Add(ec); - sessions->DoNextPacket(network_time(), &fake_hdr, inner_ip, ${pdu.packet}.data(), 0, encap); + sessions->DoNextInnerPacket(network_time(), 0, ${pdu.packet}.length(), + ${pdu.packet}.data(), ${pdu.next_header}, + outer); - delete inner_ip; + delete outer; return true; %} From ae85bd1b957d6493764d8e3c1d6bec2143428bfb Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 4 Jun 2012 16:57:46 -0500 Subject: [PATCH 31/51] Suppress Teredo weirds unless decapsulation was successful once before. --- src/Analyzer.h | 5 +++++ src/Teredo.cc | 34 +++++++++++++++++----------------- src/Teredo.h | 20 +++++++++++++++++--- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/Analyzer.h b/src/Analyzer.h index 7797e215fe..ef596ac696 100644 --- a/src/Analyzer.h +++ b/src/Analyzer.h @@ -215,6 +215,11 @@ public: // analyzer, even if the method is called multiple times. virtual void ProtocolConfirmation(); + // Return whether the analyzer previously called ProtocolConfirmation() + // at least once before. + virtual bool ProtocolConfirmed() const + { return protocol_confirmed; } + // Report that we found a significant protocol violation which might // indicate that the analyzed data is in fact not the expected // protocol. The protocol_violation event is raised once per call to diff --git a/src/Teredo.cc b/src/Teredo.cc index 08eb7d0d2b..c97d4fb8af 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -13,7 +13,8 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, { if ( len < 2 ) { - reporter->Weird(conn, "truncated_Teredo"); + Weird("truncated_Teredo"); + return false; } uint16 tag = ntohs((*((const uint16*)data))); @@ -27,7 +28,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, if ( len < 8 ) { - reporter->Weird(conn, "truncated_Teredo_origin_indication"); + Weird("truncated_Teredo_origin_indication"); return false; } @@ -46,7 +47,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, if ( len < 4 ) { - reporter->Weird(conn, "truncated_Teredo_authentication"); + Weird("truncated_Teredo_authentication"); return false; } @@ -56,7 +57,7 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, if ( len < tot_len ) { - reporter->Weird(conn, "truncated_Teredo_authentication"); + Weird("truncated_Teredo_authentication"); return false; } @@ -70,13 +71,13 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, // IPv6 if ( len < 40 ) { - reporter->Weird(conn, "truncated_IPv6_in_Teredo"); + Weird("truncated_IPv6_in_Teredo"); return false; } if ( len - 40 != ntohs(((const struct ip6_hdr*)data)->ip6_plen) ) { - reporter->Weird(conn, "Teredo_payload_len_mismatch"); + Weird("Teredo_payload_len_mismatch"); return false; } @@ -92,25 +93,24 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - const Encapsulation* e = Conn()->GetEncapsulation(); - - if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) - { - reporter->Weird(Conn(), "tunnel_depth"); - return; - } - - TeredoEncapsulation te(Conn()); + TeredoEncapsulation te(this); if ( ! te.Parse(data, len) ) { - ProtocolViolation("Invalid Teredo encapsulation", (const char*)data, - len); + ProtocolViolation("Bad Teredo encapsulation", (const char*)data, len); return; } ProtocolConfirmation(); + const Encapsulation* e = Conn()->GetEncapsulation(); + + if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) + { + Weird("tunnel_depth"); + return; + } + // TODO: raise Teredo-specific events Encapsulation* outer = new Encapsulation(e); diff --git a/src/Teredo.h b/src/Teredo.h index 0662099233..d5422cdef4 100644 --- a/src/Teredo.h +++ b/src/Teredo.h @@ -24,6 +24,17 @@ public: //TODO: specific option to turn off Teredo analysis? { return BifConst::Tunnel::max_depth > 0; } + /** + * Emits a weird only if the analyzer has previously been able to + * decapsulate a Teredo packet since otherwise the weirds could happen + * frequently enough to be less than helpful. + */ + void Weird(const char* name) const + { + if ( ProtocolConfirmed() ) + reporter->Weird(Conn(), name); + } + protected: friend class AnalyzerTimer; void ExpireTimer(double t); @@ -31,8 +42,8 @@ protected: class TeredoEncapsulation { public: - TeredoEncapsulation(Connection* c) - : inner_ip(0), origin_indication(0), auth(0), conn(c) + TeredoEncapsulation(const Teredo_Analyzer* ta) + : inner_ip(0), origin_indication(0), auth(0), analyzer(ta) {} /** @@ -54,10 +65,13 @@ public: protected: bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au); + void Weird(const char* name) const + { analyzer->Weird(name); } + const u_char* inner_ip; const u_char* origin_indication; const u_char* auth; - Connection* conn; + const Teredo_Analyzer* analyzer; }; #endif From 8540c4d0cdc240cda422d5db323eff2d722c2b03 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 5 Jun 2012 09:58:44 -0500 Subject: [PATCH 32/51] Add more sanity checks before recursing on encapsulated IP packets. i.e. the IP protocol version and payload length get checked for consistency before attempting further analysis. --- src/Sessions.cc | 31 ++++++++++++++++++++++++++----- src/Sessions.h | 25 +++++++++++++++++++++++-- src/Teredo.cc | 15 ++++++++++----- src/ayiya-analyzer.pac | 39 +++++++++++++++++++++++++++++++++------ 4 files changed, 92 insertions(+), 18 deletions(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index 5c825218d5..d873b269fe 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -554,7 +554,13 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, else outer->Add(it->second); - DoNextInnerPacket(t, hdr, caplen, data, proto, outer); + int result = DoNextInnerPacket(t, hdr, caplen, data, proto, outer); + if ( result < 0 ) + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), + "truncated_inner_IP"); + else if ( result > 0 ) + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), + "inner_IP_payload_mismatch"); delete outer; Remove(f); @@ -675,19 +681,33 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } } -void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, - int caplen, const u_char* pkt, int proto, - const Encapsulation* outer_encap) +int NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, + int caplen, const u_char* const pkt, int proto, + const Encapsulation* outer) { IP_Hdr* inner_ip = 0; if ( proto == IPPROTO_IPV6 ) + { + if ( caplen < (int)sizeof(struct ip6_hdr) ) + return -1; inner_ip = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen); + } else if ( proto == IPPROTO_IPV4 ) + { + if ( caplen < (int)sizeof(struct ip) ) + return -1; inner_ip = new IP_Hdr((const struct ip*) pkt, false); + } else reporter->InternalError("Bad IP protocol version in DoNextInnerPacket"); + if ( (uint32)caplen != inner_ip->TotalLen() ) + { + delete inner_ip; + return (uint32)caplen < inner_ip->TotalLen() ? -1 : 1; + } + struct pcap_pkthdr fake_hdr; fake_hdr.caplen = fake_hdr.len = caplen; if ( hdr ) @@ -695,9 +715,10 @@ void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, else fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; - DoNextPacket(t, &fake_hdr, inner_ip, pkt, 0, outer_encap); + DoNextPacket(t, &fake_hdr, inner_ip, pkt, 0, outer); delete inner_ip; + return 0; } bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, diff --git a/src/Sessions.h b/src/Sessions.h index 45c1e0750a..c374dcb667 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -138,8 +138,29 @@ public: const IP_Hdr* ip_hdr, const u_char* const pkt, int hdr_size, const Encapsulation* encapsulation); - void DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, int caplen, - const u_char* pkt, int proto, const Encapsulation* outer_encap); + /** + * Wrapper that recurses on DoNextPacket for encapsulated IP packets, if + * they appear to be valid based on whether \a pkt is long enough to be an + * IP header and also that the payload length field of that header matches + * matches the actual length of \a pkt given by \a caplen. + * + * @param t Network time. + * @param hdr If the outer pcap header is available, this pointer can be set + * so that the fake pcap header passed to DoNextPacket will use + * the same timeval. The caplen and len fields of the fake pcap + * header are always set to \a caplen. + * @param caplen The length of \a pkt in bytes. + * @param pkt The inner IP packet data. + * @param proto Either IPPROTO_IPV6 or IPPROTO_IPV4 to indicate which IP + * protocol \a pkt corresponds to. + * @param outer_encap The encapsulation information for the inner IP packet. + * @return 0 If the inner IP packet was valid and passed to DoNextPacket, + * else -1 if the \a caplen was greater than the supposed IP + * packet's payload length field or 1 if \a caplen was less than + * the supposed IP packet's payload length. + */ + int DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, int caplen, + const u_char* const pkt, int proto, const Encapsulation* outer); unsigned int ConnectionMemoryUsage(); unsigned int ConnectionMemoryUsageConnVals(); diff --git a/src/Teredo.cc b/src/Teredo.cc index c97d4fb8af..c7131866f9 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -97,12 +97,10 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, if ( ! te.Parse(data, len) ) { - ProtocolViolation("Bad Teredo encapsulation", (const char*)data, len); + ProtocolViolation("Bad Teredo encapsulation", (const char*) data, len); return; } - ProtocolConfirmation(); - const Encapsulation* e = Conn()->GetEncapsulation(); if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) @@ -117,7 +115,14 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO); outer->Add(ec); - sessions->DoNextInnerPacket(network_time, 0, len, te.InnerIP(), - IPPROTO_IPV6, outer); + int result = sessions->DoNextInnerPacket(network_time, 0, len, te.InnerIP(), + IPPROTO_IPV6, outer); + if ( result == 0 ) + ProtocolConfirmation(); + else if ( result < 0 ) + ProtocolViolation("Truncated Teredo", (const char*) data, len); + else + ProtocolViolation("Teredo payload length", (const char*) data, len); + delete outer; } diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 2fb787a4e5..361d5f8c66 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -32,19 +32,46 @@ flow AYIYA_Flow reporter->Weird(c, "ayiya_tunnel_non_ip"); return false; } - - connection()->bro_analyzer()->ProtocolConfirmation(); + + if ( ${pdu.packet}.length() < (int)sizeof(struct ip) ) + { + connection()->bro_analyzer()->ProtocolViolation( + "Truncated AYIYA", (const char*) ${pdu.packet}.data(), + ${pdu.packet}.length()); + return false; + } + + const struct ip* ip = (const struct ip*) ${pdu.packet}.data(); + + if ( ( ${pdu.next_header} == IPPROTO_IPV6 && ip->ip_v != 6 ) || + ( ${pdu.next_header} == IPPROTO_IPV4 && ip->ip_v != 4) ) + { + connection()->bro_analyzer()->ProtocolViolation( + "AYIYA next header mismatch", (const char*)${pdu.packet}.data(), + ${pdu.packet}.length()); + return false; + } Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA); outer->Add(ec); - sessions->DoNextInnerPacket(network_time(), 0, ${pdu.packet}.length(), - ${pdu.packet}.data(), ${pdu.next_header}, - outer); + int result = sessions->DoNextInnerPacket(network_time(), 0, + ${pdu.packet}.length(), ${pdu.packet}.data(), + ${pdu.next_header}, outer); + if ( result == 0 ) + connection()->bro_analyzer()->ProtocolConfirmation(); + else if ( result < 0 ) + connection()->bro_analyzer()->ProtocolViolation( + "Truncated AYIYA", (const char*) ${pdu.packet}.data(), + ${pdu.packet}.length()); + else + connection()->bro_analyzer()->ProtocolViolation( + "AYIYA payload length", (const char*) ${pdu.packet}.data(), + ${pdu.packet}.length()); delete outer; - return true; + return (result == 0) ? true : false; %} }; From 976e8db1559f30d4733fa346515bc03247a20825 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 5 Jun 2012 10:17:41 -0500 Subject: [PATCH 33/51] Add independent options to toggle the different decapsulation methods --- scripts/base/init-bare.bro | 11 ++++++++++- src/AYIYA.h | 4 ++-- src/Sessions.cc | 7 +++++++ src/Teredo.h | 4 ++-- src/const.bif | 3 +++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 920f4a47c2..70905824f3 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2650,8 +2650,17 @@ const ignore_keep_alive_rexmit = F &redef; module Tunnel; export { ## The maximum depth of a tunnel to decapsulate until giving up. - ## Setting this to zero will disable tunnel decapsulation. + ## Setting this to zero will disable all types of tunnel decapsulation. const max_depth: count = 2 &redef; + + ## Toggle whether to do IPv{4,6}-in-IPv{4,6} decapsulation. + const enable_ip = T &redef; + + ## Toggle whether to do IPv{4,6}-in-AYIYA decapsulation. + const enable_ayiya = T &redef; + + ## Toggle whether to do IPv6-in-Teredo decapsulation. + const enable_teredo = T &redef; } # end export module GLOBAL; diff --git a/src/AYIYA.h b/src/AYIYA.h index 2122cafee6..79b41553c7 100644 --- a/src/AYIYA.h +++ b/src/AYIYA.h @@ -16,8 +16,8 @@ public: { return new AYIYA_Analyzer(conn); } static bool Available() - // TODO: specific option to turn off AYIYA analysis - { return BifConst::Tunnel::max_depth > 0; } + { return BifConst::Tunnel::enable_ayiya && + BifConst::Tunnel::max_depth > 0; } protected: friend class AnalyzerTimer; diff --git a/src/Sessions.cc b/src/Sessions.cc index d873b269fe..9738f380d7 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -523,6 +523,13 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, case IPPROTO_IPV4: case IPPROTO_IPV6: { + if ( ! BifConst::Tunnel::enable_ip ) + { + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "IP_tunnel"); + Remove(f); + return; + } + if ( encapsulation && encapsulation->Depth() >= BifConst::Tunnel::max_depth ) { diff --git a/src/Teredo.h b/src/Teredo.h index d5422cdef4..554e97f29a 100644 --- a/src/Teredo.h +++ b/src/Teredo.h @@ -21,8 +21,8 @@ public: { return new Teredo_Analyzer(conn); } static bool Available() - //TODO: specific option to turn off Teredo analysis? - { return BifConst::Tunnel::max_depth > 0; } + { return BifConst::Tunnel::enable_teredo && + BifConst::Tunnel::max_depth > 0; } /** * Emits a weird only if the analyzer has previously been able to diff --git a/src/const.bif b/src/const.bif index 553e8b6d58..3e8fe4b53b 100644 --- a/src/const.bif +++ b/src/const.bif @@ -12,5 +12,8 @@ const NFS3::return_data_max: count; const NFS3::return_data_first_only: bool; const Tunnel::max_depth: count; +const Tunnel::enable_ip: bool; +const Tunnel::enable_ayiya: bool; +const Tunnel::enable_teredo: bool; const Threading::heartbeat_interval: interval; From b52436a53bfc849afbab7b1ae9b1015736df230f Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 5 Jun 2012 12:23:16 -0500 Subject: [PATCH 34/51] Refactor some of the NetSessions routines that recurse on IP packets. Separating the IP packet validation/parsing from the recursive call to DoNextPacket to make it easier for analyzers to get access to the inner IP_Hdr. --- src/Sessions.cc | 102 ++++++++++++++++++++++++----------------- src/Sessions.h | 33 ++++++++----- src/Teredo.cc | 24 ++++++---- src/ayiya-analyzer.pac | 22 +++++---- 4 files changed, 110 insertions(+), 71 deletions(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index 9738f380d7..4e81ba1661 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -538,6 +538,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } + // Check for a valid inner packet first. + IP_Hdr* inner = 0; + int result = ParseIPPacket(caplen, data, proto, inner); + + if ( result < 0 ) + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), + "truncated_inner_IP"); + else if ( result > 0 ) + reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), + "inner_IP_payload_mismatch"); + + if ( result != 0 ) + { + Remove(f); + return; + } + Encapsulation* outer = new Encapsulation(encapsulation); // Look up to see if we've already seen this IP tunnel, identified @@ -561,14 +578,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, else outer->Add(it->second); - int result = DoNextInnerPacket(t, hdr, caplen, data, proto, outer); - if ( result < 0 ) - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - "truncated_inner_IP"); - else if ( result > 0 ) - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - "inner_IP_payload_mismatch"); + DoNextInnerPacket(t, hdr, inner, outer); + delete inner; delete outer; Remove(f); return; @@ -576,12 +588,11 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, case IPPROTO_NONE: { - if ( encapsulation && - encapsulation->LastType() == BifEnum::Tunnel::TEREDO ) - { - // TODO: raise bubble packet event - } - else + // If the packet is encapsulated in Teredo, then it was a bubble and + // the Teredo analyzer may have raised an event for that, else we're + // not sure the reason for the No Next header in the packet. + if ( ! ( encapsulation && + encapsulation->LastType() == BifEnum::Tunnel::TEREDO ) ) Weird("ipv6_no_next", hdr, pkt); Remove(f); @@ -688,43 +699,50 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } } -int NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, - int caplen, const u_char* const pkt, int proto, - const Encapsulation* outer) +void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, + const IP_Hdr* inner, const Encapsulation* outer) { - IP_Hdr* inner_ip = 0; - - if ( proto == IPPROTO_IPV6 ) - { - if ( caplen < (int)sizeof(struct ip6_hdr) ) - return -1; - inner_ip = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen); - } - else if ( proto == IPPROTO_IPV4 ) - { - if ( caplen < (int)sizeof(struct ip) ) - return -1; - inner_ip = new IP_Hdr((const struct ip*) pkt, false); - } - else - reporter->InternalError("Bad IP protocol version in DoNextInnerPacket"); - - if ( (uint32)caplen != inner_ip->TotalLen() ) - { - delete inner_ip; - return (uint32)caplen < inner_ip->TotalLen() ? -1 : 1; - } - struct pcap_pkthdr fake_hdr; - fake_hdr.caplen = fake_hdr.len = caplen; + fake_hdr.caplen = fake_hdr.len = inner->TotalLen(); if ( hdr ) fake_hdr.ts = hdr->ts; else fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; - DoNextPacket(t, &fake_hdr, inner_ip, pkt, 0, outer); + const u_char* pkt = 0; + if ( inner->IP4_Hdr() ) + pkt = (const u_char*) inner->IP4_Hdr(); + else + pkt = (const u_char*) inner->IP6_Hdr(); + + DoNextPacket(t, &fake_hdr, inner, pkt, 0, outer); + } + +int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto, + IP_Hdr*& inner) + { + if ( proto == IPPROTO_IPV6 ) + { + if ( caplen < (int)sizeof(struct ip6_hdr) ) + return -1; + inner = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen); + } + else if ( proto == IPPROTO_IPV4 ) + { + if ( caplen < (int)sizeof(struct ip) ) + return -1; + inner = new IP_Hdr((const struct ip*) pkt, false); + } + else + reporter->InternalError("Bad IP protocol version in DoNextInnerPacket"); + + if ( (uint32)caplen != inner->TotalLen() ) + { + delete inner; + inner = 0; + return (uint32)caplen < inner->TotalLen() ? -1 : 1; + } - delete inner_ip; return 0; } diff --git a/src/Sessions.h b/src/Sessions.h index c374dcb667..9273a02787 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -139,28 +139,37 @@ public: int hdr_size, const Encapsulation* encapsulation); /** - * Wrapper that recurses on DoNextPacket for encapsulated IP packets, if - * they appear to be valid based on whether \a pkt is long enough to be an - * IP header and also that the payload length field of that header matches - * matches the actual length of \a pkt given by \a caplen. + * Wrapper that recurses on DoNextPacket for encapsulated IP packets. * * @param t Network time. * @param hdr If the outer pcap header is available, this pointer can be set * so that the fake pcap header passed to DoNextPacket will use * the same timeval. The caplen and len fields of the fake pcap - * header are always set to \a caplen. + * header are always set to the TotalLength() of \a inner. + * @param outer The encapsulation information for the inner IP packet. + */ + void DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, + const IP_Hdr* inner, const Encapsulation* outer); + + /** + * Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4 + * or IPv6 header based on whether it's long enough to contain such a header + * and also that the payload length field of that header matches the actual + * length of \a pkt given by \a caplen. + * * @param caplen The length of \a pkt in bytes. * @param pkt The inner IP packet data. * @param proto Either IPPROTO_IPV6 or IPPROTO_IPV4 to indicate which IP * protocol \a pkt corresponds to. - * @param outer_encap The encapsulation information for the inner IP packet. - * @return 0 If the inner IP packet was valid and passed to DoNextPacket, - * else -1 if the \a caplen was greater than the supposed IP - * packet's payload length field or 1 if \a caplen was less than - * the supposed IP packet's payload length. + * @param inner The inner IP packet wrapper pointer to be allocated/assigned + * if \a pkt looks like a valid IP packet. + * @return 0 If the inner IP packet appeared valid in which case the caller + * is responsible for deallocating \a inner, else -1 if \a caplen + * is greater than the supposed IP packet's payload length field or + * 1 if \a caplen is less than the supposed packet's payload length. */ - int DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, int caplen, - const u_char* const pkt, int proto, const Encapsulation* outer); + int ParseIPPacket(int caplen, const u_char* const pkt, int proto, + IP_Hdr*& inner); unsigned int ConnectionMemoryUsage(); unsigned int ConnectionMemoryUsageConnVals(); diff --git a/src/Teredo.cc b/src/Teredo.cc index c7131866f9..92cdc7f64f 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -109,20 +109,26 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, return; } - // TODO: raise Teredo-specific events + IP_Hdr* inner = 0; + int rslt = sessions->ParseIPPacket(len, te.InnerIP(), IPPROTO_IPV6, inner); + + if ( rslt == 0 ) + ProtocolConfirmation(); + else if ( rslt < 0 ) + ProtocolViolation("Truncated Teredo", (const char*) data, len); + else + ProtocolViolation("Teredo payload length", (const char*) data, len); + + if ( rslt != 0 ) return; + + // TODO: raise Teredo-specific events for bubbles, origin/authentication Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO); outer->Add(ec); - int result = sessions->DoNextInnerPacket(network_time, 0, len, te.InnerIP(), - IPPROTO_IPV6, outer); - if ( result == 0 ) - ProtocolConfirmation(); - else if ( result < 0 ) - ProtocolViolation("Truncated Teredo", (const char*) data, len); - else - ProtocolViolation("Teredo payload length", (const char*) data, len); + sessions->DoNextInnerPacket(network_time, 0, inner, outer); + delete inner; delete outer; } diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index 361d5f8c66..a0b9de5926 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -51,14 +51,11 @@ flow AYIYA_Flow ${pdu.packet}.length()); return false; } - - Encapsulation* outer = new Encapsulation(e); - EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA); - outer->Add(ec); - - int result = sessions->DoNextInnerPacket(network_time(), 0, - ${pdu.packet}.length(), ${pdu.packet}.data(), - ${pdu.next_header}, outer); + + IP_Hdr* inner = 0; + int result = sessions->ParseIPPacket(${pdu.packet}.length(), + ${pdu.packet}.data(), ${pdu.next_header}, inner); + if ( result == 0 ) connection()->bro_analyzer()->ProtocolConfirmation(); else if ( result < 0 ) @@ -69,7 +66,16 @@ flow AYIYA_Flow connection()->bro_analyzer()->ProtocolViolation( "AYIYA payload length", (const char*) ${pdu.packet}.data(), ${pdu.packet}.length()); + + if ( result != 0 ) return false; + + Encapsulation* outer = new Encapsulation(e); + EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA); + outer->Add(ec); + sessions->DoNextInnerPacket(network_time(), 0, inner, outer); + + delete inner; delete outer; return (result == 0) ? true : false; %} From 854c6252753a2a5618c3cc3a86ddb7c3d06da68a Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 5 Jun 2012 15:07:56 -0500 Subject: [PATCH 35/51] Add Teredo-specific events. These are called "teredo_packet", "teredo_authentication", "teredo_origin_indication", and "teredo_bubble" and may be raised on a per-packet basis depending on Teredo encapsulation method. --- scripts/base/init-bare.bro | 36 ++++++++ src/Teredo.cc | 68 +++++++++++++- src/Teredo.h | 2 + src/event.bif | 55 ++++++++++++ .../Baseline/core.tunnels.teredo/conn.log | 28 ++++++ .../Baseline/core.tunnels.teredo/http.log | 11 +++ .../btest/Baseline/core.tunnels.teredo/output | 83 ++++++++++++++++++ .../Baseline/core.tunnels.teredo/tunnel.log | 13 +++ testing/btest/Traces/tunnels/Teredo.pcap | Bin 0 -> 26297 bytes testing/btest/core/tunnels/teredo.bro | 35 ++++++++ 10 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/core.tunnels.teredo/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.teredo/http.log create mode 100644 testing/btest/Baseline/core.tunnels.teredo/output create mode 100644 testing/btest/Baseline/core.tunnels.teredo/tunnel.log create mode 100644 testing/btest/Traces/tunnels/Teredo.pcap create mode 100644 testing/btest/core/tunnels/teredo.bro diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 70905824f3..5ca9cdf330 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -1347,6 +1347,42 @@ type pkt_hdr: record { icmp: icmp_hdr &optional; ##< The ICMP header if an ICMP packet. }; +## A Teredo origin indication header. See :rfc:`4380` for more information +## about the Teredo protocol. +## +## .. bro:see:: teredo_bubble teredo_origin_indication teredo_authentication +## teredo_hdr +type teredo_auth: record { + id: string; ##< Teredo client identifier. + value: string; ##< HMAC-SHA1 over shared secret key between client and + ##< server, nonce, confirmation byte, origin indication + ##< (if present), and the IPv6 packet. + nonce: count; ##< Nonce chosen by Teredo client to be repeated by + ##< Teredo server. + confirm: count; ##< Confirmation byte to be set to 0 by Teredo client + ##< and non-zero by server if client needs new key. +}; + +## A Teredo authentication header. See :rfc:`4380` for more information +## about the Teredo protocol. +## +## .. bro:see:: teredo_bubble teredo_origin_indication teredo_authentication +## teredo_hdr +type teredo_origin: record { + p: port; ##< Unobfuscated UDP port of Teredo client. + a: addr; ##< Unobfuscated IPv4 address of Teredo client. +}; + +## A Teredo packet header. See :rfc:`4380` for more information about the +## Teredo protocol. +## +## .. bro:see:: teredo_bubble teredo_origin_indication teredo_authentication +type teredo_hdr: record { + auth: teredo_auth &optional; ##< Teredo authentication header. + origin: teredo_origin &optional; ##< Teredo origin indication header. + hdr: pkt_hdr; ##< IPv6 and transport protocol headers. +}; + ## Definition of "secondary filters". A secondary filter is a BPF filter given as ## index in this table. For each such filter, the corresponding event is raised for ## all matching packets. diff --git a/src/Teredo.cc b/src/Teredo.cc index 92cdc7f64f..945e54ee18 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -88,6 +88,51 @@ bool TeredoEncapsulation::DoParse(const u_char* data, int& len, return false; } +RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const + { + static RecordType* teredo_hdr_type = 0; + static RecordType* teredo_auth_type = 0; + static RecordType* teredo_origin_type = 0; + + if ( ! teredo_hdr_type ) + { + teredo_hdr_type = internal_type("teredo_hdr")->AsRecordType(); + teredo_auth_type = internal_type("teredo_auth")->AsRecordType(); + teredo_origin_type = internal_type("teredo_origin")->AsRecordType(); + } + + RecordVal* teredo_hdr = new RecordVal(teredo_hdr_type); + + if ( auth ) + { + RecordVal* teredo_auth = new RecordVal(teredo_auth_type); + uint8 id_len = *((uint8*)(auth + 2)); + uint8 au_len = *((uint8*)(auth + 3)); + uint64 nonce = ntohll(*((uint64*)(auth + 4 + id_len + au_len))); + uint8 conf = *((uint8*)(auth + 4 + id_len + au_len + 8)); + teredo_auth->Assign(0, new StringVal( + new BroString(auth + 4, id_len, 1))); + teredo_auth->Assign(1, new StringVal( + new BroString(auth + 4 + id_len, au_len, 1))); + teredo_auth->Assign(2, new Val(nonce, TYPE_COUNT)); + teredo_auth->Assign(3, new Val(conf, TYPE_COUNT)); + teredo_hdr->Assign(0, teredo_auth); + } + + if ( origin_indication ) + { + RecordVal* teredo_origin = new RecordVal(teredo_origin_type); + uint16 port = ntohs(*((uint16*)(origin_indication + 2))) ^ 0xFFFF; + uint32 addr = ntohl(*((uint32*)(origin_indication + 4))) ^ 0xFFFFFFFF; + teredo_origin->Assign(0, new PortVal(port, TRANSPORT_UDP)); + teredo_origin->Assign(1, new AddrVal(htonl(addr))); + teredo_hdr->Assign(1, teredo_origin); + } + + teredo_hdr->Assign(2, inner->BuildPktHdrVal()); + return teredo_hdr; + } + void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) { @@ -121,7 +166,28 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, if ( rslt != 0 ) return; - // TODO: raise Teredo-specific events for bubbles, origin/authentication + Val* teredo_hdr = 0; + + if ( teredo_packet ) + { + teredo_hdr = te.BuildVal(inner); + Conn()->Event(teredo_packet, 0, teredo_hdr); + } + if ( te.Authentication() && teredo_authentication ) + { + teredo_hdr = teredo_hdr ? teredo_hdr->Ref() : te.BuildVal(inner); + Conn()->Event(teredo_authentication, 0, teredo_hdr); + } + if ( te.OriginIndication() && teredo_origin_indication ) + { + teredo_hdr = teredo_hdr ? teredo_hdr->Ref() : te.BuildVal(inner); + Conn()->Event(teredo_origin_indication, 0, teredo_hdr); + } + if ( inner->NextProto() == IPPROTO_NONE && teredo_bubble ) + { + teredo_hdr = teredo_hdr ? teredo_hdr->Ref() : te.BuildVal(inner); + Conn()->Event(teredo_bubble, 0, teredo_hdr); + } Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO); diff --git a/src/Teredo.h b/src/Teredo.h index 554e97f29a..84ff8ddf38 100644 --- a/src/Teredo.h +++ b/src/Teredo.h @@ -62,6 +62,8 @@ public: const u_char* Authentication() const { return auth; } + RecordVal* BuildVal(const IP_Hdr* inner) const; + protected: bool DoParse(const u_char* data, int& len, bool found_orig, bool found_au); diff --git a/src/event.bif b/src/event.bif index c4ed03e013..8d39af0ba2 100644 --- a/src/event.bif +++ b/src/event.bif @@ -511,6 +511,61 @@ event esp_packet%(p: pkt_hdr%); ## .. bro:see:: new_packet tcp_packet ipv6_ext_headers event mobile_ipv6_message%(p: pkt_hdr%); +## Genereated for any IPv6 packet encapsulated in a Teredo tunnel. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_authentication teredo_origin_indication teredo_bubble +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particular expensive for real-time analysis. +event teredo_packet%(outer: connection, inner: teredo_hdr%); + +## Genereated for IPv6 packets encapsulated in a Teredo tunnel that +## use the Teredo authentication encapsulation method. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_packet teredo_origin_indication teredo_bubble +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particular expensive for real-time analysis. +event teredo_authentication%(outer: connection, inner: teredo_hdr%); + +## Genereated for IPv6 packets encapsulated in a Teredo tunnel that +## use the Teredo origin indication encapsulation method. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_packet teredo_authentication teredo_bubble +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particular expensive for real-time analysis. +event teredo_origin_indication%(outer: connection, inner: teredo_hdr%); + +## Genereated for Teredo bubble packets. That is, IPv6 packets encapsulated +## in a Teredo tunnel that have a Next Header value of :bro:id:`IPPROTO_NONE`. +## See :rfc:`4380` for more information about the Teredo protocol. +## +## outer: The Teredo tunnel connection. +## +## inner: The Teredo-encapsulated IPv6 packet header and transport header. +## +## .. bro:see:: teredo_packet teredo_authentication teredo_origin_indication +## +## .. note:: Since this event may be raised on a per-packet basis, handling +## it may become particular expensive for real-time analysis. +event teredo_bubble%(outer: connection, inner: teredo_hdr%); + ## Generated for every packet that has non-empty transport-layer payload. This is a ## very low-level and expensive event that should be avoided when at all possible. ## It's usually infeasible to handle when processing even medium volumes of diff --git a/testing/btest/Baseline/core.tunnels.teredo/conn.log b/testing/btest/Baseline/core.tunnels.teredo/conn.log new file mode 100644 index 0000000000..151230886b --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.teredo/conn.log @@ -0,0 +1,28 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1210953047.736921 arKYeMETxOg 192.168.2.16 1576 75.126.130.163 80 tcp - 0.000357 0 0 SHR - 0 fA 1 40 1 40 (empty) +1210953050.867067 k6kgXLOoSKl 192.168.2.16 1577 75.126.203.78 80 tcp - 0.000387 0 0 SHR - 0 fA 1 40 1 40 (empty) +1210953057.833364 5OKnoww6xl4 192.168.2.16 1577 75.126.203.78 80 tcp - 0.079208 0 0 SH - 0 Fa 1 40 1 40 (empty) +1210953058.007081 VW0XPVINV8a 192.168.2.16 1576 75.126.130.163 80 tcp - - - - RSTOS0 - 0 R 1 40 0 0 (empty) +1210953057.834454 3PKsZ2Uye21 192.168.2.16 1578 75.126.203.78 80 tcp http 0.407908 790 171 RSTO - 0 ShADadR 6 1038 4 335 (empty) +1210953058.350065 fRFu0wcOle6 192.168.2.16 1920 192.168.2.1 53 udp dns 0.223055 66 438 SF - 0 Dd 2 122 2 494 (empty) +1210953058.577231 qSsw6ESzHV4 192.168.2.16 137 192.168.2.255 137 udp dns 1.499261 150 0 S0 - 0 D 3 234 0 0 (empty) +1210953074.264819 Tw8jXtpTGu6 192.168.2.16 1920 192.168.2.1 53 udp dns 0.297723 123 598 SF - 0 Dd 3 207 3 682 (empty) +1210953061.312379 70MGiRM1Qf4 2001:0:4137:9e50:8000:f12a:b9c8:2815 1286 2001:4860:0:2001::68 80 tcp http 12.810848 1675 10467 S1 - 0 ShADad 10 2279 12 11191 GSxOnSLghOa +1210953076.058333 EAr0uf4mhq 192.168.2.16 1578 75.126.203.78 80 tcp - - - - RSTRH - 0 r 0 0 1 40 (empty) +1210953074.055744 h5DsfNtYzi1 192.168.2.16 1577 75.126.203.78 80 tcp - - - - RSTRH - 0 r 0 0 1 40 (empty) +1210953074.057124 P654jzLoe3a 192.168.2.16 1576 75.126.130.163 80 tcp - - - - RSTRH - 0 r 0 0 1 40 (empty) +1210953074.570439 c4Zw9TmAE05 192.168.2.16 1580 67.228.110.120 80 tcp http 0.466677 469 3916 SF - 0 ShADadFf 7 757 6 4164 (empty) +1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 udp teredo 8.928880 129 48 SF - 0 Dd 2 185 1 76 (empty) +1210953060.829233 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 udp teredo 13.293994 2359 11243 SF - 0 Dd 12 2695 13 11607 (empty) +1210953058.933954 iE6yhOq3SF 0.0.0.0 68 255.255.255.255 67 udp - - - - S0 - 0 D 1 328 0 0 (empty) +1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 udp teredo - - - SHR - 0 d 0 0 1 137 (empty) +1210953046.591933 UWkUyAuUGXf 192.168.2.16 138 192.168.2.255 138 udp - 28.448321 416 0 S0 - 0 D 2 472 0 0 (empty) +1210953052.324629 FrJExwHcSal fe80::8000:f227:bec8:61af 134 fe80::8000:ffff:ffff:fffd 133 icmp - - - - OTH - 0 - 1 88 0 0 TEfuqmmG4bh +1210953060.829303 qCaWGmzFtM5 2001:0:4137:9e50:8000:f12a:b9c8:2815 128 2001:4860:0:2001::68 129 icmp - 0.463615 4 4 OTH - 0 - 1 52 1 52 GSxOnSLghOa,nQcgTWjvg4c +1210953052.202579 j4u32Pc5bif fe80::8000:ffff:ffff:fffd 133 ff02::2 134 icmp - - - - OTH - 0 - 1 64 0 0 nQcgTWjvg4c diff --git a/testing/btest/Baseline/core.tunnels.teredo/http.log b/testing/btest/Baseline/core.tunnels.teredo/http.log new file mode 100644 index 0000000000..b3cf832083 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.teredo/http.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1210953057.917183 3PKsZ2Uye21 192.168.2.16 1578 75.126.203.78 80 1 POST download913.avast.com /cgi-bin/iavs4stats.cgi - Syncer/4.80 (av_pro-1169;f) 589 0 204 - - - (empty) - - - text/plain - - +1210953061.585996 70MGiRM1Qf4 2001:0:4137:9e50:8000:f12a:b9c8:2815 1286 2001:4860:0:2001::68 80 1 GET ipv6.google.com / - Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5 0 6640 200 OK - - - (empty) - - - text/html - - +1210953073.381474 70MGiRM1Qf4 2001:0:4137:9e50:8000:f12a:b9c8:2815 1286 2001:4860:0:2001::68 80 2 GET ipv6.google.com /search?hl=en&q=Wireshark+!&btnG=Google+Search http://ipv6.google.com/ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5 0 25119 200 OK - - - (empty) - - - text/html - - +1210953074.674817 c4Zw9TmAE05 192.168.2.16 1580 67.228.110.120 80 1 GET www.wireshark.org / http://ipv6.google.com/search?hl=en&q=Wireshark+%21&btnG=Google+Search Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5 0 11845 200 OK - - - (empty) - - - text/xml - - diff --git a/testing/btest/Baseline/core.tunnels.teredo/output b/testing/btest/Baseline/core.tunnels.teredo/output new file mode 100644 index 0000000000..02d5a41e74 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.teredo/output @@ -0,0 +1,83 @@ +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=24, nxt=58, hlim=255, src=fe80::8000:ffff:ffff:fffd, dst=ff02::2, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] +auth: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=24, nxt=58, hlim=255, src=fe80::8000:ffff:ffff:fffd, dst=ff02::2, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.81, resp_p=3544/udp] + ip6: [class=0, flow=0, len=48, nxt=58, hlim=255, src=fe80::8000:f227:bec8:61af, dst=fe80::8000:ffff:ffff:fffd, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] + origin: [p=3797/udp, a=70.55.215.234] +auth: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.81, resp_p=3544/udp] + ip6: [class=0, flow=0, len=48, nxt=58, hlim=255, src=fe80::8000:f227:bec8:61af, dst=fe80::8000:ffff:ffff:fffd, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] + origin: [p=3797/udp, a=70.55.215.234] +origin: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.81, resp_p=3544/udp] + ip6: [class=0, flow=0, len=48, nxt=58, hlim=255, src=fe80::8000:f227:bec8:61af, dst=fe80::8000:ffff:ffff:fffd, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] + origin: [p=3797/udp, a=70.55.215.234] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=21, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +bubble: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=21, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=12, nxt=58, hlim=21, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=fe80::708d:fe83:4114:a512, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] + origin: [p=32900/udp, a=83.170.1.38] +origin: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=fe80::708d:fe83:4114:a512, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] + origin: [p=32900/udp, a=83.170.1.38] +bubble: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=fe80::708d:fe83:4114:a512, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] + origin: [p=32900/udp, a=83.170.1.38] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=fe80::708d:fe83:4114:a512, exts=[]] +bubble: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=fe80::708d:fe83:4114:a512, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=12, nxt=58, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=24, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=24, nxt=6, hlim=245, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=817, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=514, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=898, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=812, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=717, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] diff --git a/testing/btest/Baseline/core.tunnels.teredo/tunnel.log b/testing/btest/Baseline/core.tunnels.teredo/tunnel.log new file mode 100644 index 0000000000..5549d66a29 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.teredo/tunnel.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user +#types time string addr port addr port enum enum string +1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO - +1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO - +1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO - +1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO - +1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO - +1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO - diff --git a/testing/btest/Traces/tunnels/Teredo.pcap b/testing/btest/Traces/tunnels/Teredo.pcap new file mode 100644 index 0000000000000000000000000000000000000000..2eff14469d6edb8f411e072b20f8dcd744b9faf3 GIT binary patch literal 26297 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 +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff tunnel.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.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); + } From 727b7783f94d138e23026ece7424bfad7ca42229 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 5 Jun 2012 15:17:27 -0500 Subject: [PATCH 36/51] Add AYIYA tunnel decapsulation unit test. --- .../btest/Baseline/core.tunnels.ayiya/conn.log | 15 +++++++++++++++ .../btest/Baseline/core.tunnels.ayiya/http.log | 10 ++++++++++ .../Baseline/core.tunnels.ayiya/tunnel.log | 11 +++++++++++ testing/btest/Traces/tunnels/ayiya3.trace | Bin 0 -> 13440 bytes testing/btest/core/tunnels/ayiya.test | 4 ++++ 5 files changed, 40 insertions(+) create mode 100644 testing/btest/Baseline/core.tunnels.ayiya/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.ayiya/http.log create mode 100644 testing/btest/Baseline/core.tunnels.ayiya/tunnel.log create mode 100644 testing/btest/Traces/tunnels/ayiya3.trace create mode 100644 testing/btest/core/tunnels/ayiya.test diff --git a/testing/btest/Baseline/core.tunnels.ayiya/conn.log b/testing/btest/Baseline/core.tunnels.ayiya/conn.log new file mode 100644 index 0000000000..5c23b4c404 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.ayiya/conn.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1257655301.595604 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 tcp http 2.101052 2981 4665 S1 - 0 ShADad 10 3605 11 5329 k6kgXLOoSKl +1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 udp ayiya 20.879001 5129 6109 SF - 0 Dd 21 5717 13 6473 (empty) +1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 udp ayiya - - - SHR - 0 d 0 0 1 176 (empty) +1257655296.585333 FrJExwHcSal :: 135 ff02::1:ff00:2 136 icmp - - - - OTH - 0 - 1 64 0 0 k6kgXLOoSKl +1257655293.629048 arKYeMETxOg 2001:4978:f:4c::1 128 2001:4978:f:4c::2 129 icmp - 23.834987 168 56 OTH - 0 - 3 312 1 104 UWkUyAuUGXf,k6kgXLOoSKl +1257655296.585188 TEfuqmmG4bh fe80::216:cbff:fe9a:4cb9 131 ff02::1:ff00:2 130 icmp - 0.919988 32 0 OTH - 0 - 2 144 0 0 k6kgXLOoSKl +1257655296.585151 j4u32Pc5bif fe80::216:cbff:fe9a:4cb9 131 ff02::2:f901:d225 130 icmp - 0.719947 32 0 OTH - 0 - 2 144 0 0 k6kgXLOoSKl +1257655296.585034 nQcgTWjvg4c fe80::216:cbff:fe9a:4cb9 131 ff02::1:ff9a:4cb9 130 icmp - 4.922880 32 0 OTH - 0 - 2 144 0 0 k6kgXLOoSKl diff --git a/testing/btest/Baseline/core.tunnels.ayiya/http.log b/testing/btest/Baseline/core.tunnels.ayiya/http.log new file mode 100644 index 0000000000..7cef1a1b8e --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.ayiya/http.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1257655301.652206 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 1 GET ipv6.google.com / - Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en; rv:1.9.0.15pre) Gecko/2009091516 Camino/2.0b4 (like Firefox/3.0.15pre) 0 10102 200 OK - - - (empty) - - - text/html - - +1257655302.514424 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 2 GET ipv6.google.com /csi?v=3&s=webhp&action=&tran=undefined&e=17259,19771,21517,21766,21887,22212&ei=BUz2Su7PMJTglQfz3NzCAw&rt=prt.77,xjs.565,ol.645 http://ipv6.google.com/ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en; rv:1.9.0.15pre) Gecko/2009091516 Camino/2.0b4 (like Firefox/3.0.15pre) 0 0 204 No Content - - - (empty) - - - - - - +1257655303.603569 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 3 GET ipv6.google.com /gen_204?atyp=i&ct=fade&cad=1254&ei=BUz2Su7PMJTglQfz3NzCAw&zx=1257655303600 http://ipv6.google.com/ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en; rv:1.9.0.15pre) Gecko/2009091516 Camino/2.0b4 (like Firefox/3.0.15pre) 0 0 204 No Content - - - (empty) - - - - - - diff --git a/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log b/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log new file mode 100644 index 0000000000..69e331b477 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user +#types time string addr port addr port enum enum string +1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - +1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - +1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - +1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - diff --git a/testing/btest/Traces/tunnels/ayiya3.trace b/testing/btest/Traces/tunnels/ayiya3.trace new file mode 100644 index 0000000000000000000000000000000000000000..83193050dcf1160bfbee5c947567bd37b0094249 GIT binary patch literal 13440 zcmeI3c{r5a|Ho%6*|JMYYIsVLnK5P`Ci}kcTV=)=3}cKjV@s4MNm7YODJp40rHw+- zN<@XS6e%jAM2YGE9Pzka{p_r4t0J@+~HIj^(5KWEP8%#+&}j`2YRAV05( z2?zuVd>FSJwjgARKyCu}V1O+CWEF*lELi293loMILm)*Eh#mwZZ6?+%;VoZrik~i9 z->?#rohG2~Aic(7*m4{OHIINuLae}-feZTT;cfB68-nUB%8kkcw=??V_nrMh0b}$? zdb88c`pmZla>RPV!V1C%BnQbV3&g-T=YLrZTUhi7LyiD%fMKd0Q+1lGO=|a207N=N z3aklOqXwF6JtX>J?Nn{7AhU_~Fi&I#!HSvgC8wi9? z{^7)rEURl1AokP+od7Wm}>m&2)vua_(O0dl|=DQY%COi~ch$6d1aE|Iqqh0$=%sb}}BM<@F0g(t$WI z{5BF2qnCrUkVP|Sxx6ED(Nf}?GaN2A4hc#t2XuTP=pMtkTMYj`UgcZwWeK+4%j-!*$2JQ2 zM#?unP6kUMS^lY%QcJLu%GLjADIR|;C0-XSDFq7D5A) zpWt-ALTC3u)g7U)_K~JzapRrtl~Ou#xlCsV3fLEa9)k=~iK z^+I#eKDcmqMT%G@u%_v3x=)Hgac8Hy)`b~2Xq=;`~ zg5?N^lz>1Ll%F38g$j$3j;c)B00H0~klb-l^*`aIapyY#4HC}A`mL_~90P?L`ZS+$w&!%#cQf}Vu zYXOkP+DT1Jw0xRs$Mc^>AP8Vt1BTgz0x)C@NNBF~E1|%`qOiFL#ZM<7uE^N88My7r z8GBig(RU{;1SI4y`j>HU(BMd-BYif#%8V0ji zbQ)NF5-bpmq=J#)^WZ=RkjT!#*o16uL`I_snp7WeEi8_PLu;YvBxf=aL%`8}wdi;) z8jeoHp-E2GWRw;bgCc4X@tP#7sZUy3XdDhlawL13yIM!u8l!QxI3M32Zh$t-2FO>7 zK;{?)G0jc9-FYEqk(z94j*B5XD#F^=5^v9p4E8s`=(9p1jo9I#R=y}-Lkm}rs6ZEE z78~vq6>4Pd>cRE1u=l{2YuRG0*j@pwU>ACxOk&!K4>pD znzO%+8xiki8t&q+MQ{o*wehy%618ED0Em&jzP`R02KZ;B>1^UnbJFyHvvI~KILE*g zhcR(OhgcK6*aUq`lp)H9=g+_}>>a6eb4TY;jz5hSLJKg1Te;fPEkZ1#>=;HKgg|GE zdx)VH#?{Xx3eSynB~YE%5hiFR9Si5$I$N{-XjGa%&&1Wt7sv6^H^F!_Oxgaya28N3 zA>2HS?e6M1)HxKzRKSTA%@y z7;GC5$+h7++F6T>ii?8!mf#@vkG{=T;rMA4#?Me;HqUVm^?-JKu@D~WX;mI7fQuyg zKZ-ab^$ACzncjHX+S$+xan6yL5=4| za}gqUEv?%k{T5EKzrYT>lAjkJqpS-O3e+$7*MyN@AdsKR1_QJPW@{-fY6MI>63mgu z(tv3aU^c;FUKdwIshS9_Tue!nA93A0yoM7(H*$$K|F1liuFwi=HJ)Ag43JgDV{X)n0 zwQ4s?YT=c8%BTrA(t z$2I=G7|HuWh2u|TKPLz5Jy?~;&n&@Y9(S}^-3#XpX>%QEkvv zNLF3=rF6@J8<`h8O-CAx>W!E%=!UgXDTtoKJu0g_KdbBuRnIPeq#N`Bs#0lWWty{U zbldrNN^GQGrb4Y-XFl5UahQBp*ZyNaUKM_?Y~hZ)=>7PXI!3ZbLy|i?5XnjZjM}yMRi~N1<%gZDej6*AyA3nTnLb2$!;JC5>gCpH+hVRPb zesRKj!waM)hUupojqrug%~~H04Qd`#JwjnLpyVz0<4XHAZOCyO)~e_Plq_v)lE|&; zd{updIJo^rcSFq6f?COjvQSG-ZFtm4zfF%4Y@*wqY>>=aI3bJ~AsD?*Wtzpqam#c& z+LRZ@Tq|!vBFDl%B7$hfRap6iz3aWMW;{Bx^b4o;f%n=&pH79o%33LzFRLjL!_deu zxr;uE`rs;lz*8q=XbCUR>dK)N0*C6ewRaI#{a`C^7ekmKwjYjvbZHNadRw%BAaqoM z;`Ll52bm?T^(u}37Wt+u#@4JgfUI=UF7R!|bD63>Zb>*iyN(HDxiV*qz$&J)+7mmvsN1SvEYivf=cLnSa(X{P6 zu_#pe)$6QFcR#e$cDwVZ-iOx;el{!9_m)>R{BnQeg_Vbr?s&M%KqaFm0{EW)Jno!^ z?do2Y+Qhq6(ajev4^nR3=A|MA?@*7}$i{wE73SL_xnUoYPtzHd%z#-8FW`4F=`kr< z*o34b8ko&O#|AOJH;3=M7zy7NW1TSW-H=<+aPeXqy4ByX^Vac#qqt55=2n<*&Em&J z9q(@#BNU3>tJERx`hJRce$65q40I&;z7}OI@k8vghe?0loYg#{ShTuFso@=#VV!i~ zoD03MM(ms&+}_X;zEq1X(sr)v1HX;1T_hv_MBmZKr*iAN(5Ag=Er+UGv!w9)gjJya z?|=R8)wL2am%8pKmMA^6wv_$O()(e&hK+=bmD@OaL{{QFzzSTH%uGLX{ zxh{Yn8j{0zAcj$V?Rgc&Sy<~7^RA$u4no@Ed&5epy@^Fi_re@6dzOrkB)-$LKk$B_ zAmdF#_1YI{{@bOiddiLwTRQ~}?7Wqf34is*OYFPUdtf8x^UWJst>6w^cJ&C_v4OX8Y2A-g+Pl+UZyeef zYkFEAt9>tfS8NGlqEs>KI;*VFQ$|TM+YwbOd#-%FeDDqW=KD*|e&yvSid6^rq-_*G z=Cp-(zSDuUNGaQoH4?Qz;Jr$E&Ee_>MEl2V^>_#L+1#G7IFFigE`l;};q_V=D&nn{ z*&B3mmZep|f;S~ZoFN*w`VQYV<-`L78)?4Xf@`)Z-$+Ph4z_BitTFN1Bwu_mZejPr z0_EGaYnHsIQkGg8y5(EeDEFGv=*gWzH_CtL5G^W2WxtLN=v_0_Qg4(!-VW^-}a!Trh9!Td%9rL+rl3)$r!BrCr*v zG^IMXHNz9_$8a4I>&*N`Ia zWA9W0Z##d(*N%232Oe$_lifpc8%T0l z4=|(x_qsyL_EiQHsz`6jjR*SI)vfP7(GNB3UAc@a)3dt%F5zX|K+b~5du}`(+fwHn zeSPa%Lb16~`Y>ptfFt5wPi5jp*T};!0`#4gKNHs$vCcwB%N&rambkUc;5mY~R8t*8 z`1hB{M)xWBb8Je_tmDdZHZ97hUJs<3H$TG;)IWe~AIgfdudHi{ABCnvea$d$w3qv3 zaXoCvr?x3r9DT42ieLL?cM?i2Z57JxjMUpp&dGsI0uSS|txl!ub=BN@PZ4()&p7`6 zK$UtFO3qHx;`6dg#YyJB>Y21nxT@;r^LmN7q80LD{yRe{Hi?uoHp;( zP77RyD)0ZEqN)TBToE$?^{Mid}f7>84%*lUr(=R#d+< z^N73pGTqK;V@+9c6{~F^B~bw%(0oEND z3wJ4Ua(b{%IfI`I2ky&AhcgyDIoLvh(X9>K%mVNqA#(icarZy_p@eHULWK4}~u`7Dk3 zb)Sz=UY*QCkI1VG66Gf{fGh86*BMLgUUBV9$^I7Jvdd1 zomyRo_WyhR&vclB5Zbx|lBBnPiy@HZPC-0_ zBO47Pohr^%XX*#l-A}&GtFb3B{3qVfZp~_t4 z)OvURuCkOtTaimKo+$ksdf>&B*9(;=_+17abFSS=l5jB0$uHq>(AGi5*Y(bOUwxNm zBN^y#eMF5Ak!vS7DxHRrPSXw<+ha$Hg~4x+-?msvKbcda_2FXCfwq0kEzCATUD5KJ zZDVrP!Fb(<*L{>7`Hii4^)#wZ`jXLC`5&81y>yj^M`EJI48ofx{`w|87E-?HisGruvW-{%(Nho?Wc@nBsuWO~}i!IN_V$P#I9>ai4bPtuA#W zZDs0NrPC~>GYxxOAnR`ZNVZSEn5V*XzU!*H&F(G!#+~I25<2y3YF(EgT%dVxP8q~s zS)nOrTG1b>Am~mwipgHIBhza?HKdB&#eSfCEcULkO+m#dHX(}8k*K8+wpsUN>KDW3 zYab>cT*zgf25!n?NlN(UmS;)1ez9JTLjE?AN$68Mu0*LcNbHYqYslUoeg4GOFx7$p zzkTXXb`gc2EK{$_P;%8hlT>gvv@%Yj^Iik?w|A0tXY_-5D5ss@pVkyTS_4D)Kg|nS zzbpk>*W4BHD4q!QmJ7YeOOzXd8b0w2jX(>G3{py6i#Np2S6! zYR?8b@7sS_nwy}czkfmUrc#v0oF1f2F=dw ze5w~UZ9`{=cmHdzMR(SW4EGc%z?*RY2)efrN;}FAs6zS>ey%ctxAgt3Qym=_p8(*d%lSA zib|EIQRUqXVfs~$uA;|g*SA*|wyIc-Y6?a?xE8kE@3n$gj-IR2diE9h_EU17&)RPzzA&p= zXQ|1Z2bE#t%leATeBV_qmh7XXI2QNoUsv<5BoAohmxwEFNs>jV7cMF+Q`_Rcs)E(4T!CIJi6)qw&*C&9Sd_9gRebTycrlHydddh@kWL(1iLC~zxw)4fm@(kXsPt&n4+Yl z?&FoHbX8`d>)OYp@pqh~QsvieVxykg=md5S^*PraC}0F_ITs;TGy3XW3+v&;`2H0+ z_iKNA4W1aN8~*{AOwjL))_se)*|EA_B6T;bL8x6S1FCP za{kOZ5&pk+?zievs5k>(7QP;R>x?v=d$V_INEYo<{inM!sYedh_@-=M^L~7A4w#+#p!vA#&p&ef?O#E&P|xIGcQ|%L%|Jvae zE-6`+Rj#|rZj($#IK^k%(vJb--%KbAH&L|1B@)8=1uVbF9^|D9SPtVWY68w9t_GIm zx;#|u8(L63?s~N5f~$v;&jTf;rZa~YZ;ZU=6s@=-=PYZ_!fQT72qj0^wkPznx4fQ# z$VYIT{kwIBZY1cX zxU+t0odF$P2r+{K`(;3wJrkg$shME9_1BpIRc#-dgAf|K!8HH$_DjUbzV6-ODFrVy=kkjcvH4=tNV5}xq}nh3Xd+qEnTl{aq| zkbevvuDQCcX%qRPWZHlbvhYbE!{s}Fndt%Q#=`cq+Ru8p$sQ&QZx z`wxDKds4LKl85*nsj6MC<+^(9OkItoY6=O#2=v41QJ(y#!uW3!HmhOSu+>xTDnGXH zpZ(k4R+v$n!4)R-`plj$)SjbV`J(ld+Uw&?PCnWxYj*xrQ;hJ*J>!$@`ma`)dPuP6 zt4{*%C}3lpAwtH(W;^3aJsiYTa`NL?;xvkIaC&z z#{!%w3>Mu-l}<+CwXj4D6cLX{X=nj{B|PvSkHZ1~2?XF?OADo?N@tJ_oTIcHd3ZZ( z3nxFOy>ArSCdyDhT$RHmvpHM@9Hn?+%z^Gp=YX5){#-7bghbBrX(IpYBKtq!A_E1iH~W_(0P}Q_z52OD zI$OY?o6em$V_H)EDr#Xveo_R#;pHpkz0(pqPY0A9(o_A8pq-TJszcsW68pee6cPg% zRxtc#T-npc)pCY$U5|v$A+b>A%|fzbQFK_Yal%VwmF_KNb*YCyLMUXu#&w!dL3Pzu z!VDJ~25^YMrkzy3JE8!G)0FqjmF}Yf(?Y>4s4UQXhJm4oBrJ-A)|~R5*>R|TK~xfq z6$}S`q@Xi;4j0-#DgO4jP3Dcl!yM^sAX_{ZD2IgBBB7@9{^>!Rej^8{zUgmiu z=Z+wer>_W_^EJuSgn&st4;;3gG|9kG5HBrFj4qWM$tE*YXuQ0YLyMsIn9vDKke;N>fw+Wgn5UPjKld-5R?B%>SA9iK_4^;~q!2kNGE-`) za8wk61S~5UezUI1)7CX>hIJJ`8ao%Eg5Wh(-_9RsZ9${)SH`5jbW_jcCkcz^Yh9-a z6%aWtar3aQvn<(fXGZ>fU29k+5 zhyr)>zrc5H>Hboi+3j5@fCk_v< heXdtCM{S_9-UWV{GgJ%q4Y+0k$sE@JL-$`?{{ye9y%PWc literal 0 HcmV?d00001 diff --git a/testing/btest/core/tunnels/ayiya.test b/testing/btest/core/tunnels/ayiya.test new file mode 100644 index 0000000000..043e06c621 --- /dev/null +++ b/testing/btest/core/tunnels/ayiya.test @@ -0,0 +1,4 @@ +# @TEST-EXEC: bro -r $TRACES/tunnels/ayiya3.trace +# @TEST-EXEC: btest-diff tunnel.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.log From f36d96144da10acf0a4ea104de393fb87427f4d9 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 5 Jun 2012 15:34:30 -0500 Subject: [PATCH 37/51] Add a config.h definition for IPPROTO_IPV4. Some older systems may only have IPPROTO_IPIP, the same value, but less clear to read. --- config.h.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config.h.in b/config.h.in index c2cb3ec1dc..5368d6824e 100644 --- a/config.h.in +++ b/config.h.in @@ -165,6 +165,10 @@ #ifndef HAVE_IPPROTO_IPV6 #define IPPROTO_IPV6 41 #endif +#cmakedefine HAVE_IPPROTO_IPV4 +#ifndef HAVE_IPPROTO_IPV4 +#define IPPROTO_IPV4 4 +#endif #cmakedefine HAVE_IPPROTO_ROUTING #ifndef HAVE_IPPROTO_ROUTING #define IPPROTO_ROUTING 43 From 0bdbeb89e230c041e4803db79e090866a3a42f33 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 6 Jun 2012 10:41:36 -0500 Subject: [PATCH 38/51] Memory leak fixes --- scripts/base/init-bare.bro | 5 +- src/IP.cc | 3 +- src/Tunnels.h | 4 +- .../btest/Baseline/core.leaks.ayiya/conn.log | 15 ++++ .../btest/Baseline/core.leaks.ayiya/http.log | 10 +++ .../Baseline/core.leaks.ayiya/tunnel.log | 11 +++ .../btest/Baseline/core.leaks.ip-in-ip/output | 13 +++ .../btest/Baseline/core.leaks.teredo/conn.log | 28 +++++++ .../btest/Baseline/core.leaks.teredo/http.log | 11 +++ .../btest/Baseline/core.leaks.teredo/output | 83 +++++++++++++++++++ .../Baseline/core.leaks.teredo/tunnel.log | 13 +++ testing/btest/core/leaks/ayiya.test | 10 +++ testing/btest/core/leaks/ip-in-ip.test | 33 ++++++++ testing/btest/core/leaks/teredo.bro | 41 +++++++++ 14 files changed, 276 insertions(+), 4 deletions(-) create mode 100644 testing/btest/Baseline/core.leaks.ayiya/conn.log create mode 100644 testing/btest/Baseline/core.leaks.ayiya/http.log create mode 100644 testing/btest/Baseline/core.leaks.ayiya/tunnel.log create mode 100644 testing/btest/Baseline/core.leaks.ip-in-ip/output create mode 100644 testing/btest/Baseline/core.leaks.teredo/conn.log create mode 100644 testing/btest/Baseline/core.leaks.teredo/http.log create mode 100644 testing/btest/Baseline/core.leaks.teredo/output create mode 100644 testing/btest/Baseline/core.leaks.teredo/tunnel.log create mode 100644 testing/btest/core/leaks/ayiya.test create mode 100644 testing/btest/core/leaks/ip-in-ip.test create mode 100644 testing/btest/core/leaks/teredo.bro diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 5ca9cdf330..f23a4e9714 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -1264,6 +1264,9 @@ type ip6_ext_hdr: record { mobility: ip6_mobility_hdr &optional; }; +## A type alias for a vector of IPv6 extension headers. +type ip6_ext_hdr_chain: vector of ip6_ext_hdr; + ## Values extracted from an IPv6 header. ## ## .. bro:see:: pkt_hdr ip4_hdr ip6_ext_hdr ip6_hopopts ip6_dstopts @@ -1278,7 +1281,7 @@ type ip6_hdr: record { hlim: count; ##< Hop limit. src: addr; ##< Source address. dst: addr; ##< Destination address. - exts: vector of ip6_ext_hdr; ##< Extension header chain. + exts: ip6_ext_hdr_chain; ##< Extension header chain. }; ## Values extracted from an IPv4 header. diff --git a/src/IP.cc b/src/IP.cc index f5598600d5..7113c4a678 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -583,7 +583,8 @@ VectorVal* IPv6_Hdr_Chain::BuildVal() const ip6_mob_type = internal_type("ip6_mobility_hdr")->AsRecordType(); } - VectorVal* rval = new VectorVal(new VectorType(ip6_ext_hdr_type->Ref())); + VectorVal* rval = new VectorVal( + internal_type("ip6_ext_hdr_chain")->AsVectorType()); for ( size_t i = 1; i < chain.size(); ++i ) { diff --git a/src/Tunnels.h b/src/Tunnels.h index 3365c8d0ca..c2f070c168 100644 --- a/src/Tunnels.h +++ b/src/Tunnels.h @@ -118,8 +118,8 @@ public: VectorVal* GetVectorVal() const { - VectorVal* vv = new VectorVal(new VectorType( - BifType::Record::Tunnel::EncapsulatingConn->Ref())); + VectorVal* vv = new VectorVal( + internal_type("EncapsulatingConnVector")->AsVectorType()); if ( conns ) for ( size_t i = 0; i < conns->size(); ++i ) vv->Assign(i, (*conns)[i].GetRecordVal(), 0); diff --git a/testing/btest/Baseline/core.leaks.ayiya/conn.log b/testing/btest/Baseline/core.leaks.ayiya/conn.log new file mode 100644 index 0000000000..5c23b4c404 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.ayiya/conn.log @@ -0,0 +1,15 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1257655301.595604 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 tcp http 2.101052 2981 4665 S1 - 0 ShADad 10 3605 11 5329 k6kgXLOoSKl +1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 udp ayiya 20.879001 5129 6109 SF - 0 Dd 21 5717 13 6473 (empty) +1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 udp ayiya - - - SHR - 0 d 0 0 1 176 (empty) +1257655296.585333 FrJExwHcSal :: 135 ff02::1:ff00:2 136 icmp - - - - OTH - 0 - 1 64 0 0 k6kgXLOoSKl +1257655293.629048 arKYeMETxOg 2001:4978:f:4c::1 128 2001:4978:f:4c::2 129 icmp - 23.834987 168 56 OTH - 0 - 3 312 1 104 UWkUyAuUGXf,k6kgXLOoSKl +1257655296.585188 TEfuqmmG4bh fe80::216:cbff:fe9a:4cb9 131 ff02::1:ff00:2 130 icmp - 0.919988 32 0 OTH - 0 - 2 144 0 0 k6kgXLOoSKl +1257655296.585151 j4u32Pc5bif fe80::216:cbff:fe9a:4cb9 131 ff02::2:f901:d225 130 icmp - 0.719947 32 0 OTH - 0 - 2 144 0 0 k6kgXLOoSKl +1257655296.585034 nQcgTWjvg4c fe80::216:cbff:fe9a:4cb9 131 ff02::1:ff9a:4cb9 130 icmp - 4.922880 32 0 OTH - 0 - 2 144 0 0 k6kgXLOoSKl diff --git a/testing/btest/Baseline/core.leaks.ayiya/http.log b/testing/btest/Baseline/core.leaks.ayiya/http.log new file mode 100644 index 0000000000..7cef1a1b8e --- /dev/null +++ b/testing/btest/Baseline/core.leaks.ayiya/http.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1257655301.652206 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 1 GET ipv6.google.com / - Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en; rv:1.9.0.15pre) Gecko/2009091516 Camino/2.0b4 (like Firefox/3.0.15pre) 0 10102 200 OK - - - (empty) - - - text/html - - +1257655302.514424 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 2 GET ipv6.google.com /csi?v=3&s=webhp&action=&tran=undefined&e=17259,19771,21517,21766,21887,22212&ei=BUz2Su7PMJTglQfz3NzCAw&rt=prt.77,xjs.565,ol.645 http://ipv6.google.com/ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en; rv:1.9.0.15pre) Gecko/2009091516 Camino/2.0b4 (like Firefox/3.0.15pre) 0 0 204 No Content - - - (empty) - - - - - - +1257655303.603569 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 3 GET ipv6.google.com /gen_204?atyp=i&ct=fade&cad=1254&ei=BUz2Su7PMJTglQfz3NzCAw&zx=1257655303600 http://ipv6.google.com/ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en; rv:1.9.0.15pre) Gecko/2009091516 Camino/2.0b4 (like Firefox/3.0.15pre) 0 0 204 No Content - - - (empty) - - - - - - diff --git a/testing/btest/Baseline/core.leaks.ayiya/tunnel.log b/testing/btest/Baseline/core.leaks.ayiya/tunnel.log new file mode 100644 index 0000000000..69e331b477 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.ayiya/tunnel.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user +#types time string addr port addr port enum enum string +1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - +1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - +1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - +1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - diff --git a/testing/btest/Baseline/core.leaks.ip-in-ip/output b/testing/btest/Baseline/core.leaks.ip-in-ip/output new file mode 100644 index 0000000000..d8c6bee223 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.ip-in-ip/output @@ -0,0 +1,13 @@ +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf], [cid=[orig_h=babe::beef, orig_p=0/unknown, resp_h=dead::babe, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=arKYeMETxOg]] +new_connection: tunnel + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + encap: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] +tunnel_changed: + conn_id: [orig_h=dead::beef, orig_p=30000/udp, resp_h=cafe::babe, resp_p=13000/udp] + old: [[cid=[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=0/unknown, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=UWkUyAuUGXf]] + new: [[cid=[orig_h=feed::beef, orig_p=0/unknown, resp_h=feed::cafe, resp_p=0/unknown], tunnel_type=Tunnel::IP, uid=k6kgXLOoSKl]] diff --git a/testing/btest/Baseline/core.leaks.teredo/conn.log b/testing/btest/Baseline/core.leaks.teredo/conn.log new file mode 100644 index 0000000000..151230886b --- /dev/null +++ b/testing/btest/Baseline/core.leaks.teredo/conn.log @@ -0,0 +1,28 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1210953047.736921 arKYeMETxOg 192.168.2.16 1576 75.126.130.163 80 tcp - 0.000357 0 0 SHR - 0 fA 1 40 1 40 (empty) +1210953050.867067 k6kgXLOoSKl 192.168.2.16 1577 75.126.203.78 80 tcp - 0.000387 0 0 SHR - 0 fA 1 40 1 40 (empty) +1210953057.833364 5OKnoww6xl4 192.168.2.16 1577 75.126.203.78 80 tcp - 0.079208 0 0 SH - 0 Fa 1 40 1 40 (empty) +1210953058.007081 VW0XPVINV8a 192.168.2.16 1576 75.126.130.163 80 tcp - - - - RSTOS0 - 0 R 1 40 0 0 (empty) +1210953057.834454 3PKsZ2Uye21 192.168.2.16 1578 75.126.203.78 80 tcp http 0.407908 790 171 RSTO - 0 ShADadR 6 1038 4 335 (empty) +1210953058.350065 fRFu0wcOle6 192.168.2.16 1920 192.168.2.1 53 udp dns 0.223055 66 438 SF - 0 Dd 2 122 2 494 (empty) +1210953058.577231 qSsw6ESzHV4 192.168.2.16 137 192.168.2.255 137 udp dns 1.499261 150 0 S0 - 0 D 3 234 0 0 (empty) +1210953074.264819 Tw8jXtpTGu6 192.168.2.16 1920 192.168.2.1 53 udp dns 0.297723 123 598 SF - 0 Dd 3 207 3 682 (empty) +1210953061.312379 70MGiRM1Qf4 2001:0:4137:9e50:8000:f12a:b9c8:2815 1286 2001:4860:0:2001::68 80 tcp http 12.810848 1675 10467 S1 - 0 ShADad 10 2279 12 11191 GSxOnSLghOa +1210953076.058333 EAr0uf4mhq 192.168.2.16 1578 75.126.203.78 80 tcp - - - - RSTRH - 0 r 0 0 1 40 (empty) +1210953074.055744 h5DsfNtYzi1 192.168.2.16 1577 75.126.203.78 80 tcp - - - - RSTRH - 0 r 0 0 1 40 (empty) +1210953074.057124 P654jzLoe3a 192.168.2.16 1576 75.126.130.163 80 tcp - - - - RSTRH - 0 r 0 0 1 40 (empty) +1210953074.570439 c4Zw9TmAE05 192.168.2.16 1580 67.228.110.120 80 tcp http 0.466677 469 3916 SF - 0 ShADadFf 7 757 6 4164 (empty) +1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 udp teredo 8.928880 129 48 SF - 0 Dd 2 185 1 76 (empty) +1210953060.829233 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 udp teredo 13.293994 2359 11243 SF - 0 Dd 12 2695 13 11607 (empty) +1210953058.933954 iE6yhOq3SF 0.0.0.0 68 255.255.255.255 67 udp - - - - S0 - 0 D 1 328 0 0 (empty) +1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 udp teredo - - - SHR - 0 d 0 0 1 137 (empty) +1210953046.591933 UWkUyAuUGXf 192.168.2.16 138 192.168.2.255 138 udp - 28.448321 416 0 S0 - 0 D 2 472 0 0 (empty) +1210953052.324629 FrJExwHcSal fe80::8000:f227:bec8:61af 134 fe80::8000:ffff:ffff:fffd 133 icmp - - - - OTH - 0 - 1 88 0 0 TEfuqmmG4bh +1210953060.829303 qCaWGmzFtM5 2001:0:4137:9e50:8000:f12a:b9c8:2815 128 2001:4860:0:2001::68 129 icmp - 0.463615 4 4 OTH - 0 - 1 52 1 52 GSxOnSLghOa,nQcgTWjvg4c +1210953052.202579 j4u32Pc5bif fe80::8000:ffff:ffff:fffd 133 ff02::2 134 icmp - - - - OTH - 0 - 1 64 0 0 nQcgTWjvg4c diff --git a/testing/btest/Baseline/core.leaks.teredo/http.log b/testing/btest/Baseline/core.leaks.teredo/http.log new file mode 100644 index 0000000000..b3cf832083 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.teredo/http.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1210953057.917183 3PKsZ2Uye21 192.168.2.16 1578 75.126.203.78 80 1 POST download913.avast.com /cgi-bin/iavs4stats.cgi - Syncer/4.80 (av_pro-1169;f) 589 0 204 - - - (empty) - - - text/plain - - +1210953061.585996 70MGiRM1Qf4 2001:0:4137:9e50:8000:f12a:b9c8:2815 1286 2001:4860:0:2001::68 80 1 GET ipv6.google.com / - Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5 0 6640 200 OK - - - (empty) - - - text/html - - +1210953073.381474 70MGiRM1Qf4 2001:0:4137:9e50:8000:f12a:b9c8:2815 1286 2001:4860:0:2001::68 80 2 GET ipv6.google.com /search?hl=en&q=Wireshark+!&btnG=Google+Search http://ipv6.google.com/ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5 0 25119 200 OK - - - (empty) - - - text/html - - +1210953074.674817 c4Zw9TmAE05 192.168.2.16 1580 67.228.110.120 80 1 GET www.wireshark.org / http://ipv6.google.com/search?hl=en&q=Wireshark+%21&btnG=Google+Search Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b5) Gecko/2008032620 Firefox/3.0b5 0 11845 200 OK - - - (empty) - - - text/xml - - diff --git a/testing/btest/Baseline/core.leaks.teredo/output b/testing/btest/Baseline/core.leaks.teredo/output new file mode 100644 index 0000000000..02d5a41e74 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.teredo/output @@ -0,0 +1,83 @@ +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=24, nxt=58, hlim=255, src=fe80::8000:ffff:ffff:fffd, dst=ff02::2, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] +auth: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=24, nxt=58, hlim=255, src=fe80::8000:ffff:ffff:fffd, dst=ff02::2, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.81, resp_p=3544/udp] + ip6: [class=0, flow=0, len=48, nxt=58, hlim=255, src=fe80::8000:f227:bec8:61af, dst=fe80::8000:ffff:ffff:fffd, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] + origin: [p=3797/udp, a=70.55.215.234] +auth: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.81, resp_p=3544/udp] + ip6: [class=0, flow=0, len=48, nxt=58, hlim=255, src=fe80::8000:f227:bec8:61af, dst=fe80::8000:ffff:ffff:fffd, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] + origin: [p=3797/udp, a=70.55.215.234] +origin: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.81, resp_p=3544/udp] + ip6: [class=0, flow=0, len=48, nxt=58, hlim=255, src=fe80::8000:f227:bec8:61af, dst=fe80::8000:ffff:ffff:fffd, exts=[]] + auth: [id=, value=, nonce=14796129349558001544, confirm=0] + origin: [p=3797/udp, a=70.55.215.234] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=21, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +bubble: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=21, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=12, nxt=58, hlim=21, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=fe80::708d:fe83:4114:a512, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] + origin: [p=32900/udp, a=83.170.1.38] +origin: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=fe80::708d:fe83:4114:a512, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] + origin: [p=32900/udp, a=83.170.1.38] +bubble: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=65.55.158.80, resp_p=3544/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=fe80::708d:fe83:4114:a512, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] + origin: [p=32900/udp, a=83.170.1.38] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=fe80::708d:fe83:4114:a512, exts=[]] +bubble: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=0, nxt=59, hlim=0, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=fe80::708d:fe83:4114:a512, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=12, nxt=58, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=24, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=24, nxt=6, hlim=245, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=817, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=514, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=898, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=812, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=1232, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=717, nxt=6, hlim=58, src=2001:4860:0:2001::68, dst=2001:0:4137:9e50:8000:f12a:b9c8:2815, exts=[]] +packet: [orig_h=192.168.2.16, orig_p=3797/udp, resp_h=83.170.1.38, resp_p=32900/udp] + ip6: [class=0, flow=0, len=20, nxt=6, hlim=128, src=2001:0:4137:9e50:8000:f12a:b9c8:2815, dst=2001:4860:0:2001::68, exts=[]] diff --git a/testing/btest/Baseline/core.leaks.teredo/tunnel.log b/testing/btest/Baseline/core.leaks.teredo/tunnel.log new file mode 100644 index 0000000000..5549d66a29 --- /dev/null +++ b/testing/btest/Baseline/core.leaks.teredo/tunnel.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user +#types time string addr port addr port enum enum string +1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO - +1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO - +1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO - +1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO - +1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO - +1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO - diff --git a/testing/btest/core/leaks/ayiya.test b/testing/btest/core/leaks/ayiya.test new file mode 100644 index 0000000000..adad42a822 --- /dev/null +++ b/testing/btest/core/leaks/ayiya.test @@ -0,0 +1,10 @@ +# Needs perftools support. +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-GROUP: leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -r $TRACES/tunnels/ayiya3.trace +# @TEST-EXEC: btest-diff tunnel.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.log diff --git a/testing/btest/core/leaks/ip-in-ip.test b/testing/btest/core/leaks/ip-in-ip.test new file mode 100644 index 0000000000..64fdf739f6 --- /dev/null +++ b/testing/btest/core/leaks/ip-in-ip.test @@ -0,0 +1,33 @@ +# Needs perftools support. +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-GROUP: leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -b -r $TRACES/tunnels/6in6.pcap %INPUT >>output +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -b -r $TRACES/tunnels/6in6in6.pcap %INPUT >>output +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -b -r $TRACES/tunnels/6in6-tunnel-change.pcap %INPUT >>output +# @TEST-EXEC: btest-diff output + +event new_connection(c: connection) + { + if ( c?$tunnel ) + { + print "new_connection: tunnel"; + print fmt(" conn_id: %s", c$id); + print fmt(" encap: %s", c$tunnel); + } + else + { + print "new_connection: no tunnel"; + } + } + +event tunnel_changed(c: connection, e: EncapsulatingConnVector) + { + print "tunnel_changed:"; + print fmt(" conn_id: %s", c$id); + if ( c?$tunnel ) + print fmt(" old: %s", c$tunnel); + print fmt(" new: %s", e); + } diff --git a/testing/btest/core/leaks/teredo.bro b/testing/btest/core/leaks/teredo.bro new file mode 100644 index 0000000000..9902f1258b --- /dev/null +++ b/testing/btest/core/leaks/teredo.bro @@ -0,0 +1,41 @@ +# Needs perftools support. +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-GROUP: leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -r $TRACES/tunnels/Teredo.pcap %INPUT >output +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff tunnel.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.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); + } From beacf581d331adc6e3f5a7886bfb1ae22c0112ed Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 6 Jun 2012 14:40:11 -0500 Subject: [PATCH 39/51] Just some cleanup/documentation of new tunnel-handling code. --- scripts/base/frameworks/tunnels/main.bro | 3 +- src/CMakeLists.txt | 2 +- src/Conn.cc | 2 +- src/Conn.h | 2 +- src/Sessions.cc | 5 +- src/Sessions.h | 2 +- src/{Tunnels.cc => TunnelEncapsulation.cc} | 25 ++---- src/{Tunnels.h => TunnelEncapsulation.h} | 80 +++++++++++++++++-- .../Baseline/core.leaks.ayiya/tunnel.log | 12 +-- .../Baseline/core.leaks.teredo/tunnel.log | 16 ++-- .../Baseline/core.tunnels.ayiya/tunnel.log | 12 +-- .../Baseline/core.tunnels.teredo/tunnel.log | 16 ++-- 12 files changed, 112 insertions(+), 65 deletions(-) rename src/{Tunnels.cc => TunnelEncapsulation.cc} (68%) rename src/{Tunnels.h => TunnelEncapsulation.h} (51%) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 4076e79cd5..32270cf898 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -2,7 +2,7 @@ ##! AYIYA, or IP-in-IP such as 6to4 where "IP" is either IPv4 or IPv6). ##! ##! For any connection that occurs over a tunnel, information about its -##! its encapsulating tunnels is also found in the *tunnel* field of +##! encapsulating tunnels is also found in the *tunnel* field of ##! :bro:type:`connection`. module Tunnel; @@ -35,7 +35,6 @@ export { action: Action &log; ## The type of tunnel. tunnel_type: Tunnel::Type &log; - user: string &log &optional; }; ## Logs all tunnels in an ecapsulation chain with action diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0a6c2a5c76..50e58d87e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -402,7 +402,7 @@ set(bro_SRCS Timer.cc Traverse.cc Trigger.cc - Tunnels.cc + TunnelEncapsulation.cc Type.cc UDP.cc Val.cc diff --git a/src/Conn.cc b/src/Conn.cc index ec62a1b944..9780b15dfc 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -13,7 +13,7 @@ #include "Timer.h" #include "PIA.h" #include "binpac.h" -#include "Tunnels.h" +#include "TunnelEncapsulation.h" void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer, int arg_do_expire) diff --git a/src/Conn.h b/src/Conn.h index f2efa2971d..52c14598be 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -13,7 +13,7 @@ #include "RuleMatcher.h" #include "AnalyzerTags.h" #include "IPAddr.h" -#include "Tunnels.h" +#include "TunnelEncapsulation.h" class Connection; class ConnectionTimer; diff --git a/src/Sessions.cc b/src/Sessions.cc index 4e81ba1661..77ccd7aeb6 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -30,7 +30,7 @@ #include "DPM.h" #include "PacketSort.h" -#include "Tunnels.h" +#include "TunnelEncapsulation.h" // These represent NetBIOS services on ephemeral ports. They're numbered // so that we can use a single int to hold either an actual TCP/UDP server @@ -570,8 +570,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( it == ip_tunnels.end() ) { - EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - BifEnum::Tunnel::IP); + EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr()); ip_tunnels[tunnel_idx] = ec; outer->Add(ec); } diff --git a/src/Sessions.h b/src/Sessions.h index 9273a02787..b98fc7e432 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -11,7 +11,7 @@ #include "PacketFilter.h" #include "Stats.h" #include "NetVar.h" -#include "Tunnels.h" +#include "TunnelEncapsulation.h" #include struct pcap_pkthdr; diff --git a/src/Tunnels.cc b/src/TunnelEncapsulation.cc similarity index 68% rename from src/Tunnels.cc rename to src/TunnelEncapsulation.cc index 7ae87912d7..e7ee3e27d1 100644 --- a/src/Tunnels.cc +++ b/src/TunnelEncapsulation.cc @@ -1,13 +1,13 @@ // See the file "COPYING" in the main distribution directory for copyright. -#include "Tunnels.h" +#include "TunnelEncapsulation.h" #include "util.h" #include "Conn.h" EncapsulatingConn::EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t) : src_addr(c->OrigAddr()), dst_addr(c->RespAddr()), src_port(c->OrigPort()), dst_port(c->RespPort()), - type(t), uid(c->GetUID()) + proto(c->ConnTransport()), type(t), uid(c->GetUID()) { if ( ! uid ) { @@ -18,28 +18,13 @@ EncapsulatingConn::EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t) RecordVal* EncapsulatingConn::GetRecordVal() const { - RecordVal *rv = - new RecordVal(BifType::Record::Tunnel::EncapsulatingConn); - TransportProto tproto; - switch ( type ) { - case BifEnum::Tunnel::AYIYA: - case BifEnum::Tunnel::TEREDO: - tproto = TRANSPORT_UDP; - break; - case BifEnum::Tunnel::SOCKS: - tproto = TRANSPORT_TCP; - break; - case BifEnum::Tunnel::IP: - default: - tproto = TRANSPORT_UNKNOWN; - break; - } // end switch + RecordVal *rv = new RecordVal(BifType::Record::Tunnel::EncapsulatingConn); RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal(src_addr)); - id_val->Assign(1, new PortVal(ntohs(src_port), tproto)); + id_val->Assign(1, new PortVal(ntohs(src_port), proto)); id_val->Assign(2, new AddrVal(dst_addr)); - id_val->Assign(3, new PortVal(ntohs(dst_port), tproto)); + id_val->Assign(3, new PortVal(ntohs(dst_port), proto)); rv->Assign(0, id_val); rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type)); char tmp[20]; diff --git a/src/Tunnels.h b/src/TunnelEncapsulation.h similarity index 51% rename from src/Tunnels.h rename to src/TunnelEncapsulation.h index c2f070c168..f0d07b0501 100644 --- a/src/Tunnels.h +++ b/src/TunnelEncapsulation.h @@ -11,30 +11,71 @@ class Connection; +/** + * Represents various types of tunnel "connections", that is, a pair of + * endpoints whose communication encapsulates inner IP packets. This could + * mean IP packets nested inside IP packets or IP packets nested inside a + * transport layer protocol. EncapsulatingConn's are assigned a UID, which can + * be shared with Connection's in the case the tunnel uses a transport-layer. + */ class EncapsulatingConn { public: + /** + * Default tunnel connection constructor. + */ EncapsulatingConn() - : src_port(0), dst_port(0), type(BifEnum::Tunnel::NONE), uid(0) + : src_port(0), dst_port(0), proto(TRANSPORT_UNKNOWN), + type(BifEnum::Tunnel::NONE), uid(0) {} - EncapsulatingConn(const IPAddr& s, const IPAddr& d, - BifEnum::Tunnel::Type t) - : src_addr(s), dst_addr(d), src_port(0), dst_port(0), type(t) + /** + * Construct an IP tunnel "connection" with its own UID. + * The assignment of "source" and "destination" addresses here can be + * arbitrary, comparison between EncapsulatingConn objects will treat IP + * tunnels as equivalent as long as the same two endpoints are involved. + * + * @param s The tunnel source address, likely taken from an IP header. + * @param d The tunnel destination address, likely taken from an IP header. + */ + EncapsulatingConn(const IPAddr& s, const IPAddr& d) + : src_addr(s), dst_addr(d), src_port(0), dst_port(0), + proto(TRANSPORT_UNKNOWN), type(BifEnum::Tunnel::IP) { uid = calculate_unique_id(); } + /** + * Construct a tunnel connection using information from an already existing + * transport-layer-aware connection object. + * + * @param c The connection from which endpoint information can be extracted. + * If it already has a UID associated with it, that gets inherited, + * otherwise a new UID is created for this tunnel and \a c. + * @param t The type of tunneling that is occurring over the connection. + */ EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t); + /** + * Copy constructor. + */ EncapsulatingConn(const EncapsulatingConn& other) : src_addr(other.src_addr), dst_addr(other.dst_addr), src_port(other.src_port), dst_port(other.dst_port), - type(other.type), uid(other.uid) + proto(other.proto), type(other.type), uid(other.uid) {} + /** + * Destructor. + */ ~EncapsulatingConn() {} + BifEnum::Tunnel::Type Type() const + { return type; } + + /** + * Returns record value of type "EncapsulatingConn" representing the tunnel. + */ RecordVal* GetRecordVal() const; friend bool operator==(const EncapsulatingConn& ec1, @@ -43,12 +84,13 @@ public: if ( ec1.type != ec2.type ) return false; if ( ec1.type == BifEnum::Tunnel::IP ) - return ec1.uid == ec2.uid && + // Reversing endpoints is still same tunnel. + return ec1.uid == ec2.uid && ec1.proto == ec2.proto && ((ec1.src_addr == ec2.src_addr && ec1.dst_addr == ec2.dst_addr) || (ec1.src_addr == ec2.dst_addr && ec1.dst_addr == ec2.src_addr)); return ec1.src_addr == ec2.src_addr && ec1.dst_addr == ec2.dst_addr && ec1.src_port == ec2.src_port && ec1.dst_port == ec2.dst_port && - ec1.uid == ec2.uid; + ec1.uid == ec2.uid && ec1.proto == ec2.proto; } friend bool operator!=(const EncapsulatingConn& ec1, @@ -57,14 +99,19 @@ public: return ! ( ec1 == ec2 ); } +protected: IPAddr src_addr; IPAddr dst_addr; uint16 src_port; uint16 dst_port; + TransportProto proto; BifEnum::Tunnel::Type type; uint64 uid; }; +/** + * Abstracts an arbitrary amount of nested tunneling. + */ class Encapsulation { public: Encapsulation() : conns(0) @@ -99,6 +146,11 @@ public: ~Encapsulation() { delete conns; } + /** + * Add a new inner-most tunnel to the Encapsulation. + * + * @param c The new inner-most tunnel to append to the tunnel chain. + */ void Add(const EncapsulatingConn& c) { if ( ! conns ) @@ -106,16 +158,27 @@ public: conns->push_back(c); } + /** + * Return how many nested tunnels are involved in a encapsulation, zero + * meaning no tunnels are present. + */ size_t Depth() const { return conns ? conns->size() : 0; } + /** + * Return the tunnel type of the inner-most tunnel. + */ BifEnum::Tunnel::Type LastType() const { - return conns ? (*conns)[conns->size()-1].type : BifEnum::Tunnel::NONE; + return conns ? (*conns)[conns->size()-1].Type() : BifEnum::Tunnel::NONE; } + /** + * Get the value of type "EncapsulatingConnVector" represented by the + * entire encapsulation chain. + */ VectorVal* GetVectorVal() const { VectorVal* vv = new VectorVal( @@ -133,6 +196,7 @@ public: return ! ( e1 == e2 ); } +protected: vector* conns; }; diff --git a/testing/btest/Baseline/core.leaks.ayiya/tunnel.log b/testing/btest/Baseline/core.leaks.ayiya/tunnel.log index 69e331b477..512f49b6ee 100644 --- a/testing/btest/Baseline/core.leaks.ayiya/tunnel.log +++ b/testing/btest/Baseline/core.leaks.ayiya/tunnel.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path tunnel -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user -#types time string addr port addr port enum enum string -1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - -1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - -1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - -1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type +#types time string addr port addr port enum enum +1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA +1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA +1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA +1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA diff --git a/testing/btest/Baseline/core.leaks.teredo/tunnel.log b/testing/btest/Baseline/core.leaks.teredo/tunnel.log index 5549d66a29..5a2114dd1c 100644 --- a/testing/btest/Baseline/core.leaks.teredo/tunnel.log +++ b/testing/btest/Baseline/core.leaks.teredo/tunnel.log @@ -3,11 +3,11 @@ #empty_field (empty) #unset_field - #path tunnel -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user -#types time string addr port addr port enum enum string -1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO - -1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO - -1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO - -1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO - -1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO - -1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO - +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type +#types time string addr port addr port enum enum +1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO +1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO +1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO +1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO +1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO +1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO diff --git a/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log b/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log index 69e331b477..512f49b6ee 100644 --- a/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log +++ b/testing/btest/Baseline/core.tunnels.ayiya/tunnel.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path tunnel -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user -#types time string addr port addr port enum enum string -1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - -1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA - -1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - -1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA - +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type +#types time string addr port addr port enum enum +1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA +1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::DISCOVER Tunnel::AYIYA +1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA +1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::CLOSE Tunnel::AYIYA diff --git a/testing/btest/Baseline/core.tunnels.teredo/tunnel.log b/testing/btest/Baseline/core.tunnels.teredo/tunnel.log index 5549d66a29..5a2114dd1c 100644 --- a/testing/btest/Baseline/core.tunnels.teredo/tunnel.log +++ b/testing/btest/Baseline/core.tunnels.teredo/tunnel.log @@ -3,11 +3,11 @@ #empty_field (empty) #unset_field - #path tunnel -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type user -#types time string addr port addr port enum enum string -1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO - -1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO - -1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO - -1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO - -1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO - -1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO - +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type +#types time string addr port addr port enum enum +1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO +1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO +1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO +1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO +1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO +1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO From 6f346c84060b9db6d06e931a67f47628ab72ebdd Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 7 Jun 2012 12:12:57 -0500 Subject: [PATCH 40/51] 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. --- scripts/base/init-bare.bro | 8 +++++ src/Analyzer.h | 4 +++ src/Teredo.cc | 28 +++++++++++++-- src/const.bif | 1 + .../core.tunnels.false-teredo/weird.log | 19 ++++++++++ .../btest/Traces/tunnels/false-teredo.pcap | Bin 0 -> 3098 bytes testing/btest/core/tunnels/false-teredo.bro | 34 ++++++++++++++++++ 7 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/core.tunnels.false-teredo/weird.log create mode 100644 testing/btest/Traces/tunnels/false-teredo.pcap create mode 100644 testing/btest/core/tunnels/false-teredo.bro diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index a356167cd7..879a4f5995 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2705,6 +2705,14 @@ export { ## Toggle whether to do IPv6-in-Teredo decapsulation. 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 module GLOBAL; diff --git a/src/Analyzer.h b/src/Analyzer.h index ef596ac696..21dcba9fa9 100644 --- a/src/Analyzer.h +++ b/src/Analyzer.h @@ -343,6 +343,10 @@ private: for ( analyzer_list::iterator var = the_kids.begin(); \ 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 { public: SupportAnalyzer(AnalyzerTag::Tag tag, Connection* conn, bool arg_orig) diff --git a/src/Teredo.cc b/src/Teredo.cc index 945e54ee18..21d8f90ee7 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -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); 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 ) ProtocolViolation("Truncated Teredo", (const char*) data, len); else ProtocolViolation("Teredo payload length", (const char*) data, len); - if ( rslt != 0 ) return; + if ( rslt != 0 || ! ProtocolConfirmed() ) return; Val* teredo_hdr = 0; diff --git a/src/const.bif b/src/const.bif index 3e8fe4b53b..368ee34396 100644 --- a/src/const.bif +++ b/src/const.bif @@ -15,5 +15,6 @@ const Tunnel::max_depth: count; const Tunnel::enable_ip: bool; const Tunnel::enable_ayiya: bool; const Tunnel::enable_teredo: bool; +const Tunnel::yielding_teredo_decapsulation: bool; const Threading::heartbeat_interval: interval; diff --git a/testing/btest/Baseline/core.tunnels.false-teredo/weird.log b/testing/btest/Baseline/core.tunnels.false-teredo/weird.log new file mode 100644 index 0000000000..d2bafa0384 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.false-teredo/weird.log @@ -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 diff --git a/testing/btest/Traces/tunnels/false-teredo.pcap b/testing/btest/Traces/tunnels/false-teredo.pcap new file mode 100644 index 0000000000000000000000000000000000000000..e82a6f41693b06517d460a0f976cbed141f9e8fb GIT binary patch literal 3098 zcmd6pe`r%z6vyv-xlLkiV`IB%WtO28hO}auCKj!;^oNtCLtFF&=(wfB$;N*C;fihybY)04n2zCG9nqchUXqvgvHUrf za-iqj`|kIi&pG$LcWvVA37$}r|2=v{2nWt0KMj<7>|`tak49>zZojykIFl{hIVb5N zq|0`QkYV>ny=;{02jgz-AU@)`oenL9=Wz-6Q6V0ZTtg{QOZF>rTu=waq%EYxaRRqz z;8F%%O6qpCT^BBVT@S+I=G&a}19huZ& z=z0E|LLu)uLOY-N_86-+^0vK792C;_uxbf5(6Nt@ZqP=vq}Wpa08>0g@+oFFLW=bV z>b+xTikv_rT39ZmcB}4aAFdpL)@p@mXmeBJRy9Aw)W+>*YT1q4l0!$lV|r>fG7p+& z&dQKd8J5mfMHUy0ImB>O927G)Sxgf4lriV|9i)beEo+*%Xt^*b#D#vG#n!Q&Tzk|I zy2Czoifu8lIGn_8lUt&!cXnj8CE~M0nkmWUT3WdaR!&e-N2&G|oU z9;`Bs=D-E4QjZ^4O2|{MlIMx@QWjt#eJnskQIbI+7UNTc4pmGgMO7=5?BtQguTiGq zri1(rlhKGSP;@k>_E%uZBAvOCNyG<2-(*in+1$~z5x%5MzJ8;O)XfXUQW|W+o|KBT|~3G*3Mf~wGo-|kkij^Zk59@bG5sjB{HG%*&_BtcDx?8%~W zs4G0No1HM$tdR-5@t*J&8!`Rfdn@^LmM}HOqntP+S2Lt0$I?cl#mo-VpJ6pQlU}(+{LF+CUvfo zl)*D-7J&CZ`56JWZZ!dd&{Q8)rV0RQNtt}3@_mG7RjkTr6!2)`(DgEp5vcQUaA+3!|O_Sp&U-QB;4mv#1V%MyD@nLK;ABVAG|jIq9tVFNYd31{@#|;A z3yQNN&6bGI67g6fO_qqCwU6U_9X@s5A0l+qbeC(q+Vp$6kH5*jH2t<^XO6QUb)UfA zV7?S&cTB(Q^k46cuQ2_#WvBQ2dVvPkw!5so5_;j9@j~H!*emDoyCaH)oc)*JgIY)NTj zt|g6M_><7<-`||heM)i5A15wHG#PJ{Ga;MsauoW~ X_{hSM`A!^xS5kyMizwXx^F96p8SMi; literal 0 HcmV?d00001 diff --git a/testing/btest/core/tunnels/false-teredo.bro b/testing/btest/core/tunnels/false-teredo.bro new file mode 100644 index 0000000000..ebb428f65a --- /dev/null +++ b/testing/btest/core/tunnels/false-teredo.bro @@ -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); + } From 9d2a21c49044cea53a8d5b97ba9b2025081a3fac Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 7 Jun 2012 13:03:13 -0500 Subject: [PATCH 41/51] Extend weird names that occur in core packet processing during decapsulation. Appending a "_in_tunnel" to the weird name might help clarify that the weird is happening with a packet that is attempting to be processed as a result of decapsulation. --- src/Sessions.cc | 49 +++++++++++-------- src/Sessions.h | 10 ++-- .../core.tunnels.false-teredo/weird.log | 12 ++--- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/Sessions.cc b/src/Sessions.cc index 77ccd7aeb6..1e0068acec 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -353,7 +353,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, uint32 len = ip_hdr->TotalLen(); if ( hdr->len < len + hdr_size ) { - Weird("truncated_IP", hdr, pkt); + Weird("truncated_IP", hdr, pkt, encapsulation); return; } @@ -365,7 +365,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( ! ignore_checksums && ip4 && ones_complement_checksum((void*) ip4, ip_hdr_len, 0) != 0xffff ) { - Weird("bad_IP_checksum", hdr, pkt); + Weird("bad_IP_checksum", hdr, pkt, encapsulation); return; } @@ -380,7 +380,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( caplen < len ) { - Weird("incompletely_captured_fragment", ip_hdr); + Weird("incompletely_captured_fragment", ip_hdr, encapsulation); // Don't try to reassemble, that's doomed. // Discard all except the first fragment (which @@ -432,7 +432,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( ! ignore_checksums && mobility_header_checksum(ip_hdr) != 0xffff ) { - Weird("bad_MH_checksum", hdr, pkt); + Weird("bad_MH_checksum", hdr, pkt, encapsulation); Remove(f); return; } @@ -445,7 +445,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } if ( ip_hdr->NextProto() != IPPROTO_NONE ) - Weird("mobility_piggyback", hdr, pkt); + Weird("mobility_piggyback", hdr, pkt, encapsulation); Remove(f); return; @@ -454,7 +454,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, int proto = ip_hdr->NextProto(); - if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) ) + if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt, encapsulation) ) { Remove(f); return; @@ -525,7 +525,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, { if ( ! BifConst::Tunnel::enable_ip ) { - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "IP_tunnel"); + Weird("IP_tunnel", ip_hdr, encapsulation); Remove(f); return; } @@ -533,7 +533,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, if ( encapsulation && encapsulation->Depth() >= BifConst::Tunnel::max_depth ) { - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), "tunnel_depth"); + Weird("tunnel_depth", ip_hdr, encapsulation); Remove(f); return; } @@ -543,11 +543,9 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, int result = ParseIPPacket(caplen, data, proto, inner); if ( result < 0 ) - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - "truncated_inner_IP"); + Weird("truncated_inner_IP", ip_hdr, encapsulation); else if ( result > 0 ) - reporter->Weird(ip_hdr->SrcAddr(), ip_hdr->DstAddr(), - "inner_IP_payload_mismatch"); + Weird("inner_IP_payload_mismatch", ip_hdr, encapsulation); if ( result != 0 ) { @@ -599,7 +597,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } default: - Weird(fmt("unknown_protocol_%d", proto), hdr, pkt); + Weird(fmt("unknown_protocol_%d", proto), hdr, pkt, encapsulation); Remove(f); return; } @@ -746,7 +744,8 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto, } bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, - const struct pcap_pkthdr* h, const u_char* p) + const struct pcap_pkthdr* h, + const u_char* p, const Encapsulation* encap) { uint32 min_hdr_len = 0; switch ( proto ) { @@ -775,13 +774,13 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, if ( len < min_hdr_len ) { - Weird("truncated_header", h, p); + Weird("truncated_header", h, p, encap); return true; } if ( caplen < min_hdr_len ) { - Weird("internally_truncated_header", h, p); + Weird("internally_truncated_header", h, p, encap); return true; } @@ -1298,18 +1297,26 @@ void NetSessions::Internal(const char* msg, const struct pcap_pkthdr* hdr, reporter->InternalError("%s", msg); } -void NetSessions::Weird(const char* name, - const struct pcap_pkthdr* hdr, const u_char* pkt) +void NetSessions::Weird(const char* name, const struct pcap_pkthdr* hdr, + const u_char* pkt, const Encapsulation* encap) { if ( hdr ) dump_this_packet = 1; - reporter->Weird(name); + if ( encap && encap->LastType() != BifEnum::Tunnel::NONE ) + reporter->Weird(fmt("%s_in_tunnel", name)); + else + reporter->Weird(name); } -void NetSessions::Weird(const char* name, const IP_Hdr* ip) +void NetSessions::Weird(const char* name, const IP_Hdr* ip, + const Encapsulation* encap) { - reporter->Weird(ip->SrcAddr(), ip->DstAddr(), name); + if ( encap && encap->LastType() != BifEnum::Tunnel::NONE ) + reporter->Weird(ip->SrcAddr(), ip->DstAddr(), + fmt("%s_in_tunnel", name)); + else + reporter->Weird(ip->SrcAddr(), ip->DstAddr(), name); } unsigned int NetSessions::ConnectionMemoryUsage() diff --git a/src/Sessions.h b/src/Sessions.h index b98fc7e432..28f331212b 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -108,9 +108,10 @@ public: void GetStats(SessionStats& s) const; - void Weird(const char* name, - const struct pcap_pkthdr* hdr, const u_char* pkt); - void Weird(const char* name, const IP_Hdr* ip); + void Weird(const char* name, const struct pcap_pkthdr* hdr, + const u_char* pkt, const Encapsulation* encap = 0); + void Weird(const char* name, const IP_Hdr* ip, + const Encapsulation* encap = 0); PacketFilter* GetPacketFilter() { @@ -231,7 +232,8 @@ protected: // from lower-level headers or the length actually captured is less // than that protocol's minimum header size. bool CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, - const struct pcap_pkthdr* hdr, const u_char* pkt); + const struct pcap_pkthdr* hdr, const u_char* pkt, + const Encapsulation* encap); CompositeHash* ch; PDict(Connection) tcp_conns; diff --git a/testing/btest/Baseline/core.tunnels.false-teredo/weird.log b/testing/btest/Baseline/core.tunnels.false-teredo/weird.log index d2bafa0384..989b7beede 100644 --- a/testing/btest/Baseline/core.tunnels.false-teredo/weird.log +++ b/testing/btest/Baseline/core.tunnels.false-teredo/weird.log @@ -5,15 +5,15 @@ #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.405770 - - - - - truncated_header_in_tunnel - 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.260420 - - - - - truncated_header_in_tunnel - 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.557927 - - - - - truncated_header_in_tunnel - 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.568451 - - - - - truncated_header_in_tunnel - 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.859853 - - - - - truncated_header_in_tunnel - 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.934458 - - - - - truncated_header_in_tunnel - F bro 1258600683.934672 5OKnoww6xl4 192.168.1.103 59838 192.168.1.1 53 Teredo_payload_len_mismatch - F bro From 19cf93be69dc76cfcac5141c9a3f4b8deb6ef88d Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 15 Jun 2012 14:45:07 -0700 Subject: [PATCH 42/51] Moving my todos over to the tracker ticket. --- scripts/base/frameworks/tunnels/main.bro | 9 --------- src/Analyzer.h | 4 +--- src/Sessions.cc | 3 +-- src/TunnelEncapsulation.h | 8 -------- src/event.bif | 1 - 5 files changed, 2 insertions(+), 23 deletions(-) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 0fd37e8e59..1f0258e0a3 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -18,8 +18,6 @@ export { ## A tunnel connection has closed. CLOSE, ## No new connections over a tunnel happened in the past day. - ## TODO-Jon: Where is the "past day" coming from? Should be an - ## option. EXPIRE, }; @@ -72,7 +70,6 @@ export { ## Currently active tunnels. That is, tunnels for which new, encapsulated ## connections have been seen in the last day. - ## TODO-Jon: Do we we need the &synchronized here? global active: table[conn_id] of Info = table() &synchronized &read_expire=24hrs &expire_func=expire; } @@ -132,12 +129,6 @@ event new_connection(c: connection) &priority=5 event tunnel_changed(c: connection, e: EncapsulatingConnVector) &priority=5 { - ## TODO-Jon: Not sure I understand this. Shouldn't c$tunnel already be - ## registered? And what if a layer goes way, does that need to be - ## removed here? Or is that done separately? - ## - ## Also, conn/main.bro has a tunnel_changed handler at the same - ## priority that *sets* c$tunnel. That's seems undefine behaviour. if ( c?$tunnel ) register_all(c$tunnel); diff --git a/src/Analyzer.h b/src/Analyzer.h index 6fd1b3b444..6ccd7648d3 100644 --- a/src/Analyzer.h +++ b/src/Analyzer.h @@ -217,9 +217,7 @@ public: // Return whether the analyzer previously called ProtocolConfirmation() // at least once before. - // - // TODO-Jon: Why virtual? - virtual bool ProtocolConfirmed() const + bool ProtocolConfirmed() const { return protocol_confirmed; } // Report that we found a significant protocol violation which might diff --git a/src/Sessions.cc b/src/Sessions.cc index 7f62f42c7b..c754a14698 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -546,7 +546,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, Weird("truncated_inner_IP", ip_hdr, encapsulation); else if ( result > 0 ) - Weird("inner_IP_payload_mismatch", ip_hdr, encapsulation); + Weird("inner_IP_payload_length_mismatch", ip_hdr, encapsulation); if ( result != 0 ) { @@ -706,7 +706,6 @@ void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, if ( hdr ) fake_hdr.ts = hdr->ts; else - // TODO-Jon: use network_time? fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; const u_char* pkt = 0; diff --git a/src/TunnelEncapsulation.h b/src/TunnelEncapsulation.h index 01819c0f20..9dcf134536 100644 --- a/src/TunnelEncapsulation.h +++ b/src/TunnelEncapsulation.h @@ -114,9 +114,6 @@ protected: /** * Abstracts an arbitrary amount of nested tunneling. */ - -// TODO-Jon: Rename EncapsulationChain or EncapsulationStack? I'd prefer to -// have notion in there that this covers multiple levels of encapsulations. class Encapsulation { public: Encapsulation() : conns(0) @@ -130,11 +127,6 @@ public: conns = 0; } - // TODO-Jon: I don't like the ptr-version of the ctor. When reading - // the code using that, I can't tell what it does with the pointer - // (i.e., that it deep-copied the object). Can we use just the - // reference version above? That may mean more "if ( not null )" at - // the caller end though. Encapsulation(const Encapsulation* other) { if ( other && other->conns ) diff --git a/src/event.bif b/src/event.bif index 8d4b1d28a1..0531bb8a18 100644 --- a/src/event.bif +++ b/src/event.bif @@ -146,7 +146,6 @@ event new_connection%(c: connection%); ## or from the outer encapsulation changing. Note that the connection's ## *tunnel* field is NOT automatically assigned to the new encapsulation value ## internally after this event is raised. -## TODO-Jon: I'm not sure what the last sentence is supposed to tell me? ## ## c: The connection whose tunnel/encapsulation changed. ## From d727b4f68a711f07b5f1ce170e9f045080b84d47 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 15 Jun 2012 15:05:42 -0700 Subject: [PATCH 43/51] Updating DataSeries baselines. --- .../conn.ds.txt | 72 ++++++++++--------- .../conn.ds.txt | 72 ++++++++++--------- .../http.ds.txt | 24 +++---- 3 files changed, 86 insertions(+), 82 deletions(-) diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt index 1d7cba3b3c..620babdd4c 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt @@ -28,6 +28,7 @@ + @@ -48,40 +49,41 @@ + # Extent, type='conn' -ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes -1300475167096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 73 0 0 -1300475167097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0 0 0 S0 F 0 D 1 199 0 0 -1300475167099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0 0 0 S0 F 0 D 1 179 0 0 -1300475168853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 435 0 89 SHR F 0 Cd 0 0 1 117 -1300475168854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 420 0 99 SHR F 0 Cd 0 0 1 127 -1300475168854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 391 0 183 SHR F 0 Cd 0 0 1 211 -1300475168857956 3PKsZ2Uye21 141.142.220.118 32902 141.142.2.2 53 udp dns 317 0 89 SHR F 0 Cd 0 0 1 117 -1300475168858306 VW0XPVINV8a 141.142.220.118 59816 141.142.2.2 53 udp dns 343 0 99 SHR F 0 Cd 0 0 1 127 -1300475168858713 fRFu0wcOle6 141.142.220.118 59714 141.142.2.2 53 udp dns 375 0 183 SHR F 0 Cd 0 0 1 211 -1300475168891644 qSsw6ESzHV4 141.142.220.118 58206 141.142.2.2 53 udp dns 339 0 89 SHR F 0 Cd 0 0 1 117 -1300475168892037 iE6yhOq3SF 141.142.220.118 38911 141.142.2.2 53 udp dns 334 0 99 SHR F 0 Cd 0 0 1 127 -1300475168892414 GSxOnSLghOa 141.142.220.118 59746 141.142.2.2 53 udp dns 420 0 183 SHR F 0 Cd 0 0 1 211 -1300475168893988 qCaWGmzFtM5 141.142.220.118 45000 141.142.2.2 53 udp dns 384 0 89 SHR F 0 Cd 0 0 1 117 -1300475168894422 70MGiRM1Qf4 141.142.220.118 48479 141.142.2.2 53 udp dns 316 0 99 SHR F 0 Cd 0 0 1 127 -1300475168894787 h5DsfNtYzi1 141.142.220.118 48128 141.142.2.2 53 udp dns 422 0 183 SHR F 0 Cd 0 0 1 211 -1300475168901749 P654jzLoe3a 141.142.220.118 56056 141.142.2.2 53 udp dns 402 0 131 SHR F 0 Cd 0 0 1 159 -1300475168902195 Tw8jXtpTGu6 141.142.220.118 55092 141.142.2.2 53 udp dns 374 0 198 SHR F 0 Cd 0 0 1 226 -1300475169899438 BWaU4aSuwkc 141.142.220.44 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 85 0 0 -1300475170862384 10XodEwRycf 141.142.220.226 137 141.142.220.255 137 udp dns 2613016 350 0 S0 F 0 D 7 546 0 0 -1300475171675372 zno26fFZkrh fe80::3074:17d5:2052:c324 65373 ff02::1:3 5355 udp dns 100096 66 0 S0 F 0 D 2 162 0 0 -1300475171677081 v5rgkJBig5l 141.142.220.226 55131 224.0.0.252 5355 udp dns 100020 66 0 S0 F 0 D 2 122 0 0 -1300475173116749 eWZCH7OONC1 fe80::3074:17d5:2052:c324 54213 ff02::1:3 5355 udp dns 99801 66 0 S0 F 0 D 2 162 0 0 -1300475173117362 0Pwk3ntf8O3 141.142.220.226 55671 224.0.0.252 5355 udp dns 99848 66 0 S0 F 0 D 2 122 0 0 -1300475173153679 0HKorjr8Zp7 141.142.220.238 56641 141.142.220.255 137 udp dns 0 0 0 S0 F 0 D 1 78 0 0 -1300475168859163 GvmoxJFXdTa 141.142.220.118 49998 208.80.152.3 80 tcp 215893 1130 734 S1 F 1130 ShACad 4 216 4 950 -1300475168652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 61328 0 350 OTH F 0 CdA 1 52 1 402 -1300475168895267 UfGkYA2HI2g 141.142.220.118 50001 208.80.152.3 80 tcp 227283 1178 734 S1 F 1178 ShACad 4 216 4 950 -1300475168902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp 120040 534 412 S1 F 534 ShACad 3 164 3 576 -1300475168892936 0Q4FH8sESw5 141.142.220.118 50000 208.80.152.3 80 tcp 229603 1148 734 S1 F 1148 ShACad 4 216 4 950 -1300475168855305 EAr0uf4mhq 141.142.220.118 49996 208.80.152.3 80 tcp 218501 1171 733 S1 F 1171 ShACad 4 216 4 949 -1300475168892913 slFea8xwSmb 141.142.220.118 49999 208.80.152.3 80 tcp 220960 1137 733 S1 F 1137 ShACad 4 216 4 949 -1300475169780331 2cx26uAvUPl 141.142.220.235 6705 173.192.163.128 80 tcp 0 0 0 OTH F 0 h 0 0 1 48 -1300475168724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp 119904 525 232 S1 F 525 ShACad 3 164 3 396 -1300475168855330 c4Zw9TmAE05 141.142.220.118 49997 208.80.152.3 80 tcp 219720 1125 734 S1 F 1125 ShACad 4 216 4 950 +ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +1300475167096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 73 0 0 +1300475167097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0 0 0 S0 F 0 D 1 199 0 0 +1300475167099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0 0 0 S0 F 0 D 1 179 0 0 +1300475168853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 435 0 89 SHR F 0 Cd 0 0 1 117 +1300475168854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 420 0 99 SHR F 0 Cd 0 0 1 127 +1300475168854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 391 0 183 SHR F 0 Cd 0 0 1 211 +1300475168857956 fRFu0wcOle6 141.142.220.118 32902 141.142.2.2 53 udp dns 317 0 89 SHR F 0 Cd 0 0 1 117 +1300475168858306 qSsw6ESzHV4 141.142.220.118 59816 141.142.2.2 53 udp dns 343 0 99 SHR F 0 Cd 0 0 1 127 +1300475168858713 iE6yhOq3SF 141.142.220.118 59714 141.142.2.2 53 udp dns 375 0 183 SHR F 0 Cd 0 0 1 211 +1300475168891644 qCaWGmzFtM5 141.142.220.118 58206 141.142.2.2 53 udp dns 339 0 89 SHR F 0 Cd 0 0 1 117 +1300475168892037 70MGiRM1Qf4 141.142.220.118 38911 141.142.2.2 53 udp dns 334 0 99 SHR F 0 Cd 0 0 1 127 +1300475168892414 h5DsfNtYzi1 141.142.220.118 59746 141.142.2.2 53 udp dns 420 0 183 SHR F 0 Cd 0 0 1 211 +1300475168893988 c4Zw9TmAE05 141.142.220.118 45000 141.142.2.2 53 udp dns 384 0 89 SHR F 0 Cd 0 0 1 117 +1300475168894422 EAr0uf4mhq 141.142.220.118 48479 141.142.2.2 53 udp dns 316 0 99 SHR F 0 Cd 0 0 1 127 +1300475168894787 GvmoxJFXdTa 141.142.220.118 48128 141.142.2.2 53 udp dns 422 0 183 SHR F 0 Cd 0 0 1 211 +1300475168901749 slFea8xwSmb 141.142.220.118 56056 141.142.2.2 53 udp dns 402 0 131 SHR F 0 Cd 0 0 1 159 +1300475168902195 UfGkYA2HI2g 141.142.220.118 55092 141.142.2.2 53 udp dns 374 0 198 SHR F 0 Cd 0 0 1 226 +1300475169899438 BWaU4aSuwkc 141.142.220.44 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 85 0 0 +1300475170862384 10XodEwRycf 141.142.220.226 137 141.142.220.255 137 udp dns 2613016 350 0 S0 F 0 D 7 546 0 0 +1300475171675372 zno26fFZkrh fe80::3074:17d5:2052:c324 65373 ff02::1:3 5355 udp dns 100096 66 0 S0 F 0 D 2 162 0 0 +1300475171677081 v5rgkJBig5l 141.142.220.226 55131 224.0.0.252 5355 udp dns 100020 66 0 S0 F 0 D 2 122 0 0 +1300475173116749 eWZCH7OONC1 fe80::3074:17d5:2052:c324 54213 ff02::1:3 5355 udp dns 99801 66 0 S0 F 0 D 2 162 0 0 +1300475173117362 0Pwk3ntf8O3 141.142.220.226 55671 224.0.0.252 5355 udp dns 99848 66 0 S0 F 0 D 2 122 0 0 +1300475173153679 0HKorjr8Zp7 141.142.220.238 56641 141.142.220.255 137 udp dns 0 0 0 S0 F 0 D 1 78 0 0 +1300475168859163 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 tcp 215893 1130 734 S1 F 1130 ShACad 4 216 4 950 +1300475168652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 61328 0 350 OTH F 0 CdA 1 52 1 402 +1300475168895267 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 tcp 227283 1178 734 S1 F 1178 ShACad 4 216 4 950 +1300475168902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp 120040 534 412 S1 F 534 ShACad 3 164 3 576 +1300475168892936 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 tcp 229603 1148 734 S1 F 1148 ShACad 4 216 4 950 +1300475168855305 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 tcp 218501 1171 733 S1 F 1171 ShACad 4 216 4 949 +1300475168892913 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 tcp 220960 1137 733 S1 F 1137 ShACad 4 216 4 949 +1300475169780331 2cx26uAvUPl 141.142.220.235 6705 173.192.163.128 80 tcp 0 0 0 OTH F 0 h 0 0 1 48 +1300475168724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp 119904 525 232 S1 F 525 ShACad 3 164 3 396 +1300475168855330 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 tcp 219720 1125 734 S1 F 1125 ShACad 4 216 4 950 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt index 3cafa078de..c20e38d4f3 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt @@ -28,6 +28,7 @@ + @@ -48,40 +49,41 @@ + # Extent, type='conn' -ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes -1300475167.096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 73 0 0 -1300475167.097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0.000000 0 0 S0 F 0 D 1 199 0 0 -1300475167.099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0.000000 0 0 S0 F 0 D 1 179 0 0 -1300475168.853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 0.000435 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 0.000420 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 0.000392 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.857956 3PKsZ2Uye21 141.142.220.118 32902 141.142.2.2 53 udp dns 0.000317 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.858306 VW0XPVINV8a 141.142.220.118 59816 141.142.2.2 53 udp dns 0.000343 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.858713 fRFu0wcOle6 141.142.220.118 59714 141.142.2.2 53 udp dns 0.000375 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.891644 qSsw6ESzHV4 141.142.220.118 58206 141.142.2.2 53 udp dns 0.000339 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.892037 iE6yhOq3SF 141.142.220.118 38911 141.142.2.2 53 udp dns 0.000335 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.892414 GSxOnSLghOa 141.142.220.118 59746 141.142.2.2 53 udp dns 0.000421 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.893988 qCaWGmzFtM5 141.142.220.118 45000 141.142.2.2 53 udp dns 0.000384 0 89 SHR F 0 Cd 0 0 1 117 -1300475168.894422 70MGiRM1Qf4 141.142.220.118 48479 141.142.2.2 53 udp dns 0.000317 0 99 SHR F 0 Cd 0 0 1 127 -1300475168.894787 h5DsfNtYzi1 141.142.220.118 48128 141.142.2.2 53 udp dns 0.000423 0 183 SHR F 0 Cd 0 0 1 211 -1300475168.901749 P654jzLoe3a 141.142.220.118 56056 141.142.2.2 53 udp dns 0.000402 0 131 SHR F 0 Cd 0 0 1 159 -1300475168.902195 Tw8jXtpTGu6 141.142.220.118 55092 141.142.2.2 53 udp dns 0.000374 0 198 SHR F 0 Cd 0 0 1 226 -1300475169.899438 BWaU4aSuwkc 141.142.220.44 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 85 0 0 -1300475170.862384 10XodEwRycf 141.142.220.226 137 141.142.220.255 137 udp dns 2.613017 350 0 S0 F 0 D 7 546 0 0 -1300475171.675372 zno26fFZkrh fe80::3074:17d5:2052:c324 65373 ff02::1:3 5355 udp dns 0.100096 66 0 S0 F 0 D 2 162 0 0 -1300475171.677081 v5rgkJBig5l 141.142.220.226 55131 224.0.0.252 5355 udp dns 0.100021 66 0 S0 F 0 D 2 122 0 0 -1300475173.116749 eWZCH7OONC1 fe80::3074:17d5:2052:c324 54213 ff02::1:3 5355 udp dns 0.099801 66 0 S0 F 0 D 2 162 0 0 -1300475173.117362 0Pwk3ntf8O3 141.142.220.226 55671 224.0.0.252 5355 udp dns 0.099849 66 0 S0 F 0 D 2 122 0 0 -1300475173.153679 0HKorjr8Zp7 141.142.220.238 56641 141.142.220.255 137 udp dns 0.000000 0 0 S0 F 0 D 1 78 0 0 -1300475168.859163 GvmoxJFXdTa 141.142.220.118 49998 208.80.152.3 80 tcp 0.215893 1130 734 S1 F 1130 ShACad 4 216 4 950 -1300475168.652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 0.061329 0 350 OTH F 0 CdA 1 52 1 402 -1300475168.895267 UfGkYA2HI2g 141.142.220.118 50001 208.80.152.3 80 tcp 0.227284 1178 734 S1 F 1178 ShACad 4 216 4 950 -1300475168.902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp 0.120041 534 412 S1 F 534 ShACad 3 164 3 576 -1300475168.892936 0Q4FH8sESw5 141.142.220.118 50000 208.80.152.3 80 tcp 0.229603 1148 734 S1 F 1148 ShACad 4 216 4 950 -1300475168.855305 EAr0uf4mhq 141.142.220.118 49996 208.80.152.3 80 tcp 0.218501 1171 733 S1 F 1171 ShACad 4 216 4 949 -1300475168.892913 slFea8xwSmb 141.142.220.118 49999 208.80.152.3 80 tcp 0.220961 1137 733 S1 F 1137 ShACad 4 216 4 949 -1300475169.780331 2cx26uAvUPl 141.142.220.235 6705 173.192.163.128 80 tcp 0.000000 0 0 OTH F 0 h 0 0 1 48 -1300475168.724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp 0.119905 525 232 S1 F 525 ShACad 3 164 3 396 -1300475168.855330 c4Zw9TmAE05 141.142.220.118 49997 208.80.152.3 80 tcp 0.219720 1125 734 S1 F 1125 ShACad 4 216 4 950 +ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +1300475167.096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 73 0 0 +1300475167.097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0.000000 0 0 S0 F 0 D 1 199 0 0 +1300475167.099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0.000000 0 0 S0 F 0 D 1 179 0 0 +1300475168.853899 TEfuqmmG4bh 141.142.220.118 43927 141.142.2.2 53 udp dns 0.000435 0 89 SHR F 0 Cd 0 0 1 117 +1300475168.854378 FrJExwHcSal 141.142.220.118 37676 141.142.2.2 53 udp dns 0.000420 0 99 SHR F 0 Cd 0 0 1 127 +1300475168.854837 5OKnoww6xl4 141.142.220.118 40526 141.142.2.2 53 udp dns 0.000392 0 183 SHR F 0 Cd 0 0 1 211 +1300475168.857956 fRFu0wcOle6 141.142.220.118 32902 141.142.2.2 53 udp dns 0.000317 0 89 SHR F 0 Cd 0 0 1 117 +1300475168.858306 qSsw6ESzHV4 141.142.220.118 59816 141.142.2.2 53 udp dns 0.000343 0 99 SHR F 0 Cd 0 0 1 127 +1300475168.858713 iE6yhOq3SF 141.142.220.118 59714 141.142.2.2 53 udp dns 0.000375 0 183 SHR F 0 Cd 0 0 1 211 +1300475168.891644 qCaWGmzFtM5 141.142.220.118 58206 141.142.2.2 53 udp dns 0.000339 0 89 SHR F 0 Cd 0 0 1 117 +1300475168.892037 70MGiRM1Qf4 141.142.220.118 38911 141.142.2.2 53 udp dns 0.000335 0 99 SHR F 0 Cd 0 0 1 127 +1300475168.892414 h5DsfNtYzi1 141.142.220.118 59746 141.142.2.2 53 udp dns 0.000421 0 183 SHR F 0 Cd 0 0 1 211 +1300475168.893988 c4Zw9TmAE05 141.142.220.118 45000 141.142.2.2 53 udp dns 0.000384 0 89 SHR F 0 Cd 0 0 1 117 +1300475168.894422 EAr0uf4mhq 141.142.220.118 48479 141.142.2.2 53 udp dns 0.000317 0 99 SHR F 0 Cd 0 0 1 127 +1300475168.894787 GvmoxJFXdTa 141.142.220.118 48128 141.142.2.2 53 udp dns 0.000423 0 183 SHR F 0 Cd 0 0 1 211 +1300475168.901749 slFea8xwSmb 141.142.220.118 56056 141.142.2.2 53 udp dns 0.000402 0 131 SHR F 0 Cd 0 0 1 159 +1300475168.902195 UfGkYA2HI2g 141.142.220.118 55092 141.142.2.2 53 udp dns 0.000374 0 198 SHR F 0 Cd 0 0 1 226 +1300475169.899438 BWaU4aSuwkc 141.142.220.44 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 85 0 0 +1300475170.862384 10XodEwRycf 141.142.220.226 137 141.142.220.255 137 udp dns 2.613017 350 0 S0 F 0 D 7 546 0 0 +1300475171.675372 zno26fFZkrh fe80::3074:17d5:2052:c324 65373 ff02::1:3 5355 udp dns 0.100096 66 0 S0 F 0 D 2 162 0 0 +1300475171.677081 v5rgkJBig5l 141.142.220.226 55131 224.0.0.252 5355 udp dns 0.100021 66 0 S0 F 0 D 2 122 0 0 +1300475173.116749 eWZCH7OONC1 fe80::3074:17d5:2052:c324 54213 ff02::1:3 5355 udp dns 0.099801 66 0 S0 F 0 D 2 162 0 0 +1300475173.117362 0Pwk3ntf8O3 141.142.220.226 55671 224.0.0.252 5355 udp dns 0.099849 66 0 S0 F 0 D 2 122 0 0 +1300475173.153679 0HKorjr8Zp7 141.142.220.238 56641 141.142.220.255 137 udp dns 0.000000 0 0 S0 F 0 D 1 78 0 0 +1300475168.859163 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 tcp 0.215893 1130 734 S1 F 1130 ShACad 4 216 4 950 +1300475168.652003 nQcgTWjvg4c 141.142.220.118 35634 208.80.152.2 80 tcp 0.061329 0 350 OTH F 0 CdA 1 52 1 402 +1300475168.895267 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 tcp 0.227284 1178 734 S1 F 1178 ShACad 4 216 4 950 +1300475168.902635 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 tcp 0.120041 534 412 S1 F 534 ShACad 3 164 3 576 +1300475168.892936 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 tcp 0.229603 1148 734 S1 F 1148 ShACad 4 216 4 950 +1300475168.855305 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 tcp 0.218501 1171 733 S1 F 1171 ShACad 4 216 4 949 +1300475168.892913 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 tcp 0.220961 1137 733 S1 F 1137 ShACad 4 216 4 949 +1300475169.780331 2cx26uAvUPl 141.142.220.235 6705 173.192.163.128 80 tcp 0.000000 0 0 OTH F 0 h 0 0 1 48 +1300475168.724007 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 tcp 0.119905 525 232 S1 F 525 ShACad 3 164 3 396 +1300475168.855330 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 tcp 0.219720 1125 734 S1 F 1125 ShACad 4 216 4 950 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt index adb7bb3f7b..ae62fbec3d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/http.ds.txt @@ -66,16 +66,16 @@ # Extent, type='http' ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file 1300475168.843894 j4u32Pc5bif 141.142.220.118 48649 208.80.152.118 80 0 0 0 304 Not Modified 0 -1300475168.975800 c4Zw9TmAE05 141.142.220.118 49997 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475168.976327 EAr0uf4mhq 141.142.220.118 49996 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475168.979160 GvmoxJFXdTa 141.142.220.118 49998 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.012666 0Q4FH8sESw5 141.142.220.118 50000 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.012730 slFea8xwSmb 141.142.220.118 49999 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.014860 UfGkYA2HI2g 141.142.220.118 50001 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475168.975800 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475168.976327 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475168.979160 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.012666 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.012730 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.014860 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 0 0 0 304 Not Modified 0 1300475169.022665 i2rO3KD1Syg 141.142.220.118 35642 208.80.152.2 80 0 0 0 304 Not Modified 0 -1300475169.036294 c4Zw9TmAE05 141.142.220.118 49997 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.036798 EAr0uf4mhq 141.142.220.118 49996 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.039923 GvmoxJFXdTa 141.142.220.118 49998 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.074793 0Q4FH8sESw5 141.142.220.118 50000 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.074938 slFea8xwSmb 141.142.220.118 49999 208.80.152.3 80 0 0 0 304 Not Modified 0 -1300475169.075065 UfGkYA2HI2g 141.142.220.118 50001 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.036294 VW0XPVINV8a 141.142.220.118 49997 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.036798 3PKsZ2Uye21 141.142.220.118 49996 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.039923 GSxOnSLghOa 141.142.220.118 49998 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.074793 Tw8jXtpTGu6 141.142.220.118 50000 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.074938 P654jzLoe3a 141.142.220.118 49999 208.80.152.3 80 0 0 0 304 Not Modified 0 +1300475169.075065 0Q4FH8sESw5 141.142.220.118 50001 208.80.152.3 80 0 0 0 304 Not Modified 0 From c7c3ff7af9fb1ae71c66cba892f5241043cb5b39 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 15 Jun 2012 16:01:59 -0700 Subject: [PATCH 44/51] Adding a SOCKS test case. However, I'm not sure the output is right. --- scripts/base/protocols/socks/main.bro | 101 ------------------ .../Baseline/core.tunnels.socks/conn.log | 8 ++ .../Baseline/core.tunnels.socks/http.log | 8 ++ .../btest/Baseline/core.tunnels.socks/output | 11 ++ .../Baseline/core.tunnels.socks/tunnel.log | 9 ++ testing/btest/Traces/tunnels/socks.pcap | Bin 0 -> 5446 bytes testing/btest/core/tunnels/socks.bro | 19 ++++ 7 files changed, 55 insertions(+), 101 deletions(-) create mode 100644 testing/btest/Baseline/core.tunnels.socks/conn.log create mode 100644 testing/btest/Baseline/core.tunnels.socks/http.log create mode 100644 testing/btest/Baseline/core.tunnels.socks/output create mode 100644 testing/btest/Baseline/core.tunnels.socks/tunnel.log create mode 100644 testing/btest/Traces/tunnels/socks.pcap create mode 100644 testing/btest/core/tunnels/socks.bro diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro index bd27f4fb85..54d181e43e 100644 --- a/scripts/base/protocols/socks/main.bro +++ b/scripts/base/protocols/socks/main.bro @@ -13,104 +13,3 @@ event socks_request(c: connection, request_type: count, dstaddr: addr, dstname: { Tunnel::register([$cid=c$id, $tunnel_type=Tunnel::SOCKS, $uid=c$uid]); } - -# -#global output = open_log_file("socks"); -# -#type socks_conn: record { -# id: conn_id; -# t: time; -# req: socks_request_type &optional; -# dstaddr: addr &optional; -# dstname: string &optional; -# p: port &optional; -# user: string &optional; -# service: string &optional; -# variant: string &default = "SOCKS v4"; -# granted: string &default = "no-reply"; -#}; -# -# -#global conns: table[conn_id] of socks_conn; -#global proxies: set[addr] &read_expire = 24hrs; -# -#event socks_request(c: connection, t: socks_request_type, dstaddr: addr, dstname: string, p: port, user: string) -# { -# local id = c$id; -# -# local sc: socks_conn; -# sc$id = id; -# sc$t = c$start_time; -# sc$req = t; -# -# if ( dstaddr != 0.0.0.0 ) -# sc$dstaddr = dstaddr; -# -# if ( dstname != "" ) -# sc$dstname = dstname; -# -# if ( p != 0/tcp ) -# sc$p = p; -# -# if ( user != "" ) -# sc$user = user; -# -# conns[id] = sc; -# } -# -#event socks_reply(c: connection, granted: bool, dst: addr, p: port) -# { -# local id = c$id; -# local sc: socks_conn; -# -# if ( id in conns ) -# sc = conns[id]; -# else -# { -# sc$id = id; -# sc$t = c$start_time; -# conns[id] = sc; -# } -# -# sc$granted = granted ? "ok" : "denied"; -# -# local proxy = c$id$resp_h; -# -# if ( proxy !in proxies ) -# { -# NOTICE([$note=SOCKSProxy, $src=proxy, $sub=sc$variant, -# $msg=fmt("SOCKS proxy seen at %s (%s)", proxy, sc$variant)]); -# add proxies[proxy]; -# } -# } -# -#function print_conn(sc: socks_conn) -# { -# local req = ""; -# if ( sc?$req ) -# { -# if ( sc$req == SOCKS_CONNECTION ) -# req = "relay-to"; -# if ( sc$req == SOCKS_PORT ) -# req = "bind-port"; -# } -# -# local p = sc?$p ? fmt("%s", sc$p) : ""; -# -# local dest = sc?$dstaddr -# ? (fmt("%s:%s%s", sc$dstaddr, p, (sc?$dstname ? fmt(" (%s)", sc$dstname) : ""))) -# : (sc?$dstname ? fmt("%s:%s", sc$dstname, p) : ""); -# local user = sc?$user ? fmt(" (user %s)", sc?$user) : ""; -# -# local service = sc?$service ? fmt(" [%s]", sc$service) : ""; -# -# print output, fmt("%.6f %s %s %s %s-> %s%s", sc$t, id_string(sc$id), req, -# dest, user, sc$granted, service); -# } -# -#event connection_state_remove(c: connection) -# { -# if ( c$id in conns ) -# print_conn(conns[c$id]); -# } -# diff --git a/testing/btest/Baseline/core.tunnels.socks/conn.log b/testing/btest/Baseline/core.tunnels.socks/conn.log new file mode 100644 index 0000000000..9d5ae8efb1 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.socks/conn.log @@ -0,0 +1,8 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#types time string addr port addr port enum string interval count count string bool count string count count count count table[string] +1208299429.265243 UWkUyAuUGXf 127.0.0.1 62270 127.0.0.1 1080 tcp http,socks 0.008138 152 3950 SF - 0 ShAaDdfF 9 632 9 4430 (empty) diff --git a/testing/btest/Baseline/core.tunnels.socks/http.log b/testing/btest/Baseline/core.tunnels.socks/http.log new file mode 100644 index 0000000000..2dcab3f254 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.socks/http.log @@ -0,0 +1,8 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file +#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string file +1208299429.270361 UWkUyAuUGXf 127.0.0.1 62270 127.0.0.1 1080 1 GET www.icir.org / - curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3 0 3677 200 OK - - - (empty) - - - text/html - - diff --git a/testing/btest/Baseline/core.tunnels.socks/output b/testing/btest/Baseline/core.tunnels.socks/output new file mode 100644 index 0000000000..8bf984a58a --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.socks/output @@ -0,0 +1,11 @@ +[id=[orig_h=127.0.0.1, orig_p=62270/tcp, resp_h=127.0.0.1, resp_p=1080/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=177, flow_label=0], resp=[size=8, state=4, num_pkts=3, num_bytes_ip=168, flow_label=0], start_time=1208299429.265243, duration=0.002565, service={ +SOCKS +}, addl=, hot=0, history=ShAaDd, uid=UWkUyAuUGXf, tunnel=[], dpd=, conn=[ts=1208299429.265243, uid=UWkUyAuUGXf, id=[orig_h=127.0.0.1, orig_p=62270/tcp, resp_h=127.0.0.1, resp_p=1080/tcp], proto=tcp, service=, duration=, orig_bytes=, resp_bytes=, conn_state=, local_orig=, missed_bytes=0, history=, orig_pkts=, orig_ip_bytes=, resp_pkts=, resp_ip_bytes=, parents={ + +}], extract_orig=F, extract_resp=F, dns=, dns_state=, ftp=, http=, http_state=, irc=, smtp=, smtp_state=, ssh=, ssl=, syslog=] +--- +1 +192.150.187.12 + +80/tcp + diff --git a/testing/btest/Baseline/core.tunnels.socks/tunnel.log b/testing/btest/Baseline/core.tunnels.socks/tunnel.log new file mode 100644 index 0000000000..9ccbe8af26 --- /dev/null +++ b/testing/btest/Baseline/core.tunnels.socks/tunnel.log @@ -0,0 +1,9 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p action tunnel_type +#types time string addr port addr port enum enum +1208299429.267808 UWkUyAuUGXf 127.0.0.1 62270 127.0.0.1 1080 Tunnel::DISCOVER Tunnel::SOCKS +1208299429.273401 UWkUyAuUGXf 127.0.0.1 62270 127.0.0.1 1080 Tunnel::CLOSE Tunnel::SOCKS diff --git a/testing/btest/Traces/tunnels/socks.pcap b/testing/btest/Traces/tunnels/socks.pcap new file mode 100644 index 0000000000000000000000000000000000000000..d70e2cb7dcbeefefc6e3ff9907f53a069e59e9bd GIT binary patch literal 5446 zcmcIo&2!{N6`%DERIJ260!8t0>4*Y$7fYJ)$J(CNXl;+j_7K}+JaV=cs@U{MJu|)5 zNJ@9hlgR;c;6PEu70x+u;X;Z_QpJTL2l59{l??}~_K+L5oH)Spx~2Khc)a0)s$@&8 z?qC10FBS?v zFBERb`!lDw`Q`JM9XaZ~g=f$Hvj%;O_n+LjdGqFt8!u>!I);`)p$GsH^G9sJ?fylkO|VECuk z@p>0<{tB4#&Uk(JY4bTalGporUI%p-S?JJpPpz_9UeeAvVa86Egrb7Hgay`yS-xwo zqFZq^AT0I_9LE7Me9Q(k+%ikIQ9#?%9h)%;TdgCjWNw)o0eTxg1M-Twx}+UO98d>? zfk{2e%!qZDv>neQF|^*X?ks6bnl#TJ=9uR%yZL2hZhH!P`uIBYd=nK5zkIQv?$kUl z{^F7U92_vu;xKQXkzvqEsf3!ZEopmLkP31WvW&{>XeVa!%O+Y`sjRJ5*0#{WvAd+T z2)iV#0-v$hBi0Hm|1P?Rw>_2 z!RjvVR*+s^TPu}_LDqevys@#h1=H#y^BHG2>=Ir`oTTq^)TZ^RL|XgV^ccDes!-|b0418K`X~c z==6N|s8K_@VObAWYnHX=?xi2r%u*S-42PV`nQ&lP^%Gt12@zK;OZtAWDm`zxXKJc7 zD~N!K=?h3vJi%=K|M0_fc=uwVvA|enZVPJYcouxwqaxd+|nP^kT(;0S=C2Yl8e`om)fkV&#?mKk+HeCzGakk$L3-f z5F}tw*4N`)chENN#}N|<_RK9^^)cm#+xL)dsaMAqR0PCvdjvIVtp++FVi2(l8g|hE zi;@@_s0p&Uq-0=QX+qkPE zJoA2;e|My@59>R7^)qQIf!naGcEo%FQV57U9b)b0uE{hvg+d%E&#yb z_D923S78(|=!R82ARPgQvjliyeh&}SN*D-WadC0PTzne3A-Qx8JfgTEa)rO^1REY{VswXP}SkVlBzNv$6bBejW`fhJ)73T z6OxiW(3O@^N^qN}=%{h>8al3@oTHPS*Bb{rZlif3wc*ptktwByz?Yw|mKgi~NG&s- zlUf-&qK!ELP$EJ7YZR0DEVCeboiGlu1(nSb>=`7(DTy8`6pcp${&D5wYjKPqR#!PDzRZJNUA!=aOh0qS77=5ro z7*qXY5`bOdKl%XeuGl z$s}-QVcM}fka-~eHXDFp|k3uM$Q(%DqwuRej_`XySrJVRy=_ zSwm_jIZYOX)rLspwPUw~$h&wmi3D*pO|xT1lNo9(hpEhcB}C~?L&oh;c@GDu7WLx< z8nl*2N$5eIgJetvG)W3b=5p8$p%JsF1KC}sYV{SKkTyG`4<+Id_oB%3qP}%Tx@kFa z{;2inQAmi6p5-Bwa5lA+|_Vq-<2*RNc zJp)z3OwC0(K=5UlNFt`Nn1Qcp3|$e1a_y1?Lunw1J)Y~ z??Tli>-+CRT|RsKp>O5u^6dEY@#BRz%GcHR@82mFPT&YG@3g)z{_wX(9w$8~yir!? z1gP&9?&s@!DFYm%Hh7qZKqq0T%#_pQbeZHeyX` z;SE`2XJyW~7@n^D#yi)vYR%J!$`UQzsYUTnl|`^Nh#D%+nz^#kZbOwijkFK`=trPO z8iH&3Dt05>j*{%S1qlXDAh*Rn;G$zeK z)*%QY&HhdjCR}a+72c>ADxJU%!r?HF4SPlEvj;yM@ChT_PB_VPnqo9tgHIbjt03n| zOdhcy%&QZlj8Y##beWA(cV?o?Bue=Q*F~wPb8!Ct)p=3MKTuKX<@vv|{c{e^KVHb= uO!2w)$E;6(aCKcD&HvR8qOX7W&NY1gH3#Qs-^=q!qpyDm>v}TJKK})-%m&W@ literal 0 HcmV?d00001 diff --git a/testing/btest/core/tunnels/socks.bro b/testing/btest/core/tunnels/socks.bro new file mode 100644 index 0000000000..8ab288c9bd --- /dev/null +++ b/testing/btest/core/tunnels/socks.bro @@ -0,0 +1,19 @@ +# @TEST-EXEC: bro -Cr $TRACES/tunnels/socks.pcap %INPUT >output +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff tunnel.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.log + +event socks_request(c: connection, request_type: count, dstaddr: addr, + dstname: string, p: port, user: string) + { + print c; + print "---"; + print request_type; + print dstaddr; + print dstname; + print p; + print user; + } + + From 146cb47d6ae76c1478569bca3dfb60cc44fcb700 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 18 Jun 2012 11:11:07 -0500 Subject: [PATCH 45/51] Fix performance problem checking packet encapsulation. (addresses #830) Connections were creating a new encapsulation object for nearly every packet even if no tunnels were ever involved with the Connection. --- src/Conn.cc | 12 +++++++++--- testing/btest/Baseline/core.tunnels.socks/output | 4 +--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Conn.cc b/src/Conn.cc index 18d52f8a12..f3ebaca0c9 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -205,20 +205,26 @@ void Connection::CheckEncapsulation(const Encapsulation* arg_encap) if ( encapsulation && arg_encap ) { if ( *encapsulation != *arg_encap ) + { Event(tunnel_changed, 0, arg_encap->GetVectorVal()); + delete encapsulation; + encapsulation = new Encapsulation(arg_encap); + } } else if ( encapsulation ) { Encapsulation empty; Event(tunnel_changed, 0, empty.GetVectorVal()); + delete encapsulation; + encapsulation = new Encapsulation(arg_encap); } else if ( arg_encap ) + { Event(tunnel_changed, 0, arg_encap->GetVectorVal()); - - delete encapsulation; - encapsulation = new Encapsulation(arg_encap); + encapsulation = new Encapsulation(arg_encap); + } } void Connection::Done() diff --git a/testing/btest/Baseline/core.tunnels.socks/output b/testing/btest/Baseline/core.tunnels.socks/output index 8bf984a58a..ee5c5b5c20 100644 --- a/testing/btest/Baseline/core.tunnels.socks/output +++ b/testing/btest/Baseline/core.tunnels.socks/output @@ -1,8 +1,6 @@ [id=[orig_h=127.0.0.1, orig_p=62270/tcp, resp_h=127.0.0.1, resp_p=1080/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=177, flow_label=0], resp=[size=8, state=4, num_pkts=3, num_bytes_ip=168, flow_label=0], start_time=1208299429.265243, duration=0.002565, service={ SOCKS -}, addl=, hot=0, history=ShAaDd, uid=UWkUyAuUGXf, tunnel=[], dpd=, conn=[ts=1208299429.265243, uid=UWkUyAuUGXf, id=[orig_h=127.0.0.1, orig_p=62270/tcp, resp_h=127.0.0.1, resp_p=1080/tcp], proto=tcp, service=, duration=, orig_bytes=, resp_bytes=, conn_state=, local_orig=, missed_bytes=0, history=, orig_pkts=, orig_ip_bytes=, resp_pkts=, resp_ip_bytes=, parents={ - -}], extract_orig=F, extract_resp=F, dns=, dns_state=, ftp=, http=, http_state=, irc=, smtp=, smtp_state=, ssh=, ssl=, syslog=] +}, addl=, hot=0, history=ShAaDd, uid=UWkUyAuUGXf, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dns=, dns_state=, ftp=, http=, http_state=, irc=, smtp=, smtp_state=, ssh=, ssl=, syslog=] --- 1 192.150.187.12 From f3b3e73eba1dba81aa35f477d6a20ebdd54cf7a8 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 18 Jun 2012 12:29:49 -0500 Subject: [PATCH 46/51] Script-layer tunnel interface cleanup. - Clarify "tunnel_changed" event documentation. - Make expiration of "Tunnel::active" elements configuration via "Tunnel::expiration_interval". - Remove redundant registration of a connection's tunnels in tunnel/main.bro's "tunnel_changed" handler. - Rename "parents" field of "Conn::Info" to "tunnel_parents" to give more context. --- scripts/base/frameworks/tunnels/main.bro | 15 +++++++++------ scripts/base/protocols/conn/main.bro | 6 +++--- src/event.bif | 8 +++++--- .../Baseline/core.print-bpf-filters/conn.log | 2 +- .../btest/Baseline/core.print-bpf-filters/output | 8 ++++---- .../btest/Baseline/core.tunnels.ayiya/conn.log | 2 +- .../btest/Baseline/core.tunnels.socks/conn.log | 2 +- .../btest/Baseline/core.tunnels.teredo/conn.log | 2 +- testing/btest/Baseline/core.vlan-mpls/conn.log | 2 +- .../scripts.base.protocols.ftp.ftp-ipv4/conn.log | 2 +- .../scripts.base.protocols.ftp.ftp-ipv6/conn.log | 2 +- 11 files changed, 28 insertions(+), 23 deletions(-) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 1f0258e0a3..2f5625f8b2 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -17,7 +17,8 @@ export { DISCOVER, ## A tunnel connection has closed. CLOSE, - ## No new connections over a tunnel happened in the past day. + ## No new connections over a tunnel happened in the amount of + ## time indicated by :bro:see:`Tunnel::expiration_interval`. EXPIRE, }; @@ -68,9 +69,14 @@ export { ## action: The specific reason for the tunnel ending. global close: function(tunnel: Info, action: Action); + ## The amount of time a tunnel is not used in establishment of new + ## connections before it is considered inactive/expired. + const expiration_interval = 24hrs &redef; + ## Currently active tunnels. That is, tunnels for which new, encapsulated - ## connections have been seen in the last day. - global active: table[conn_id] of Info = table() &synchronized &read_expire=24hrs &expire_func=expire; + ## connections have been seen in the interval indicated by + ## :bro:see:`Tunnel::expiration_interval`. + global active: table[conn_id] of Info = table() &synchronized &read_expire=expiration_interval &expire_func=expire; } const ayiya_ports = { 5072/udp }; @@ -129,9 +135,6 @@ event new_connection(c: connection) &priority=5 event tunnel_changed(c: connection, e: EncapsulatingConnVector) &priority=5 { - if ( c?$tunnel ) - register_all(c$tunnel); - register_all(e); } diff --git a/scripts/base/protocols/conn/main.bro b/scripts/base/protocols/conn/main.bro index 432bb12e84..5796c3c6b1 100644 --- a/scripts/base/protocols/conn/main.bro +++ b/scripts/base/protocols/conn/main.bro @@ -104,7 +104,7 @@ export { ## If this connection was over a tunnel, indicate the ## *uid* values for any encapsulating parent connections ## used over the lifetime of this inner connection. - parents: set[string] &log; + tunnel_parents: set[string] &log; }; ## Event that can be handled to access the :bro:type:`Conn::Info` @@ -195,7 +195,7 @@ function set_conn(c: connection, eoc: bool) c$conn$uid=c$uid; c$conn$id=c$id; if ( c?$tunnel && |c$tunnel| > 0 ) - add c$conn$parents[c$tunnel[|c$tunnel|-1]$uid]; + add c$conn$tunnel_parents[c$tunnel[|c$tunnel|-1]$uid]; c$conn$proto=get_port_transport_proto(c$id$resp_p); if( |Site::local_nets| > 0 ) c$conn$local_orig=Site::is_local_addr(c$id$orig_h); @@ -238,7 +238,7 @@ event tunnel_changed(c: connection, e: EncapsulatingConnVector) &priority=5 { set_conn(c, F); if ( |e| > 0 ) - add c$conn$parents[e[|e|-1]$uid]; + add c$conn$tunnel_parents[e[|e|-1]$uid]; c$tunnel = e; } diff --git a/src/event.bif b/src/event.bif index 0531bb8a18..72c033cd75 100644 --- a/src/event.bif +++ b/src/event.bif @@ -143,9 +143,11 @@ event new_connection%(c: connection%); ## Generated for a connection whose tunneling has changed. This could ## be from a previously seen connection now being encapsulated in a tunnel, -## or from the outer encapsulation changing. Note that the connection's -## *tunnel* field is NOT automatically assigned to the new encapsulation value -## internally after this event is raised. +## or from the outer encapsulation changing. Note that connection *c*'s +## *tunnel* field is NOT automatically/internally assigned to the new +## encapsulation value of *e* after this event is raised. If the desired +## behavior is to track the latest tunnel encapsulation per-connection, +## then a handler of this event should assign *e* to ``c$tunnel``. ## ## c: The connection whose tunnel/encapsulation changed. ## diff --git a/testing/btest/Baseline/core.print-bpf-filters/conn.log b/testing/btest/Baseline/core.print-bpf-filters/conn.log index ca81844a4a..b563c4a3ed 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/conn.log +++ b/testing/btest/Baseline/core.print-bpf-filters/conn.log @@ -3,6 +3,6 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 1128727435.450898 UWkUyAuUGXf 141.42.64.125 56730 125.190.109.199 80 tcp http 1.733303 98 9417 SF - 0 ShADdFaf 12 730 10 9945 (empty) diff --git a/testing/btest/Baseline/core.print-bpf-filters/output b/testing/btest/Baseline/core.print-bpf-filters/output index b4a52965cb..0560b34769 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/output +++ b/testing/btest/Baseline/core.print-bpf-filters/output @@ -5,7 +5,7 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1335456050.312960 - ip or not ip T T +1340040469.440535 - ip or not ip T T #separator \x09 #set_separator , #empty_field (empty) @@ -13,7 +13,7 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1335456050.557822 - ((((((((((((((((((((((((port 53) or (tcp port 989)) or (tcp port 443)) or (port 6669)) or (udp and port 5353)) or (port 6668)) or (udp and port 5355)) or (tcp port 22)) or (tcp port 995)) or (port 21)) or (tcp port 25 or tcp port 587)) or (port 6667)) or (tcp port 614)) or (tcp port 990)) or (udp port 137)) or (tcp port 993)) or (tcp port 5223)) or (port 514)) or (tcp port 585)) or (tcp port 992)) or (tcp port 563)) or (tcp port 994)) or (tcp port 636)) or (tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888))) or (port 6666) T T +1340040469.681428 - ((((((((((((((((((((((((port 53) or (tcp port 989)) or (tcp port 443)) or (port 6669)) or (udp and port 5353)) or (port 6668)) or (udp and port 5355)) or (tcp port 22)) or (tcp port 995)) or (port 21)) or (tcp port 25 or tcp port 587)) or (port 6667)) or (tcp port 614)) or (tcp port 990)) or (udp port 137)) or (tcp port 993)) or (tcp port 5223)) or (port 514)) or (tcp port 585)) or (tcp port 992)) or (tcp port 563)) or (tcp port 994)) or (tcp port 636)) or (tcp and port (80 or 81 or 631 or 1080 or 3138 or 8000 or 8080 or 8888))) or (port 6666) T T #separator \x09 #set_separator , #empty_field (empty) @@ -21,7 +21,7 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1335456050.805695 - port 42 T T +1340040469.925663 - port 42 T T #separator \x09 #set_separator , #empty_field (empty) @@ -29,4 +29,4 @@ #path packet_filter #fields ts node filter init success #types time string string bool bool -1335456051.042953 - port 56730 T T +1340040470.169001 - port 56730 T T diff --git a/testing/btest/Baseline/core.tunnels.ayiya/conn.log b/testing/btest/Baseline/core.tunnels.ayiya/conn.log index 5c23b4c404..db54a8a475 100644 --- a/testing/btest/Baseline/core.tunnels.ayiya/conn.log +++ b/testing/btest/Baseline/core.tunnels.ayiya/conn.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 1257655301.595604 5OKnoww6xl4 2001:4978:f:4c::2 53382 2001:4860:b002::68 80 tcp http 2.101052 2981 4665 S1 - 0 ShADad 10 3605 11 5329 k6kgXLOoSKl 1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 udp ayiya 20.879001 5129 6109 SF - 0 Dd 21 5717 13 6473 (empty) diff --git a/testing/btest/Baseline/core.tunnels.socks/conn.log b/testing/btest/Baseline/core.tunnels.socks/conn.log index 9d5ae8efb1..f8a684d4c6 100644 --- a/testing/btest/Baseline/core.tunnels.socks/conn.log +++ b/testing/btest/Baseline/core.tunnels.socks/conn.log @@ -3,6 +3,6 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 1208299429.265243 UWkUyAuUGXf 127.0.0.1 62270 127.0.0.1 1080 tcp http,socks 0.008138 152 3950 SF - 0 ShAaDdfF 9 632 9 4430 (empty) diff --git a/testing/btest/Baseline/core.tunnels.teredo/conn.log b/testing/btest/Baseline/core.tunnels.teredo/conn.log index 151230886b..cefc8f3e84 100644 --- a/testing/btest/Baseline/core.tunnels.teredo/conn.log +++ b/testing/btest/Baseline/core.tunnels.teredo/conn.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 1210953047.736921 arKYeMETxOg 192.168.2.16 1576 75.126.130.163 80 tcp - 0.000357 0 0 SHR - 0 fA 1 40 1 40 (empty) 1210953050.867067 k6kgXLOoSKl 192.168.2.16 1577 75.126.203.78 80 tcp - 0.000387 0 0 SHR - 0 fA 1 40 1 40 (empty) diff --git a/testing/btest/Baseline/core.vlan-mpls/conn.log b/testing/btest/Baseline/core.vlan-mpls/conn.log index 20903d1db8..e165df621a 100644 --- a/testing/btest/Baseline/core.vlan-mpls/conn.log +++ b/testing/btest/Baseline/core.vlan-mpls/conn.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 952109346.874907 UWkUyAuUGXf 10.1.2.1 11001 10.34.0.1 23 tcp - 2.102560 26 0 SH - 0 SADF 11 470 0 0 (empty) 1128727435.450898 arKYeMETxOg 141.42.64.125 56730 125.190.109.199 80 tcp http 1.733303 98 9417 SF - 0 ShADdFaf 12 730 10 9945 (empty) diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log index 5704153b07..4a20ec39b4 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv4/conn.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 1329843175.736107 arKYeMETxOg 141.142.220.235 37604 199.233.217.249 56666 tcp ftp-data 0.112432 0 342 SF - 0 ShAdfFa 4 216 4 562 (empty) 1329843179.871641 k6kgXLOoSKl 141.142.220.235 59378 199.233.217.249 56667 tcp ftp-data 0.111218 0 77 SF - 0 ShAdfFa 4 216 4 297 (empty) diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log index e3d458bae7..9d19ffaf85 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.ftp-ipv6/conn.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path conn -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents #types time string addr port addr port enum string interval count count string bool count string count count count count table[string] 1329327783.316897 arKYeMETxOg 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49186 2001:470:4867:99::21 57086 tcp ftp-data 0.219721 0 342 SF - 0 ShAdfFa 5 372 4 642 (empty) 1329327786.524332 k6kgXLOoSKl 2001:470:1f11:81f:c999:d94:aa7c:2e3e 49187 2001:470:4867:99::21 57087 tcp ftp-data 0.217501 0 43 SF - 0 ShAdfFa 5 372 4 343 (empty) From 2ba3f5420b13ddc0f2cb173a2ccb41a716972f98 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 18 Jun 2012 12:48:03 -0500 Subject: [PATCH 47/51] Add "encap_hdr_size" option back in. The "tunnel_port" and "parse_udp_tunnels" options are still gone as those did not work entirely (e.g. IPv6 support and misnaming of tunnel_port/udp_tunnel_port). --- scripts/base/init-bare.bro | 4 ++++ src/NetVar.cc | 4 ++++ src/NetVar.h | 2 ++ src/Sessions.cc | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 879a4f5995..503bf2547c 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -915,6 +915,10 @@ const frag_timeout = 0.0 sec &redef; ## to be potentially copied and buffered. const packet_sort_window = 0 usecs &redef; +## If positive, indicates the encapsulation header size that should +## be skipped. This applies to all packets. +const encap_hdr_size = 0 &redef; + ## Whether to use the ``ConnSize`` analyzer to count the number of packets and ## IP-level bytes transfered by each endpoint. If true, these values are returned ## in the connection's :bro:see:`endpoint` record value. diff --git a/src/NetVar.cc b/src/NetVar.cc index 70aa60c886..b057efad11 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -30,6 +30,8 @@ int partial_connection_ok; int tcp_SYN_ack_ok; int tcp_match_undelivered; +int encap_hdr_size; + double frag_timeout; double tcp_SYN_timeout; @@ -323,6 +325,8 @@ void init_net_var() tcp_SYN_ack_ok = opt_internal_int("tcp_SYN_ack_ok"); tcp_match_undelivered = opt_internal_int("tcp_match_undelivered"); + encap_hdr_size = opt_internal_int("encap_hdr_size"); + frag_timeout = opt_internal_double("frag_timeout"); tcp_SYN_timeout = opt_internal_double("tcp_SYN_timeout"); diff --git a/src/NetVar.h b/src/NetVar.h index 7aff9b84e6..e6f6e0cfc4 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -33,6 +33,8 @@ extern int partial_connection_ok; extern int tcp_SYN_ack_ok; extern int tcp_match_undelivered; +extern int encap_hdr_size; + extern double frag_timeout; extern double tcp_SYN_timeout; diff --git a/src/Sessions.cc b/src/Sessions.cc index c754a14698..b5d82f147f 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -158,6 +158,10 @@ void NetSessions::DispatchPacket(double t, const struct pcap_pkthdr* hdr, ip_data = pkt + hdr_size + (ip_hdr->ip_hl << 2); } + if ( encap_hdr_size > 0 && ip_data ) + // Blanket encapsulation + hdr_size += encap_hdr_size; + if ( src_ps->FilterType() == TYPE_FILTER_NORMAL ) NextPacket(t, hdr, pkt, hdr_size, pkt_elem); else From e04d6297330f4872c97588131f31abacce780acb Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 18 Jun 2012 15:44:34 -0500 Subject: [PATCH 48/51] Add state management of NetSessions's IP tunnel map. Entries are checked for inactivity at an interval controlled by "Tunnel::ip_tunnel_timeout" and discarded if needed. --- scripts/base/init-bare.bro | 3 +++ src/Sessions.cc | 28 +++++++++++++++++++++++++--- src/Sessions.h | 20 +++++++++++++++++++- src/Timer.cc | 1 + src/Timer.h | 1 + src/const.bif | 1 + 6 files changed, 50 insertions(+), 4 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 503bf2547c..3a57a65b20 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2717,6 +2717,9 @@ export { ## reduce false positives of UDP traffic (e.g. DNS) that also happens ## to have a valid Teredo encapsulation. const yielding_teredo_decapsulation = T &redef; + + ## How often to cleanup internal state for inactive IP tunnels. + const ip_tunnel_timeout = 24hrs &redef; } # end export module GLOBAL; diff --git a/src/Sessions.cc b/src/Sessions.cc index b5d82f147f..84c881b0ef 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -68,6 +68,24 @@ void TimerMgrExpireTimer::Dispatch(double t, int is_expire) } } +void IPTunnelTimer::Dispatch(double t, int is_expire) + { + NetSessions::IPTunnelMap::const_iterator it = + sessions->ip_tunnels.find(tunnel_idx); + + if ( it == sessions->ip_tunnels.end() ) return; + + double last_active = it->second.second; + double inactive_time = t > last_active ? t - last_active : 0; + + if ( inactive_time >= BifConst::Tunnel::ip_tunnel_timeout ) + // tunnel activity timed out, delete it from map + sessions->ip_tunnels.erase(tunnel_idx); + else if ( ! is_expire ) + // tunnel activity didn't timeout, schedule another timer + timer_mgr->Add(new IPTunnelTimer(t, tunnel_idx)); + } + NetSessions::NetSessions() { TypeList* t = new TypeList(); @@ -569,16 +587,20 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, else tunnel_idx = IPPair(ip_hdr->DstAddr(), ip_hdr->SrcAddr()); - IPTunnelMap::const_iterator it = ip_tunnels.find(tunnel_idx); + IPTunnelMap::iterator it = ip_tunnels.find(tunnel_idx); if ( it == ip_tunnels.end() ) { EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr()); - ip_tunnels[tunnel_idx] = ec; + ip_tunnels[tunnel_idx] = TunnelActivity(ec, network_time); + timer_mgr->Add(new IPTunnelTimer(network_time, tunnel_idx)); outer->Add(ec); } else - outer->Add(it->second); + { + it->second.second = network_time; + outer->Add(it->second.first); + } DoNextInnerPacket(t, hdr, inner, outer); diff --git a/src/Sessions.h b/src/Sessions.h index ed7f56c878..548c0903be 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -181,6 +181,7 @@ protected: friend class RemoteSerializer; friend class ConnCompressor; friend class TimerMgrExpireTimer; + friend class IPTunnelTimer; Connection* NewConn(HashKey* k, double t, const ConnID* id, const u_char* data, int proto, uint32 flow_lable, @@ -240,8 +241,10 @@ protected: PDict(Connection) udp_conns; PDict(Connection) icmp_conns; PDict(FragReassembler) fragments; + typedef pair IPPair; - typedef std::map IPTunnelMap; + typedef pair TunnelActivity; + typedef std::map IPTunnelMap; IPTunnelMap ip_tunnels; ARP_Analyzer* arp_analyzer; @@ -261,6 +264,21 @@ protected: TimerMgrMap timer_mgrs; }; + +class IPTunnelTimer : public Timer { +public: + IPTunnelTimer(double t, NetSessions::IPPair p) + : Timer(t + BifConst::Tunnel::ip_tunnel_timeout, + TIMER_IP_TUNNEL_INACTIVITY), tunnel_idx(p) {} + + ~IPTunnelTimer() {} + + void Dispatch(double t, int is_expire); + +protected: + NetSessions::IPPair tunnel_idx; +}; + // Manager for the currently active sessions. extern NetSessions* sessions; diff --git a/src/Timer.cc b/src/Timer.cc index 2e2fb09c6b..c2a8bb3421 100644 --- a/src/Timer.cc +++ b/src/Timer.cc @@ -20,6 +20,7 @@ const char* TimerNames[] = { "IncrementalSendTimer", "IncrementalWriteTimer", "InterconnTimer", + "IPTunnelInactivityTimer", "NetbiosExpireTimer", "NetworkTimer", "NTPExpireTimer", diff --git a/src/Timer.h b/src/Timer.h index bb6b8d56ae..310e72bdc9 100644 --- a/src/Timer.h +++ b/src/Timer.h @@ -26,6 +26,7 @@ enum TimerType { TIMER_INCREMENTAL_SEND, TIMER_INCREMENTAL_WRITE, TIMER_INTERCONN, + TIMER_IP_TUNNEL_INACTIVITY, TIMER_NB_EXPIRE, TIMER_NETWORK, TIMER_NTP_EXPIRE, diff --git a/src/const.bif b/src/const.bif index 368ee34396..499dc63314 100644 --- a/src/const.bif +++ b/src/const.bif @@ -16,5 +16,6 @@ const Tunnel::enable_ip: bool; const Tunnel::enable_ayiya: bool; const Tunnel::enable_teredo: bool; const Tunnel::yielding_teredo_decapsulation: bool; +const Tunnel::ip_tunnel_timeout: interval; const Threading::heartbeat_interval: interval; From ce58a3e90864a00027ec5ecabdf71e4f0eaa93f4 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 18 Jun 2012 16:56:19 -0500 Subject: [PATCH 49/51] Refactor of interal tunnel analysis code. - Pulled more common code into NetSessions::DoNextInnerPacket() and made the pcap header it makes internally use network_time - Remove Encapsulation class ctor from pointer - Rename Encapsulation class to EncapsulationStack --- src/Conn.cc | 14 +++++++------- src/Conn.h | 8 ++++---- src/Sessions.cc | 37 +++++++++++++++++++++---------------- src/Sessions.h | 21 +++++++++++++-------- src/Teredo.cc | 9 ++------- src/TunnelEncapsulation.cc | 2 +- src/TunnelEncapsulation.h | 26 ++++++++++---------------- src/ayiya-analyzer.pac | 8 ++------ 8 files changed, 60 insertions(+), 65 deletions(-) diff --git a/src/Conn.cc b/src/Conn.cc index f3ebaca0c9..bc2e7fb5cf 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -113,7 +113,7 @@ unsigned int Connection::external_connections = 0; IMPLEMENT_SERIAL(Connection, SER_CONNECTION); Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, - uint32 flow, const Encapsulation* arg_encap) + uint32 flow, const EncapsulationStack* arg_encap) { sessions = s; key = k; @@ -162,7 +162,7 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, uid = 0; // Will set later. if ( arg_encap ) - encapsulation = new Encapsulation(arg_encap); + encapsulation = new EncapsulationStack(*arg_encap); else encapsulation = 0; @@ -200,7 +200,7 @@ Connection::~Connection() --external_connections; } -void Connection::CheckEncapsulation(const Encapsulation* arg_encap) +void Connection::CheckEncapsulation(const EncapsulationStack* arg_encap) { if ( encapsulation && arg_encap ) { @@ -208,22 +208,22 @@ void Connection::CheckEncapsulation(const Encapsulation* arg_encap) { Event(tunnel_changed, 0, arg_encap->GetVectorVal()); delete encapsulation; - encapsulation = new Encapsulation(arg_encap); + encapsulation = new EncapsulationStack(*arg_encap); } } else if ( encapsulation ) { - Encapsulation empty; + EncapsulationStack empty; Event(tunnel_changed, 0, empty.GetVectorVal()); delete encapsulation; - encapsulation = new Encapsulation(arg_encap); + encapsulation = 0; } else if ( arg_encap ) { Event(tunnel_changed, 0, arg_encap->GetVectorVal()); - encapsulation = new Encapsulation(arg_encap); + encapsulation = new EncapsulationStack(*arg_encap); } } diff --git a/src/Conn.h b/src/Conn.h index b3798cfb36..782d41a801 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -52,7 +52,7 @@ class Analyzer; class Connection : public BroObj { public: Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, - uint32 flow, const Encapsulation* arg_encap); + uint32 flow, const EncapsulationStack* arg_encap); virtual ~Connection(); // Invoked when an encapsulation is discovered. It records the @@ -60,7 +60,7 @@ public: // event if it's different from the previous encapsulation (or the // first encountered). encap can be null to indicate no // encapsulation. - void CheckEncapsulation(const Encapsulation* encap); + void CheckEncapsulation(const EncapsulationStack* encap); // Invoked when connection is about to be removed. Use Ref(this) // inside Done to keep the connection object around (though it'll @@ -252,7 +252,7 @@ public: uint64 GetUID() const { return uid; } - const Encapsulation* GetEncapsulation() const + const EncapsulationStack* GetEncapsulation() const { return encapsulation; } void CheckFlowLabel(bool is_orig, uint32 flow_label); @@ -292,7 +292,7 @@ protected: double inactivity_timeout; RecordVal* conn_val; LoginConn* login_conn; // either nil, or this - const Encapsulation* encapsulation; // tunnels + const EncapsulationStack* encapsulation; // tunnels int suppress_event; // suppress certain events to once per conn. unsigned int installed_status_timer:1; diff --git a/src/Sessions.cc b/src/Sessions.cc index 84c881b0ef..10126f45b1 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -367,7 +367,7 @@ int NetSessions::CheckConnectionTag(Connection* conn) void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size, const Encapsulation* encapsulation) + int hdr_size, const EncapsulationStack* encapsulation) { uint32 caplen = hdr->caplen - hdr_size; const struct ip* ip4 = ip_hdr->IP4_Hdr(); @@ -576,8 +576,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, return; } - Encapsulation* outer = new Encapsulation(encapsulation); - // Look up to see if we've already seen this IP tunnel, identified // by the pair of IP addresses, so that we can always associate the // same UID with it. @@ -594,18 +592,13 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr()); ip_tunnels[tunnel_idx] = TunnelActivity(ec, network_time); timer_mgr->Add(new IPTunnelTimer(network_time, tunnel_idx)); - outer->Add(ec); } else - { it->second.second = network_time; - outer->Add(it->second.first); - } - DoNextInnerPacket(t, hdr, inner, outer); + DoNextInnerPacket(t, hdr, inner, encapsulation, + ip_tunnels[tunnel_idx].first); - delete inner; - delete outer; Remove(f); return; } @@ -724,7 +717,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, } void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, - const IP_Hdr* inner, const Encapsulation* outer) + const IP_Hdr* inner, const EncapsulationStack* prev, + const EncapsulatingConn& ec) { struct pcap_pkthdr fake_hdr; fake_hdr.caplen = fake_hdr.len = inner->TotalLen(); @@ -732,7 +726,11 @@ void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, if ( hdr ) fake_hdr.ts = hdr->ts; else - fake_hdr.ts.tv_sec = fake_hdr.ts.tv_usec = 0; + { + fake_hdr.ts.tv_sec = (time_t) network_time; + fake_hdr.ts.tv_usec = (suseconds_t) + ((network_time - (double)fake_hdr.ts.tv_sec) * 1000000); + } const u_char* pkt = 0; @@ -741,7 +739,14 @@ void NetSessions::DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, else pkt = (const u_char*) inner->IP6_Hdr(); + EncapsulationStack* outer = prev ? + new EncapsulationStack(*prev) : new EncapsulationStack(); + outer->Add(ec); + DoNextPacket(t, &fake_hdr, inner, pkt, 0, outer); + + delete inner; + delete outer; } int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto, @@ -778,7 +783,7 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto, bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, const struct pcap_pkthdr* h, - const u_char* p, const Encapsulation* encap) + const u_char* p, const EncapsulationStack* encap) { uint32 min_hdr_len = 0; switch ( proto ) { @@ -1110,7 +1115,7 @@ void NetSessions::GetStats(SessionStats& s) const Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, const u_char* data, int proto, uint32 flow_label, - const Encapsulation* encapsulation) + const EncapsulationStack* encapsulation) { // FIXME: This should be cleaned up a bit, it's too protocol-specific. // But I'm not yet sure what the right abstraction for these things is. @@ -1331,7 +1336,7 @@ void NetSessions::Internal(const char* msg, const struct pcap_pkthdr* hdr, } void NetSessions::Weird(const char* name, const struct pcap_pkthdr* hdr, - const u_char* pkt, const Encapsulation* encap) + const u_char* pkt, const EncapsulationStack* encap) { if ( hdr ) dump_this_packet = 1; @@ -1343,7 +1348,7 @@ void NetSessions::Weird(const char* name, const struct pcap_pkthdr* hdr, } void NetSessions::Weird(const char* name, const IP_Hdr* ip, - const Encapsulation* encap) + const EncapsulationStack* encap) { if ( encap && encap->LastType() != BifEnum::Tunnel::NONE ) reporter->Weird(ip->SrcAddr(), ip->DstAddr(), diff --git a/src/Sessions.h b/src/Sessions.h index 548c0903be..613eebe5ca 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -16,7 +16,7 @@ struct pcap_pkthdr; -class Encapsulation; +class EncapsulationStack; class Connection; class ConnID; class OSFingerprint; @@ -109,9 +109,9 @@ public: void GetStats(SessionStats& s) const; void Weird(const char* name, const struct pcap_pkthdr* hdr, - const u_char* pkt, const Encapsulation* encap = 0); + const u_char* pkt, const EncapsulationStack* encap = 0); void Weird(const char* name, const IP_Hdr* ip, - const Encapsulation* encap = 0); + const EncapsulationStack* encap = 0); PacketFilter* GetPacketFilter() { @@ -137,7 +137,7 @@ public: void DoNextPacket(double t, const struct pcap_pkthdr* hdr, const IP_Hdr* ip_hdr, const u_char* const pkt, - int hdr_size, const Encapsulation* encapsulation); + int hdr_size, const EncapsulationStack* encapsulation); /** * Wrapper that recurses on DoNextPacket for encapsulated IP packets. @@ -147,10 +147,15 @@ public: * so that the fake pcap header passed to DoNextPacket will use * the same timeval. The caplen and len fields of the fake pcap * header are always set to the TotalLength() of \a inner. - * @param outer The encapsulation information for the inner IP packet. + * @param inner Pointer to IP header wrapper of the inner packet, ownership + * of the pointer's memory is assumed by this function. + * @param prev Any previous encapsulation stack of the caller, not including + * the most-recently found depth of encapsulation. + * @param ec The most-recently found depth of encapsulation. */ void DoNextInnerPacket(double t, const struct pcap_pkthdr* hdr, - const IP_Hdr* inner, const Encapsulation* outer); + const IP_Hdr* inner, const EncapsulationStack* prev, + const EncapsulatingConn& ec); /** * Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4 @@ -185,7 +190,7 @@ protected: Connection* NewConn(HashKey* k, double t, const ConnID* id, const u_char* data, int proto, uint32 flow_lable, - const Encapsulation* encapsulation); + const EncapsulationStack* encapsulation); // Check whether the tag of the current packet is consistent with // the given connection. Returns: @@ -234,7 +239,7 @@ protected: // than that protocol's minimum header size. bool CheckHeaderTrunc(int proto, uint32 len, uint32 caplen, const struct pcap_pkthdr* hdr, const u_char* pkt, - const Encapsulation* encap); + const EncapsulationStack* encap); CompositeHash* ch; PDict(Connection) tcp_conns; diff --git a/src/Teredo.cc b/src/Teredo.cc index e537edb916..ac68bdbed1 100644 --- a/src/Teredo.cc +++ b/src/Teredo.cc @@ -149,7 +149,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, return; } - const Encapsulation* e = Conn()->GetEncapsulation(); + const EncapsulationStack* e = Conn()->GetEncapsulation(); if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) { @@ -222,12 +222,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, Conn()->Event(teredo_bubble, 0, teredo_hdr); } - Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(Conn(), BifEnum::Tunnel::TEREDO); - outer->Add(ec); - sessions->DoNextInnerPacket(network_time, 0, inner, outer); - - delete inner; - delete outer; + sessions->DoNextInnerPacket(network_time, 0, inner, e, ec); } diff --git a/src/TunnelEncapsulation.cc b/src/TunnelEncapsulation.cc index f023a40b6a..edbabef81f 100644 --- a/src/TunnelEncapsulation.cc +++ b/src/TunnelEncapsulation.cc @@ -34,7 +34,7 @@ RecordVal* EncapsulatingConn::GetRecordVal() const return rv; } -bool operator==(const Encapsulation& e1, const Encapsulation& e2) +bool operator==(const EncapsulationStack& e1, const EncapsulationStack& e2) { if ( ! e1.conns ) return e2.conns; diff --git a/src/TunnelEncapsulation.h b/src/TunnelEncapsulation.h index 9dcf134536..e8ca7a48b6 100644 --- a/src/TunnelEncapsulation.h +++ b/src/TunnelEncapsulation.h @@ -114,12 +114,12 @@ protected: /** * Abstracts an arbitrary amount of nested tunneling. */ -class Encapsulation { +class EncapsulationStack { public: - Encapsulation() : conns(0) + EncapsulationStack() : conns(0) {} - Encapsulation(const Encapsulation& other) + EncapsulationStack(const EncapsulationStack& other) { if ( other.conns ) conns = new vector(*(other.conns)); @@ -127,15 +127,7 @@ public: conns = 0; } - Encapsulation(const Encapsulation* other) - { - if ( other && other->conns ) - conns = new vector(*(other->conns)); - else - conns = 0; - } - - Encapsulation& operator=(const Encapsulation& other) + EncapsulationStack& operator=(const EncapsulationStack& other) { if ( this == &other ) return *this; @@ -150,10 +142,10 @@ public: return *this; } - ~Encapsulation() { delete conns; } + ~EncapsulationStack() { delete conns; } /** - * Add a new inner-most tunnel to the Encapsulation. + * Add a new inner-most tunnel to the EncapsulationStack. * * @param c The new inner-most tunnel to append to the tunnel chain. */ @@ -200,9 +192,11 @@ public: return vv; } - friend bool operator==(const Encapsulation& e1, const Encapsulation& e2); + friend bool operator==(const EncapsulationStack& e1, + const EncapsulationStack& e2); - friend bool operator!=(const Encapsulation& e1, const Encapsulation& e2) + friend bool operator!=(const EncapsulationStack& e1, + const EncapsulationStack& e2) { return ! ( e1 == e2 ); } diff --git a/src/ayiya-analyzer.pac b/src/ayiya-analyzer.pac index f1b144ff44..89d1143ad7 100644 --- a/src/ayiya-analyzer.pac +++ b/src/ayiya-analyzer.pac @@ -12,7 +12,7 @@ flow AYIYA_Flow function process_ayiya(pdu: PDU): bool %{ Connection *c = connection()->bro_analyzer()->Conn(); - const Encapsulation* e = c->GetEncapsulation(); + const EncapsulationStack* e = c->GetEncapsulation(); if ( e && e->Depth() >= BifConst::Tunnel::max_depth ) { @@ -72,14 +72,10 @@ flow AYIYA_Flow if ( result != 0 ) return false; - Encapsulation* outer = new Encapsulation(e); EncapsulatingConn ec(c, BifEnum::Tunnel::AYIYA); - outer->Add(ec); - sessions->DoNextInnerPacket(network_time(), 0, inner, outer); + sessions->DoNextInnerPacket(network_time(), 0, inner, e, ec); - delete inner; - delete outer; return (result == 0) ? true : false; %} From d6286d953d0d0c34096ebbe9bec4b25ed2d72565 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 18 Jun 2012 17:04:46 -0500 Subject: [PATCH 50/51] Remove &synchronized from Tunnel::active table. --- scripts/base/frameworks/tunnels/main.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/frameworks/tunnels/main.bro b/scripts/base/frameworks/tunnels/main.bro index 2f5625f8b2..869c501fe6 100644 --- a/scripts/base/frameworks/tunnels/main.bro +++ b/scripts/base/frameworks/tunnels/main.bro @@ -76,7 +76,7 @@ export { ## Currently active tunnels. That is, tunnels for which new, encapsulated ## connections have been seen in the interval indicated by ## :bro:see:`Tunnel::expiration_interval`. - global active: table[conn_id] of Info = table() &synchronized &read_expire=expiration_interval &expire_func=expire; + global active: table[conn_id] of Info = table() &read_expire=expiration_interval &expire_func=expire; } const ayiya_ports = { 5072/udp }; From cf593f13e0f664051bae119ea56b3f02441e18a1 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 18 Jun 2012 15:58:52 -0700 Subject: [PATCH 51/51] Updating baselines and NEWS. --- NEWS | 4 ++-- .../conn.ds.txt | 6 +++--- .../conn.ds.txt | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 66bf8b040c..75bb78130f 100644 --- a/NEWS +++ b/NEWS @@ -60,8 +60,8 @@ Bro 2.1 signature_files constant, this can be used to load signatures relative to the current script (e.g., "@load-sigs ./foo.sig"). -- The options encap_hdr_size and tunnel_port have been removed. Bro - now supports decapsulating tunnels directly for protocols it +- The options "tunnel_port" and "parse_udp_tunnels" have been removed. + Bro now supports decapsulating tunnels directly for protocols it understands. TODO: Extend. diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt index 620babdd4c..c4ac546ab6 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.time-as-int/conn.ds.txt @@ -28,7 +28,7 @@ - + @@ -49,10 +49,10 @@ - + # Extent, type='conn' -ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents 1300475167096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0 0 0 S0 F 0 D 1 73 0 0 1300475167097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0 0 0 S0 F 0 D 1 199 0 0 1300475167099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0 0 0 S0 F 0 D 1 179 0 0 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt index c20e38d4f3..b74b9fd7e3 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.dataseries.wikipedia/conn.ds.txt @@ -28,7 +28,7 @@ - + @@ -49,10 +49,10 @@ - + # Extent, type='conn' -ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes parents +ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents 1300475167.096535 UWkUyAuUGXf 141.142.220.202 5353 224.0.0.251 5353 udp dns 0.000000 0 0 S0 F 0 D 1 73 0 0 1300475167.097012 arKYeMETxOg fe80::217:f2ff:fed7:cf65 5353 ff02::fb 5353 udp 0.000000 0 0 S0 F 0 D 1 199 0 0 1300475167.099816 k6kgXLOoSKl 141.142.220.50 5353 224.0.0.251 5353 udp 0.000000 0 0 S0 F 0 D 1 179 0 0