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.
This commit is contained in:
Seth Hall 2012-04-24 01:05:35 -04:00
parent ae96314196
commit 2a79fe95ec
12 changed files with 53 additions and 122 deletions

View file

@ -10,7 +10,7 @@ export {
type Info: record { type Info: record {
ts: time &log; ts: time &log;
uid: string &log; uid: string &log &optional;
id: conn_id &log; id: conn_id &log;
action: Action &log; action: Action &log;
tunnel_type: string &log; tunnel_type: string &log;

View file

@ -2631,21 +2631,7 @@ module Tunnel;
export { export {
## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4) ## Whether to decapsulate IP tunnels (IPinIP, 6in4, 6to4)
const decapsulate_ip = T &redef; 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. ## The maximum depth of a tunnel to decapsulate until giving up.
const max_depth: count = 2 &redef; const max_depth: count = 2 &redef;
} # end export } # end export

View file

@ -101,6 +101,9 @@ export {
resp_pkts: count &log &optional; resp_pkts: count &log &optional;
## Number IP level bytes the responder sent. See ``orig_pkts``. ## Number IP level bytes the responder sent. See ``orig_pkts``.
resp_ip_bytes: count &log &optional; 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` ## 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$ts=c$start_time;
c$conn$uid=c$uid; c$conn$uid=c$uid;
c$conn$id=c$id; 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); c$conn$proto=get_port_transport_proto(c$id$resp_p);
if( |Site::local_nets| > 0 ) if( |Site::local_nets| > 0 )
c$conn$local_orig=Site::is_local_addr(c$id$orig_h); c$conn$local_orig=Site::is_local_addr(c$id$orig_h);

View file

@ -1,13 +1,10 @@
#include "AYIYA.h" #include "AYIYA.h"
#include "TCP_Reassembler.h"
AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn) AYIYA_Analyzer::AYIYA_Analyzer(Connection* conn)
: Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn) : Analyzer(AnalyzerTag::SYSLOG_BINPAC, conn)
{ {
interp = new binpac::AYIYA::AYIYA_Conn(this); interp = new binpac::AYIYA::AYIYA_Conn(this);
did_session_done = 0; did_session_done = 0;
//ADD_ANALYZER_TIMER(&AYIYA_Analyzer::ExpireTimer,
// network_time + Syslog_session_timeout, 1, TIMER_Syslog_EXPIRE);
} }
AYIYA_Analyzer::~AYIYA_Analyzer() 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); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
interp->NewData(orig, data, data + len); 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);
// }

View file

@ -1,9 +1,6 @@
#ifndef AYIYA_h #ifndef AYIYA_h
#define AYIYA_h #define AYIYA_h
#include "UDP.h"
#include "TCP.h"
#include "ayiya_pac.h" #include "ayiya_pac.h"
class AYIYA_Analyzer : public Analyzer { class AYIYA_Analyzer : public Analyzer {
@ -19,7 +16,7 @@ public:
{ return new AYIYA_Analyzer(conn); } { return new AYIYA_Analyzer(conn); }
static bool Available() static bool Available()
{ return true; } { return BifConst::Tunnel::decapsulate_ip; }
protected: protected:
friend class AnalyzerTimer; friend class AnalyzerTimer;
@ -30,26 +27,4 @@ protected:
binpac::AYIYA::AYIYA_Conn* interp; 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 #endif

View file

@ -129,9 +129,6 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
Syslog_Analyzer_binpac::InstantiateAnalyzer, Syslog_Analyzer_binpac::InstantiateAnalyzer,
Syslog_Analyzer_binpac::Available, 0, false }, Syslog_Analyzer_binpac::Available, 0, false },
//{ AnalyzerTag::6to4, "6to4",
// 6to4_Analyzer::InstantiateAnalyzer,
// 6to4_Anylzer::Available, 0, false },
{ AnalyzerTag::AYIYA, "AYIYA", { AnalyzerTag::AYIYA, "AYIYA",
AYIYA_Analyzer::InstantiateAnalyzer, AYIYA_Analyzer::InstantiateAnalyzer,
AYIYA_Analyzer::Available, 0, false }, AYIYA_Analyzer::Available, 0, false },

View file

@ -34,7 +34,6 @@ namespace AnalyzerTag {
HTTP_BINPAC, SSL, SYSLOG_BINPAC, HTTP_BINPAC, SSL, SYSLOG_BINPAC,
// Decapsulation Analyzers // Decapsulation Analyzers
//6to4,
AYIYA, AYIYA,
SOCKS, SOCKS,
//Teredo, //Teredo,

View file

@ -245,7 +245,9 @@ public:
void SetTransport(TransportProto arg_proto) { proto = arg_proto; } void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
void SetUID(uint64 arg_uid) { uid = arg_uid; } void SetUID(uint64 arg_uid) { uid = arg_uid; }
Encapsulation* GetEncapsulation() { return &encapsulation; }
protected: protected:
Connection() { persistent = 0; } Connection() { persistent = 0; }

View file

@ -131,6 +131,10 @@ public:
return tcp_conns.Length() + udp_conns.Length() + return tcp_conns.Length() + udp_conns.Length() +
icmp_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 ConnectionMemoryUsage();
unsigned int ConnectionMemoryUsageConnVals(); unsigned int ConnectionMemoryUsageConnVals();
@ -174,10 +178,6 @@ protected:
const u_char* const pkt, int hdr_size, const u_char* const pkt, int hdr_size,
PacketSortElement* pkt_elem); 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, void NextPacketSecondary(double t, const struct pcap_pkthdr* hdr,
const u_char* const pkt, int hdr_size, const u_char* const pkt, int hdr_size,
const PktSrc* src_ps); const PktSrc* src_ps);

View file

@ -11,10 +11,37 @@ flow AYIYA_Flow
function process_ayiya(pdu: PDU): bool function process_ayiya(pdu: PDU): bool
%{ %{
connection()->bro_analyzer()->ProtocolConfirmation(); Connection *c = connection()->bro_analyzer()->Conn();
// Not sure what to do here. if ( c->GetEncapsulation()->Depth() >= BifConst::Tunnel::max_depth )
printf("packet: %s\n", ${pdu.packet}.data()); {
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; return true;
%} %}

View file

@ -12,7 +12,4 @@ const NFS3::return_data_max: count;
const NFS3::return_data_first_only: bool; const NFS3::return_data_first_only: bool;
const Tunnel::decapsulate_ip: 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; const Tunnel::max_depth: count;

View file

@ -178,8 +178,7 @@ enum Type %{
IP4_IN_IP6, IP4_IN_IP6,
IP6_IN_UDP, IP6_IN_UDP,
IP4_IN_UDP, IP4_IN_UDP,
IP6_IN_AYIAY, AYIYA,
IP4_IN_AYIAY,
%} %}
type EncapsulatingConn: record; type EncapsulatingConn: record;