mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Merge branch 'topic/tunnels' of git://git.bro-ids.org/bro into topic/tunnels
This commit is contained in:
commit
ae96314196
20 changed files with 695 additions and 2 deletions
|
@ -149,3 +149,40 @@ 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"
|
||||
#}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
|
|
4
scripts/base/frameworks/tunnels/__load__.bro
Normal file
4
scripts/base/frameworks/tunnels/__load__.bro
Normal file
|
@ -0,0 +1,4 @@
|
|||
@load ./main
|
||||
|
||||
const ports = { 5072/udp } &redef;
|
||||
redef dpd_config += { [ANALYZER_AYIYA] = [$ports = ports] };
|
53
scripts/base/frameworks/tunnels/main.bro
Normal file
53
scripts/base/frameworks/tunnels/main.bro
Normal file
|
@ -0,0 +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();
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
@ -36,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
|
||||
|
|
1
scripts/base/protocols/socks/__load__.bro
Normal file
1
scripts/base/protocols/socks/__load__.bro
Normal file
|
@ -0,0 +1 @@
|
|||
@load ./main
|
116
scripts/base/protocols/socks/main.bro
Normal file
116
scripts/base/protocols/socks/main.bro
Normal file
|
@ -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 = "<unknown-type>";
|
||||
# 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) : "<no-port>";
|
||||
#
|
||||
# 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) : "<no-dest>");
|
||||
# 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]);
|
||||
# }
|
||||
#
|
90
src/AYIYA.cc
Normal file
90
src/AYIYA.cc
Normal file
|
@ -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);
|
||||
// }
|
55
src/AYIYA.h
Normal file
55
src/AYIYA.h
Normal file
|
@ -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
|
|
@ -4,6 +4,7 @@
|
|||
#include "PIA.h"
|
||||
#include "Event.h"
|
||||
|
||||
#include "AYIYA.h"
|
||||
#include "BackDoor.h"
|
||||
#include "BitTorrent.h"
|
||||
#include "BitTorrentTracker.h"
|
||||
|
@ -33,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"
|
||||
|
@ -127,6 +129,19 @@ 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::SOCKS, "SOCKS",
|
||||
SOCKS_Analyzer::InstantiateAnalyzer,
|
||||
SOCKS_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",
|
||||
|
|
|
@ -33,11 +33,16 @@ namespace AnalyzerTag {
|
|||
DHCP_BINPAC, DNS_TCP_BINPAC, DNS_UDP_BINPAC,
|
||||
HTTP_BINPAC, SSL, SYSLOG_BINPAC,
|
||||
|
||||
// Decapsulation Analyzers
|
||||
//6to4,
|
||||
AYIYA,
|
||||
SOCKS,
|
||||
//Teredo,
|
||||
|
||||
// Other
|
||||
File, Backdoor, InterConn, SteppingStone, TCPStats,
|
||||
ConnSize,
|
||||
|
||||
|
||||
// Support-analyzers
|
||||
Contents, ContentLine, NVT, Zip, Contents_DNS, Contents_NCP,
|
||||
Contents_NetbiosSSN, Contents_Rlogin, Contents_Rsh,
|
||||
|
|
|
@ -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
|
||||
|
@ -205,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
|
||||
|
@ -277,6 +282,7 @@ set(bro_SRCS
|
|||
Anon.cc
|
||||
ARP.cc
|
||||
Attr.cc
|
||||
AYIYA.cc
|
||||
BackDoor.cc
|
||||
Base64.cc
|
||||
BitTorrent.cc
|
||||
|
@ -375,6 +381,7 @@ set(bro_SRCS
|
|||
SmithWaterman.cc
|
||||
SMB.cc
|
||||
SMTP.cc
|
||||
SOCKS.cc
|
||||
SSH.cc
|
||||
SSL-binpac.cc
|
||||
Scope.cc
|
||||
|
|
79
src/SOCKS.cc
Normal file
79
src/SOCKS.cc
Normal file
|
@ -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);
|
||||
}
|
||||
|
45
src/SOCKS.h
Normal file
45
src/SOCKS.h
Normal file
|
@ -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
|
25
src/ayiya-analyzer.pac
Normal file
25
src/ayiya-analyzer.pac
Normal file
|
@ -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);
|
||||
};
|
14
src/ayiya-protocol.pac
Normal file
14
src/ayiya-protocol.pac
Normal file
|
@ -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;
|
10
src/ayiya.pac
Normal file
10
src/ayiya.pac
Normal file
|
@ -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
|
|
@ -5987,6 +5987,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
|
||||
|
|
57
src/socks-analyzer.pac
Normal file
57
src/socks-analyzer.pac
Normal file
|
@ -0,0 +1,57 @@
|
|||
|
||||
%header{
|
||||
StringVal* array_to_string(vector<uint8> *a);
|
||||
%}
|
||||
|
||||
%code{
|
||||
StringVal* array_to_string(vector<uint8> *a)
|
||||
{
|
||||
int len = a->size();
|
||||
char tmp[len];
|
||||
char *s = tmp;
|
||||
for ( vector<uint8>::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<SOCKS_Analyzer*>(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<SOCKS_Analyzer*>(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);
|
||||
};
|
34
src/socks-protocol.pac
Normal file
34
src/socks-protocol.pac
Normal file
|
@ -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;
|
24
src/socks.pac
Normal file
24
src/socks.pac
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue