From 896f252a31dfa59dc75eb7a1d9326ca04be79fd7 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Wed, 20 Jun 2012 13:58:25 -0400 Subject: [PATCH] Updates for the SOCKS analyzer. - Now supports SOCKSv5 in the analyzer and the DPD sigs. - Reworked the core events. - Tests. - A SOCKS log! --- scripts/base/frameworks/dpd/dpd.sig | 27 +++- scripts/base/protocols/socks/__load__.bro | 1 + scripts/base/protocols/socks/consts.bro | 41 +++++++ scripts/base/protocols/socks/main.bro | 93 +++++++++++++- src/event.bif | 20 ++- src/socks-analyzer.pac | 116 +++++++++++++++--- src/socks-protocol.pac | 115 ++++++++++++++--- src/socks.pac | 2 +- .../socks.log | 8 ++ .../tunnel.log | 8 ++ .../socks.log | 8 ++ .../tunnel.log | 8 ++ testing/btest/Traces/socks-with-ssl.trace | Bin 0 -> 5695 bytes testing/btest/Traces/socks.trace | Bin 0 -> 11260 bytes .../scripts/base/protocols/socks/trace1.test | 6 + .../scripts/base/protocols/socks/trace2.test | 5 + 16 files changed, 411 insertions(+), 47 deletions(-) create mode 100644 scripts/base/protocols/socks/consts.bro create mode 100644 testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.socks.trace1/tunnel.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.socks.trace2/tunnel.log create mode 100644 testing/btest/Traces/socks-with-ssl.trace create mode 100644 testing/btest/Traces/socks.trace create mode 100644 testing/btest/scripts/base/protocols/socks/trace1.test create mode 100644 testing/btest/scripts/base/protocols/socks/trace2.test diff --git a/scripts/base/frameworks/dpd/dpd.sig b/scripts/base/frameworks/dpd/dpd.sig index 305383809d..245e79bfdf 100644 --- a/scripts/base/frameworks/dpd/dpd.sig +++ b/scripts/base/frameworks/dpd/dpd.sig @@ -162,33 +162,48 @@ 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 + payload /^\x05/ + tcp-state originator +} + +signature dpd_socks5_server { + ip-proto == tcp + requires-reverse-signature dpd_socks5_client + payload /^\x05/ + tcp-state responder + enable "socks" +} + + diff --git a/scripts/base/protocols/socks/__load__.bro b/scripts/base/protocols/socks/__load__.bro index d551be57d3..0098b81a7a 100644 --- a/scripts/base/protocols/socks/__load__.bro +++ b/scripts/base/protocols/socks/__load__.bro @@ -1 +1,2 @@ +@load ./consts @load ./main \ No newline at end of file diff --git a/scripts/base/protocols/socks/consts.bro b/scripts/base/protocols/socks/consts.bro new file mode 100644 index 0000000000..6341262041 --- /dev/null +++ b/scripts/base/protocols/socks/consts.bro @@ -0,0 +1,41 @@ +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", + [4] = "Unassigned", + [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); }; + +} \ No newline at end of file diff --git a/scripts/base/protocols/socks/main.bro b/scripts/base/protocols/socks/main.bro index 54d181e43e..cceea68758 100644 --- a/scripts/base/protocols/socks/main.bro +++ b/scripts/base/protocols/socks/main.bro @@ -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); + } \ No newline at end of file diff --git a/src/event.bif b/src/event.bif index 4d28ab7a40..d1e28a98e5 100644 --- a/src/event.bif +++ b/src/event.bif @@ -6101,7 +6101,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. ## @@ -6109,13 +6111,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 diff --git a/src/socks-analyzer.pac b/src/socks-analyzer.pac index 88a29fe383..0842303f40 100644 --- a/src/socks-analyzer.pac +++ b/src/socks-analyzer.pac @@ -19,39 +19,127 @@ StringVal* array_to_string(vector *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; + if ( ${request.v4a} ) + dstname = array_to_string(${request.name}); + 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(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(bro_analyzer())->EndpointDone(false); return true; %} + + function socks5_request(request: SOCKS5_Request): 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 ( ${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; + } + + 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(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; + } + + 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(bro_analyzer())->EndpointDone(false); + return true; + %} + }; -refine typeattr SOCKS_Request += &let { - proc: bool = $context.connection.socks_request(command, addr, empty, port, user); +refine typeattr SOCKS4_Request += &let { + proc: bool = $context.connection.socks4_request(this); }; -refine typeattr SOCKS_Reply += &let { - proc: bool = $context.connection.socks_reply((status == 0x5a), addr, port); +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); }; diff --git a/src/socks-protocol.pac b/src/socks-protocol.pac index a908c2da68..8ae81a6e02 100644 --- a/src/socks-protocol.pac +++ b/src/socks-protocol.pac @@ -1,34 +1,115 @@ -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: empty; + }; }; -type SOCKS_Request = record { - version: uint8; +# 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; + %} +}; + diff --git a/src/socks.pac b/src/socks.pac index 4f16582690..15d3580674 100644 --- a/src/socks.pac +++ b/src/socks.pac @@ -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 \ No newline at end of file diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log b/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log new file mode 100644 index 0000000000..4241190234 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.socks.trace1/socks.log @@ -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 diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.trace1/tunnel.log b/testing/btest/Baseline/scripts.base.protocols.socks.trace1/tunnel.log new file mode 100644 index 0000000000..a7068cd0da --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.socks.trace1/tunnel.log @@ -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 diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log b/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log new file mode 100644 index 0000000000..556ed9263e --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.socks.trace2/socks.log @@ -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 diff --git a/testing/btest/Baseline/scripts.base.protocols.socks.trace2/tunnel.log b/testing/btest/Baseline/scripts.base.protocols.socks.trace2/tunnel.log new file mode 100644 index 0000000000..5eac3ae7ad --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.socks.trace2/tunnel.log @@ -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 diff --git a/testing/btest/Traces/socks-with-ssl.trace b/testing/btest/Traces/socks-with-ssl.trace new file mode 100644 index 0000000000000000000000000000000000000000..da27cc88736d8906a4789ee990dbca865cfd6685 GIT binary patch literal 5695 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 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/socks/trace1.test b/testing/btest/scripts/base/protocols/socks/trace1.test new file mode 100644 index 0000000000..fb65b33cbc --- /dev/null +++ b/testing/btest/scripts/base/protocols/socks/trace1.test @@ -0,0 +1,6 @@ +# @TEST-EXEC: bro -r $TRACES/socks.trace %INPUT +# @TEST-EXEC: btest-diff socks.log +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: btest-diff tunnel.log + +@load base/protocols/socks diff --git a/testing/btest/scripts/base/protocols/socks/trace2.test b/testing/btest/scripts/base/protocols/socks/trace2.test new file mode 100644 index 0000000000..5e3a449120 --- /dev/null +++ b/testing/btest/scripts/base/protocols/socks/trace2.test @@ -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