mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/seth/tunnels-merge'
* origin/topic/seth/tunnels-merge: SOCKS DPD fixes. Fix a bug in the SOCKS analyzer. SOCKS and tunnel test updates. Updates for the SOCKS analyzer. Very small updates to the tunnels framework.
This commit is contained in:
commit
6cda00c75e
30 changed files with 524 additions and 127 deletions
24
CHANGES
24
CHANGES
|
@ -1,4 +1,28 @@
|
|||
|
||||
2.0-698 | 2012-06-20 14:30:40 -0700
|
||||
|
||||
* Updates for the SOCKS analyzer (Seth Hall).
|
||||
|
||||
- A SOCKS log!
|
||||
|
||||
- Now supports SOCKSv5 in the analyzer and the DPD sigs.
|
||||
|
||||
- Added protocol violations.
|
||||
|
||||
* Updates to the tunnels framework. (Seth Hall)
|
||||
|
||||
- Make the uid field optional since it's conceptually incorrect
|
||||
for proxies being treated as tunnels to have it.
|
||||
|
||||
- Reordered two fields in the log.
|
||||
|
||||
- Reduced the default tunnel expiration interface to something
|
||||
more reasonable (1 hour).
|
||||
|
||||
* Make Teredo bubble packet parsing more lenient. (Jon Siwek)
|
||||
|
||||
* Fix a crash in NetSessions::ParseIPPacket(). (Jon Siwek)
|
||||
|
||||
2.0-690 | 2012-06-18 16:01:33 -0700
|
||||
|
||||
* Support for decapsulating tunnels via the new tunnel framework in
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.0-690
|
||||
2.0-698
|
||||
|
|
|
@ -162,33 +162,50 @@ signature dpd_teredo {
|
|||
enable "teredo"
|
||||
}
|
||||
|
||||
signature dpd_socks_client {
|
||||
signature dpd_socks4_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 {
|
||||
signature dpd_socks4_server {
|
||||
ip-proto == tcp
|
||||
requires-reverse-signature dpd_socks_client
|
||||
requires-reverse-signature dpd_socks4_client
|
||||
payload /^\x00[\x5a\x5b\x5c\x5d]/
|
||||
tcp-state responder
|
||||
enable "socks"
|
||||
}
|
||||
|
||||
signature dpd_socks_reverse_client {
|
||||
signature dpd_socks4_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 {
|
||||
signature dpd_socks4_reverse_server {
|
||||
ip-proto == tcp
|
||||
requires-reverse-signature dpd_socks_client
|
||||
requires-reverse-signature dpd_socks4_reverse_client
|
||||
payload /^\x00[\x5a\x5b\x5c\x5d]/
|
||||
tcp-state originator
|
||||
enable "socks"
|
||||
}
|
||||
|
||||
signature dpd_socks5_client {
|
||||
ip-proto == tcp
|
||||
# Watch for a few authentication methods to reduce false positives.
|
||||
payload /^\x05.[\x00\x01\x02]/
|
||||
tcp-state originator
|
||||
}
|
||||
|
||||
signature dpd_socks5_server {
|
||||
ip-proto == tcp
|
||||
requires-reverse-signature dpd_socks5_client
|
||||
# Watch for a single authentication method to be chosen by the server.
|
||||
payload /^\x05\x01[\x00\x01\x02]/
|
||||
tcp-state responder
|
||||
enable "socks"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,17 +28,20 @@ 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;
|
||||
## This is optional because there could be numerous connections
|
||||
## for payload proxies like SOCKS but we should treat it as a single
|
||||
## tunnel.
|
||||
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;
|
||||
## The type of activity that occurred.
|
||||
action: Action &log;
|
||||
};
|
||||
|
||||
## Logs all tunnels in an ecapsulation chain with action
|
||||
## Logs all tunnels in an encapsulation 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);
|
||||
|
@ -71,7 +74,7 @@ export {
|
|||
|
||||
## 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;
|
||||
const expiration_interval = 1hrs &redef;
|
||||
|
||||
## Currently active tunnels. That is, tunnels for which new, encapsulated
|
||||
## connections have been seen in the interval indicated by
|
||||
|
@ -104,7 +107,8 @@ function register(ec: EncapsulatingConn)
|
|||
{
|
||||
local tunnel: Info;
|
||||
tunnel$ts = network_time();
|
||||
tunnel$uid = ec$uid;
|
||||
if ( ec?$uid )
|
||||
tunnel$uid = ec$uid;
|
||||
tunnel$id = ec$cid;
|
||||
tunnel$action = DISCOVER;
|
||||
tunnel$tunnel_type = ec$tunnel_type;
|
||||
|
|
|
@ -191,7 +191,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;
|
||||
uid: string &optional;
|
||||
} &log;
|
||||
} # end export
|
||||
module GLOBAL;
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
@load ./consts
|
||||
@load ./main
|
40
scripts/base/protocols/socks/consts.bro
Normal file
40
scripts/base/protocols/socks/consts.bro
Normal file
|
@ -0,0 +1,40 @@
|
|||
module SOCKS;
|
||||
|
||||
export {
|
||||
type RequestType: enum {
|
||||
CONNECTION = 1,
|
||||
PORT = 2,
|
||||
};
|
||||
|
||||
const v5_authentication_methods: table[count] of string = {
|
||||
[0] = "No Authentication Required",
|
||||
[1] = "GSSAPI",
|
||||
[2] = "Username/Password",
|
||||
[3] = "Challenge-Handshake Authentication Protocol",
|
||||
[5] = "Challenge-Response Authentication Method",
|
||||
[6] = "Secure Sockets Layer",
|
||||
[7] = "NDS Authentication",
|
||||
[8] = "Multi-Authentication Framework",
|
||||
[255] = "No Acceptable Methods",
|
||||
} &default=function(i: count):string { return fmt("unknown-%d", i); };
|
||||
|
||||
const v4_status: table[count] of string = {
|
||||
[0x5a] = "succeeded",
|
||||
[0x5b] = "general SOCKS server failure",
|
||||
[0x5c] = "request failed because client is not running identd",
|
||||
[0x5d] = "request failed because client's identd could not confirm the user ID string in the request",
|
||||
} &default=function(i: count):string { return fmt("unknown-%d", i); };
|
||||
|
||||
const v5_status: table[count] of string = {
|
||||
[0] = "succeeded",
|
||||
[1] = "general SOCKS server failure",
|
||||
[2] = "connection not allowed by ruleset",
|
||||
[3] = "Network unreachable",
|
||||
[4] = "Host unreachable",
|
||||
[5] = "Connection refused",
|
||||
[6] = "TTL expired",
|
||||
[7] = "Command not supported",
|
||||
[8] = "Address type not supported",
|
||||
} &default=function(i: count):string { return fmt("unknown-%d", i); };
|
||||
|
||||
}
|
|
@ -1,15 +1,98 @@
|
|||
@load base/frameworks/tunnels
|
||||
@load ./consts
|
||||
|
||||
module SOCKS;
|
||||
|
||||
export {
|
||||
type RequestType: enum {
|
||||
CONNECTION = 1,
|
||||
PORT = 2,
|
||||
redef enum Log::ID += { LOG };
|
||||
|
||||
type Info: record {
|
||||
## Time when the proxy connection was first detected.
|
||||
ts: time &log;
|
||||
uid: string &log;
|
||||
id: conn_id &log;
|
||||
## Protocol version of SOCKS.
|
||||
version: count &log;
|
||||
## Username for the proxy if extracted from the network.
|
||||
user: string &log &optional;
|
||||
## Server status for the attempt at using the proxy.
|
||||
status: string &log &optional;
|
||||
## Client requested address. Mutually exclusive with req_name.
|
||||
req_h: addr &log &optional;
|
||||
## Client requested domain name. Mutually exclusive with req_h.
|
||||
req_name: string &log &optional;
|
||||
## Client requested port.
|
||||
req_p: port &log &optional;
|
||||
## Server bound address. Mutually exclusive with bound_name.
|
||||
bound_h: addr &log &optional;
|
||||
## Server bound domain name. Mutually exclusive with bound_h.
|
||||
bound_name: string &log &optional;
|
||||
## Server bound port.
|
||||
bound_p: port &log &optional;
|
||||
};
|
||||
|
||||
## Event that can be handled to access the SOCKS
|
||||
## record as it is sent on to the logging framework.
|
||||
global log_socks: event(rec: Info);
|
||||
}
|
||||
|
||||
event socks_request(c: connection, request_type: count, dstaddr: addr, dstname: string, p: port, user: string)
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Tunnel::register([$cid=c$id, $tunnel_type=Tunnel::SOCKS, $uid=c$uid]);
|
||||
Log::create_stream(SOCKS::LOG, [$columns=Info, $ev=log_socks]);
|
||||
}
|
||||
|
||||
redef record connection += {
|
||||
socks: SOCKS::Info &optional;
|
||||
};
|
||||
|
||||
# Configure DPD
|
||||
redef capture_filters += { ["socks"] = "tcp port 1080" };
|
||||
redef dpd_config += { [ANALYZER_SOCKS] = [$ports = set(1080/tcp)] };
|
||||
redef likely_server_ports += { 1080/tcp };
|
||||
|
||||
function set_session(c: connection, version: count)
|
||||
{
|
||||
if ( ! c?$socks )
|
||||
c$socks = [$ts=network_time(), $id=c$id, $uid=c$uid, $version=version];
|
||||
}
|
||||
|
||||
event socks_request(c: connection, version: count, request_type: count,
|
||||
dstaddr: addr, dstname: string, p: port, user: string) &priority=5
|
||||
{
|
||||
set_session(c, version);
|
||||
|
||||
if ( dstaddr != [::] )
|
||||
c$socks$req_h = dstaddr;
|
||||
if ( dstname != "" )
|
||||
c$socks$req_name = dstname;
|
||||
c$socks$req_p = p;
|
||||
|
||||
# Copy this conn_id and set the orig_p to zero because in the case of SOCKS proxies there will
|
||||
# be potentially many source ports since a new proxy connection is established for each
|
||||
# proxied connection. We treat this as a singular "tunnel".
|
||||
local cid = copy(c$id);
|
||||
cid$orig_p = 0/tcp;
|
||||
Tunnel::register([$cid=cid, $tunnel_type=Tunnel::SOCKS, $payload_proxy=T]);
|
||||
}
|
||||
|
||||
event socks_reply(c: connection, version: count, reply: count, dstaddr: addr, dstname: string, p: port) &priority=5
|
||||
{
|
||||
set_session(c, version);
|
||||
|
||||
if ( version == 5 )
|
||||
c$socks$status = v5_status[reply];
|
||||
else if ( version == 4 )
|
||||
c$socks$status = v4_status[reply];
|
||||
|
||||
if ( dstaddr != [::] )
|
||||
c$socks$bound_h = dstaddr;
|
||||
if ( dstname != "" )
|
||||
c$socks$bound_name = dstname;
|
||||
|
||||
c$socks$bound_p = p;
|
||||
}
|
||||
|
||||
event socks_reply(c: connection, version: count, reply: count, dstaddr: addr, dstname: string, p: port) &priority=-5
|
||||
{
|
||||
Log::write(SOCKS::LOG, c$socks);
|
||||
}
|
||||
|
|
|
@ -6226,7 +6226,9 @@ event signature_match%(state: signature_state, msg: string, data: string%);
|
|||
##
|
||||
## c: The parent connection of the proxy.
|
||||
##
|
||||
## t: The type of the request.
|
||||
## version: The version of SOCKS this message used.
|
||||
##
|
||||
## request_type: The type of the request.
|
||||
##
|
||||
## dstaddr: Address that the tunneled traffic should be sent to.
|
||||
##
|
||||
|
@ -6234,13 +6236,23 @@ event signature_match%(state: signature_state, msg: string, data: string%);
|
|||
##
|
||||
## 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%);
|
||||
## user: Username given for the SOCKS connection. This is not yet implemented for SOCKSv5.
|
||||
event socks_request%(c: connection, version: count, request_type: count, dstaddr: addr, dstname: string, p: port, user: string%);
|
||||
|
||||
## Generated when a SOCKS reply is analyzed.
|
||||
##
|
||||
## c: The parent connection of the proxy.
|
||||
##
|
||||
event socks_reply%(c: connection, granted: bool, dst: addr, p: port%);
|
||||
## version: The version of SOCKS this message used.
|
||||
##
|
||||
## reply: The status reply from the server.
|
||||
##
|
||||
## dstaddr: The address that the server sent the traffic to.
|
||||
##
|
||||
## dstname: The name the server sent the traffic to. Only applicable for SOCKSv5.
|
||||
##
|
||||
## p: The destination port for the proxied traffic.
|
||||
event socks_reply%(c: connection, version: count, reply: count, dstaddr: addr, dstname: string, 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
|
||||
|
|
|
@ -19,39 +19,169 @@ StringVal* array_to_string(vector<uint8> *a)
|
|||
%}
|
||||
|
||||
refine connection SOCKS_Conn += {
|
||||
function socks_request(cmd: uint8, dstaddr: uint32, dstname: uint8[], p: uint16, user: uint8[]): bool
|
||||
|
||||
function socks4_request(request: SOCKS4_Request): bool
|
||||
%{
|
||||
|
||||
StringVal *dstname = 0;
|
||||
if ( ${request.v4a} )
|
||||
dstname = array_to_string(${request.name});
|
||||
else
|
||||
dstname = new StringVal("");
|
||||
|
||||
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));
|
||||
4,
|
||||
${request.command},
|
||||
new AddrVal(htonl(${request.addr})),
|
||||
dstname,
|
||||
new PortVal(${request.port} | TCP_PORT_MASK),
|
||||
array_to_string(${request.user}));
|
||||
|
||||
static_cast<SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(true);
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
function socks_reply(granted: bool, dst: uint32, p: uint16): bool
|
||||
function socks4_reply(reply: SOCKS4_Reply): bool
|
||||
%{
|
||||
BifEvent::generate_socks_reply(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
granted,
|
||||
new AddrVal(htonl(dst)),
|
||||
new PortVal(p | TCP_PORT_MASK));
|
||||
4,
|
||||
${reply.status},
|
||||
new AddrVal(htonl(${reply.addr})),
|
||||
new StringVal(""),
|
||||
new PortVal(${reply.port} | TCP_PORT_MASK));
|
||||
|
||||
bro_analyzer()->ProtocolConfirmation();
|
||||
static_cast<SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(false);
|
||||
return true;
|
||||
%}
|
||||
|
||||
function socks5_request(request: SOCKS5_Request): bool
|
||||
%{
|
||||
if ( ${request.reserved} != 0 )
|
||||
{
|
||||
bro_analyzer()->ProtocolViolation(fmt("invalid value in reserved field: %d", ${request.reserved}));
|
||||
return false;
|
||||
}
|
||||
|
||||
AddrVal *ip_addr = 0;
|
||||
StringVal *domain_name = 0;
|
||||
|
||||
// This is dumb and there must be a better way (checking for presence of a field)...
|
||||
switch ( ${request.remote_name.addr_type} )
|
||||
{
|
||||
case 1:
|
||||
ip_addr = new AddrVal(htonl(${request.remote_name.ipv4}));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
domain_name = new StringVal(${request.remote_name.domain_name.name}.length(),
|
||||
(const char*) ${request.remote_name.domain_name.name}.data());
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ip_addr = new AddrVal(IPAddr(IPv6, (const uint32_t*) ${request.remote_name.ipv6}, IPAddr::Network));
|
||||
break;
|
||||
|
||||
default:
|
||||
bro_analyzer()->ProtocolViolation(fmt("invalid SOCKSv5 addr type: %d", ${request.remote_name.addr_type}));
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! ip_addr )
|
||||
ip_addr = new AddrVal(uint32(0));
|
||||
|
||||
if ( ! domain_name )
|
||||
domain_name = new StringVal("");
|
||||
|
||||
BifEvent::generate_socks_request(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
5,
|
||||
${request.command},
|
||||
ip_addr,
|
||||
domain_name,
|
||||
new PortVal(${request.port} | TCP_PORT_MASK),
|
||||
new StringVal(""));
|
||||
|
||||
static_cast<SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(true);
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
function socks5_reply(reply: SOCKS5_Reply): bool
|
||||
%{
|
||||
AddrVal *ip_addr = 0;
|
||||
StringVal *domain_name = 0;
|
||||
|
||||
// This is dumb and there must be a better way (checking for presence of a field)...
|
||||
switch ( ${reply.bound.addr_type} )
|
||||
{
|
||||
case 1:
|
||||
ip_addr = new AddrVal(htonl(${reply.bound.ipv4}));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
domain_name = new StringVal(${reply.bound.domain_name.name}.length(),
|
||||
(const char*) ${reply.bound.domain_name.name}.data());
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ip_addr = new AddrVal(IPAddr(IPv6, (const uint32_t*) ${reply.bound.ipv6}, IPAddr::Network));
|
||||
break;
|
||||
|
||||
default:
|
||||
bro_analyzer()->ProtocolViolation(fmt("invalid SOCKSv5 addr type: %d", ${reply.bound.addr_type}));
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! ip_addr )
|
||||
ip_addr = new AddrVal(uint32(0));
|
||||
|
||||
if ( ! domain_name )
|
||||
domain_name = new StringVal("");
|
||||
|
||||
BifEvent::generate_socks_reply(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
5,
|
||||
${reply.reply},
|
||||
ip_addr,
|
||||
domain_name,
|
||||
new PortVal(${reply.port} | TCP_PORT_MASK));
|
||||
|
||||
bro_analyzer()->ProtocolConfirmation();
|
||||
static_cast<SOCKS_Analyzer*>(bro_analyzer())->EndpointDone(false);
|
||||
return true;
|
||||
%}
|
||||
|
||||
function version_error(version: uint8): bool
|
||||
%{
|
||||
bro_analyzer()->ProtocolViolation(fmt("unsupported/unknown SOCKS version %d", version));
|
||||
return true;
|
||||
%}
|
||||
|
||||
|
||||
};
|
||||
|
||||
refine typeattr SOCKS_Request += &let {
|
||||
proc: bool = $context.connection.socks_request(command, addr, empty, port, user);
|
||||
refine typeattr SOCKS_Version_Error += &let {
|
||||
proc: bool = $context.connection.version_error(version);
|
||||
};
|
||||
|
||||
refine typeattr SOCKS_Reply += &let {
|
||||
proc: bool = $context.connection.socks_reply((status == 0x5a), addr, port);
|
||||
refine typeattr SOCKS4_Request += &let {
|
||||
proc: bool = $context.connection.socks4_request(this);
|
||||
};
|
||||
|
||||
refine typeattr SOCKS4_Reply += &let {
|
||||
proc: bool = $context.connection.socks4_reply(this);
|
||||
};
|
||||
|
||||
refine typeattr SOCKS5_Request += &let {
|
||||
proc: bool = $context.connection.socks5_request(this);
|
||||
};
|
||||
|
||||
refine typeattr SOCKS5_Reply += &let {
|
||||
proc: bool = $context.connection.socks5_reply(this);
|
||||
};
|
||||
|
|
|
@ -1,34 +1,119 @@
|
|||
type SOCKS_Message(is_orig: bool) = case is_orig of {
|
||||
true -> request: SOCKS_Request;
|
||||
false -> reply: SOCKS_Reply;
|
||||
|
||||
type SOCKS_Version(is_orig: bool) = record {
|
||||
version: uint8;
|
||||
msg: case version of {
|
||||
4 -> socks4_msg: SOCKS4_Message(is_orig);
|
||||
5 -> socks5_msg: SOCKS5_Message(is_orig);
|
||||
default -> socks_msg_fail: SOCKS_Version_Error(version);
|
||||
};
|
||||
};
|
||||
|
||||
type SOCKS_Request = record {
|
||||
version: uint8;
|
||||
type SOCKS_Version_Error(version: uint8) = record {
|
||||
nothing: empty;
|
||||
};
|
||||
|
||||
# SOCKS5 Implementation
|
||||
type SOCKS5_Message(is_orig: bool) = case $context.connection.v5_past_authentication() of {
|
||||
true -> msg: SOCKS5_Real_Message(is_orig);
|
||||
false -> auth: SOCKS5_Auth_Negotiation(is_orig);
|
||||
};
|
||||
|
||||
type SOCKS5_Auth_Negotiation(is_orig: bool) = case is_orig of {
|
||||
true -> req: SOCKS5_Auth_Negotiation_Request;
|
||||
false -> rep: SOCKS5_Auth_Negotiation_Reply;
|
||||
};
|
||||
|
||||
type SOCKS5_Auth_Negotiation_Request = record {
|
||||
method_count: uint8;
|
||||
methods: uint8[method_count];
|
||||
};
|
||||
|
||||
type SOCKS5_Auth_Negotiation_Reply = record {
|
||||
selected_auth_method: uint8;
|
||||
} &let {
|
||||
past_auth = $context.connection.set_v5_past_authentication();
|
||||
};
|
||||
|
||||
type SOCKS5_Real_Message(is_orig: bool) = case is_orig of {
|
||||
true -> request: SOCKS5_Request;
|
||||
false -> reply: SOCKS5_Reply;
|
||||
};
|
||||
|
||||
type Domain_Name = record {
|
||||
len: uint8;
|
||||
name: bytestring &length=len;
|
||||
} &byteorder = bigendian;
|
||||
|
||||
type SOCKS5_Address = record {
|
||||
addr_type: uint8;
|
||||
addr: case addr_type of {
|
||||
1 -> ipv4: uint32;
|
||||
3 -> domain_name: Domain_Name;
|
||||
4 -> ipv6: uint32[4];
|
||||
default -> err: bytestring &restofdata &transient;
|
||||
};
|
||||
} &byteorder = bigendian;
|
||||
|
||||
type SOCKS5_Request = record {
|
||||
command: uint8;
|
||||
reserved: uint8;
|
||||
remote_name: SOCKS5_Address;
|
||||
port: uint16;
|
||||
} &byteorder = bigendian;
|
||||
|
||||
type SOCKS5_Reply = record {
|
||||
reply: uint8;
|
||||
reserved: uint8;
|
||||
bound: SOCKS5_Address;
|
||||
port: uint16;
|
||||
} &byteorder = bigendian;
|
||||
|
||||
|
||||
# SOCKS4 Implementation
|
||||
type SOCKS4_Message(is_orig: bool) = case is_orig of {
|
||||
true -> request: SOCKS4_Request;
|
||||
false -> reply: SOCKS4_Reply;
|
||||
};
|
||||
|
||||
type SOCKS4_Request = record {
|
||||
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;
|
||||
type SOCKS4_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;
|
||||
|
||||
|
||||
refine connection SOCKS_Conn += {
|
||||
%member{
|
||||
bool v5_authenticated_;
|
||||
%}
|
||||
|
||||
%init{
|
||||
v5_authenticated_ = false;
|
||||
%}
|
||||
|
||||
function v5_past_authentication(): bool
|
||||
%{
|
||||
return v5_authenticated_;
|
||||
%}
|
||||
|
||||
function set_v5_past_authentication(): bool
|
||||
%{
|
||||
v5_authenticated_ = true;
|
||||
return true;
|
||||
%}
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ connection SOCKS_Conn(bro_analyzer: BroAnalyzer) {
|
|||
%include socks-protocol.pac
|
||||
|
||||
flow SOCKS_Flow(is_orig: bool) {
|
||||
datagram = SOCKS_Message(is_orig) withcontext(connection, this);
|
||||
datagram = SOCKS_Version(is_orig) withcontext(connection, this);
|
||||
};
|
||||
|
||||
%include socks-analyzer.pac
|
|
@ -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
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action
|
||||
#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
|
||||
1257655293.629048 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::AYIYA Tunnel::DISCOVER
|
||||
1257655296.585034 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::AYIYA Tunnel::DISCOVER
|
||||
1257655317.464035 k6kgXLOoSKl 192.168.3.101 53859 216.14.98.22 5072 Tunnel::AYIYA Tunnel::CLOSE
|
||||
1257655317.464035 UWkUyAuUGXf 192.168.3.101 53796 216.14.98.22 5072 Tunnel::AYIYA Tunnel::CLOSE
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#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 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)
|
|
@ -1,8 +0,0 @@
|
|||
#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 - -
|
|
@ -1,9 +0,0 @@
|
|||
[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=<uninitialized>, dpd=<uninitialized>, conn=<uninitialized>, extract_orig=F, extract_resp=F, dns=<uninitialized>, dns_state=<uninitialized>, ftp=<uninitialized>, http=<uninitialized>, http_state=<uninitialized>, irc=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, ssh=<uninitialized>, ssl=<uninitialized>, syslog=<uninitialized>]
|
||||
---
|
||||
1
|
||||
192.150.187.12
|
||||
|
||||
80/tcp
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#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
|
|
@ -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
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action
|
||||
#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
|
||||
1210953052.202579 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::TEREDO Tunnel::DISCOVER
|
||||
1210953052.324629 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::TEREDO Tunnel::DISCOVER
|
||||
1210953061.292918 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::TEREDO Tunnel::DISCOVER
|
||||
1210953076.058333 nQcgTWjvg4c 192.168.2.16 3797 65.55.158.80 3544 Tunnel::TEREDO Tunnel::CLOSE
|
||||
1210953076.058333 GSxOnSLghOa 192.168.2.16 3797 83.170.1.38 32900 Tunnel::TEREDO Tunnel::CLOSE
|
||||
1210953076.058333 TEfuqmmG4bh 192.168.2.16 3797 65.55.158.81 3544 Tunnel::TEREDO Tunnel::CLOSE
|
||||
|
|
|
@ -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
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
1340127577.336558 UWkUyAuUGXf 192.168.2.16 3797 65.55.158.80 3544 Tunnel::DISCOVER Tunnel::TEREDO
|
||||
1340127577.339015 k6kgXLOoSKl 192.168.2.16 3797 65.55.158.81 3544 Tunnel::DISCOVER Tunnel::TEREDO
|
||||
1340127577.351747 j4u32Pc5bif 192.168.2.16 3797 83.170.1.38 32900 Tunnel::DISCOVER Tunnel::TEREDO
|
||||
1340127577.406995 UWkUyAuUGXf 192.168.2.16 3797 65.55.158.80 3544 Tunnel::CLOSE Tunnel::TEREDO
|
||||
1340127577.406995 j4u32Pc5bif 192.168.2.16 3797 83.170.1.38 32900 Tunnel::CLOSE Tunnel::TEREDO
|
||||
1340127577.406995 k6kgXLOoSKl 192.168.2.16 3797 65.55.158.81 3544 Tunnel::CLOSE Tunnel::TEREDO
|
||||
1340127577.336558 UWkUyAuUGXf 192.168.2.16 3797 65.55.158.80 3544 Tunnel::TEREDO Tunnel::DISCOVER
|
||||
1340127577.339015 k6kgXLOoSKl 192.168.2.16 3797 65.55.158.81 3544 Tunnel::TEREDO Tunnel::DISCOVER
|
||||
1340127577.351747 j4u32Pc5bif 192.168.2.16 3797 83.170.1.38 32900 Tunnel::TEREDO Tunnel::DISCOVER
|
||||
1340127577.406995 UWkUyAuUGXf 192.168.2.16 3797 65.55.158.80 3544 Tunnel::TEREDO Tunnel::CLOSE
|
||||
1340127577.406995 j4u32Pc5bif 192.168.2.16 3797 83.170.1.38 32900 Tunnel::TEREDO Tunnel::CLOSE
|
||||
1340127577.406995 k6kgXLOoSKl 192.168.2.16 3797 65.55.158.81 3544 Tunnel::TEREDO Tunnel::CLOSE
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path socks
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user status req_h req_name req_p bound_h bound_name bound_p
|
||||
#types time string addr port addr port count string string addr string port addr string port
|
||||
1340213015.276495 UWkUyAuUGXf 10.0.0.55 53994 60.190.189.214 8124 5 - succeeded - www.osnews.com 80 192.168.0.31 - 2688
|
|
@ -0,0 +1,8 @@
|
|||
#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 tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
1340213015.276495 - 10.0.0.55 0 60.190.189.214 8124 Tunnel::SOCKS Tunnel::DISCOVER
|
|
@ -0,0 +1,8 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path socks
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version user status req_h req_name req_p bound_h bound_name bound_p
|
||||
#types time string addr port addr port count string string addr string port addr string port
|
||||
1340113261.914619 UWkUyAuUGXf 10.0.0.50 59580 85.194.84.197 1080 5 - succeeded - www.google.com 443 0.0.0.0 - 443
|
|
@ -0,0 +1,8 @@
|
|||
#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 tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
1340113261.914619 - 10.0.0.50 0 85.194.84.197 1080 Tunnel::SOCKS Tunnel::DISCOVER
|
|
@ -0,0 +1,8 @@
|
|||
#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 tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
1208299429.265774 - 127.0.0.1 0 127.0.0.1 1080 Tunnel::SOCKS Tunnel::DISCOVER
|
BIN
testing/btest/Traces/socks-with-ssl.trace
Normal file
BIN
testing/btest/Traces/socks-with-ssl.trace
Normal file
Binary file not shown.
BIN
testing/btest/Traces/socks.trace
Normal file
BIN
testing/btest/Traces/socks.trace
Normal file
Binary file not shown.
|
@ -1,19 +0,0 @@
|
|||
# @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;
|
||||
}
|
||||
|
||||
|
5
testing/btest/scripts/base/protocols/socks/trace1.test
Normal file
5
testing/btest/scripts/base/protocols/socks/trace1.test
Normal file
|
@ -0,0 +1,5 @@
|
|||
# @TEST-EXEC: bro -r $TRACES/socks.trace %INPUT
|
||||
# @TEST-EXEC: btest-diff socks.log
|
||||
# @TEST-EXEC: btest-diff tunnel.log
|
||||
|
||||
@load base/protocols/socks
|
5
testing/btest/scripts/base/protocols/socks/trace2.test
Normal file
5
testing/btest/scripts/base/protocols/socks/trace2.test
Normal file
|
@ -0,0 +1,5 @@
|
|||
# @TEST-EXEC: bro -r $TRACES/socks-with-ssl.trace %INPUT
|
||||
# @TEST-EXEC: btest-diff socks.log
|
||||
# @TEST-EXEC: btest-diff tunnel.log
|
||||
|
||||
@load base/protocols/socks
|
4
testing/btest/scripts/base/protocols/socks/trace3.test
Normal file
4
testing/btest/scripts/base/protocols/socks/trace3.test
Normal file
|
@ -0,0 +1,4 @@
|
|||
# @TEST-EXEC: bro -C -r $TRACES/tunnels/socks.pcap %INPUT
|
||||
# @TEST-EXEC: btest-diff tunnel.log
|
||||
|
||||
@load base/protocols/socks
|
Loading…
Add table
Add a link
Reference in a new issue