Refactor SOCKS5 user/pass authentication support.

- Rename event "socks_login_userpass" to "socks_login_userpass_request"
- Rename event "socks_login_reply" to "socks_login_userpass_reply"
- Split unsupported authN weird into 2 types: method vs. version

Addresses BIT-1011
This commit is contained in:
Jon Siwek 2015-02-12 17:06:38 -06:00
parent 9592f64225
commit 961fd06cad
6 changed files with 82 additions and 27 deletions

View file

@ -94,7 +94,7 @@ event socks_reply(c: connection, version: count, reply: count, sa: SOCKS::Addres
Log::write(SOCKS::LOG, c$socks); Log::write(SOCKS::LOG, c$socks);
} }
event socks_login_userpass(c: connection, user: string, password: string) &priority=5 event socks_login_userpass_request(c: connection, user: string, password: string) &priority=5
{ {
# Authentication only possible with the version 5. # Authentication only possible with the version 5.
set_session(c, 5); set_session(c, 5);
@ -103,7 +103,7 @@ event socks_login_userpass(c: connection, user: string, password: string) &prior
c$socks$password = password; c$socks$password = password;
} }
event socks_login_reply(c: connection, code: count) &priority=5 event socks_login_userpass_reply(c: connection, code: count) &priority=5
{ {
# Authentication only possible with the version 5. # Authentication only possible with the version 5.
set_session(c, 5); set_session(c, 5);

View file

@ -34,12 +34,12 @@ event socks_reply%(c: connection, version: count, reply: count, sa: SOCKS::Addre
## user: The given username. ## user: The given username.
## ##
## password: The given password. ## password: The given password.
event socks_login_userpass%(c: connection, user: string, password: string%); event socks_login_userpass_request%(c: connection, user: string, password: string%);
## Generated when a SOCKS server replies to a login attempt. ## Generated when a SOCKS server replies to a username/password login attempt.
## ##
## c: The parent connection of the proxy. ## c: The parent connection of the proxy.
## ##
## code: The response code for the attempted login. ## code: The response code for the attempted login.
event socks_login_reply%(c: connection, code: count%); event socks_login_userpass_reply%(c: connection, code: count%);

View file

@ -148,28 +148,34 @@ refine connection SOCKS_Conn += {
return true; return true;
%} %}
function socks5_auth_request_userpass(request: SOCKS5_Auth_Request_UserPass): bool function socks5_auth_request_userpass(request: SOCKS5_Auth_Request_UserPass_v1): bool
%{ %{
StringVal* user = new StringVal(${request.username}.length(), (const char*) ${request.username}.begin()); StringVal* user = new StringVal(${request.username}.length(), (const char*) ${request.username}.begin());
StringVal* pass = new StringVal(${request.password}.length(), (const char*) ${request.password}.begin()); StringVal* pass = new StringVal(${request.password}.length(), (const char*) ${request.password}.begin());
BifEvent::generate_socks_login_userpass(bro_analyzer(), BifEvent::generate_socks_login_userpass_request(bro_analyzer(),
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
user, pass); user, pass);
return true; return true;
%} %}
function socks5_unsupported_authentication(auth_method: uint8): bool function socks5_unsupported_authentication_method(auth_method: uint8): bool
%{ %{
reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_%d", auth_method)); reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_method_%d", auth_method));
return true;
%}
function socks5_unsupported_authentication_version(auth_method: uint8, version: uint8): bool
%{
reporter->Weird(bro_analyzer()->Conn(), fmt("socks5_unsupported_authentication_%d_%d", auth_method, version));
return true; return true;
%} %}
function socks5_auth_reply(reply: SOCKS5_Auth_Reply): bool function socks5_auth_reply_userpass(reply: SOCKS5_Auth_Reply_UserPass_v1): bool
%{ %{
BifEvent::generate_socks_login_reply(bro_analyzer(), BifEvent::generate_socks_login_userpass_reply(bro_analyzer(),
bro_analyzer()->Conn(), bro_analyzer()->Conn(),
${reply.code}); ${reply.code});
return true; return true;
%} %}
@ -205,14 +211,18 @@ refine typeattr SOCKS5_Reply += &let {
refine typeattr SOCKS5_Auth_Negotiation_Reply += &let { refine typeattr SOCKS5_Auth_Negotiation_Reply += &let {
}; };
refine typeattr SOCKS5_Auth_Request_UserPass += &let { refine typeattr SOCKS5_Auth_Request_UserPass_v1 += &let {
proc: bool = $context.connection.socks5_auth_request_userpass(this); proc: bool = $context.connection.socks5_auth_request_userpass(this);
}; };
refine typeattr SOCKS5_Auth_Reply += &let { refine typeattr SOCKS5_Auth_Reply_UserPass_v1 += &let {
proc: bool = $context.connection.socks5_auth_reply(this); proc: bool = $context.connection.socks5_auth_reply_userpass(this);
}; };
refine typeattr SOCKS5_Unsupported_Authentication += &let { refine typeattr SOCKS5_Unsupported_Authentication_Method += &let {
proc: bool = $context.connection.socks5_unsupported_authentication($context.connection.v5_auth_method()); proc: bool = $context.connection.socks5_unsupported_authentication_method($context.connection.v5_auth_method());
};
refine typeattr SOCKS5_Unsupported_Authentication_Version += &let {
proc: bool = $context.connection.socks5_unsupported_authentication_version($context.connection.v5_auth_method(), version);
}; };

View file

@ -1,8 +1,12 @@
type SOCKS_Message(is_orig: bool) = case $context.connection.v5_in_auth_sub_negotiation() of {
true -> auth: SOCKS5_Auth_Message(is_orig);
false -> msg: SOCKS_Version(is_orig);
};
type SOCKS_Version(is_orig: bool) = record { type SOCKS_Version(is_orig: bool) = record {
version: uint8; version: uint8;
msg: case version of { msg: case version of {
1 -> socks5_auth_msg: SOCKS5_Auth_Message(is_orig);
4 -> socks4_msg: SOCKS4_Message(is_orig); 4 -> socks4_msg: SOCKS4_Message(is_orig);
5 -> socks5_msg: SOCKS5_Message(is_orig); 5 -> socks5_msg: SOCKS5_Message(is_orig);
default -> socks_msg_fail: SOCKS_Version_Error(version); default -> socks_msg_fail: SOCKS_Version_Error(version);
@ -33,6 +37,7 @@ type SOCKS5_Auth_Negotiation_Request = record {
type SOCKS5_Auth_Negotiation_Reply = record { type SOCKS5_Auth_Negotiation_Reply = record {
selected_auth_method: uint8; selected_auth_method: uint8;
} &let { } &let {
in_auth_sub_neg = $context.connection.set_v5_in_auth_sub_negotiation(selected_auth_method == 0 || selected_auth_method == 0xff ? false : true);
past_auth = $context.connection.set_v5_past_authentication(); past_auth = $context.connection.set_v5_past_authentication();
set_auth = $context.connection.set_v5_auth_method(selected_auth_method); set_auth = $context.connection.set_v5_auth_method(selected_auth_method);
}; };
@ -44,21 +49,48 @@ type SOCKS5_Auth_Message(is_orig: bool) = case is_orig of {
type SOCKS5_Auth_Request = case $context.connection.v5_auth_method() of { type SOCKS5_Auth_Request = case $context.connection.v5_auth_method() of {
0x02 -> userpass : SOCKS5_Auth_Request_UserPass; 0x02 -> userpass : SOCKS5_Auth_Request_UserPass;
default -> unsupported : SOCKS5_Unsupported_Authentication; default -> unsupported : SOCKS5_Unsupported_Authentication_Method;
}; };
type SOCKS5_Unsupported_Authentication = record { type SOCKS5_Unsupported_Authentication_Method = record {
crap: bytestring &restofdata;
};
type SOCKS5_Unsupported_Authentication_Version(version: uint8) = record {
crap: bytestring &restofdata; crap: bytestring &restofdata;
}; };
type SOCKS5_Auth_Request_UserPass = record { type SOCKS5_Auth_Request_UserPass = record {
version: uint8;
msg: case version of {
1 -> v1: SOCKS5_Auth_Request_UserPass_v1;
default -> unsupported: SOCKS5_Unsupported_Authentication_Version(version);
};
};
type SOCKS5_Auth_Request_UserPass_v1 = record {
ulen : uint8; ulen : uint8;
username : bytestring &length=ulen; username : bytestring &length=ulen;
plen : uint8; plen : uint8;
password : bytestring &length=plen; password : bytestring &length=plen;
}; };
type SOCKS5_Auth_Reply = record { type SOCKS5_Auth_Reply = case $context.connection.v5_auth_method() of {
0x02 -> userpass : SOCKS5_Auth_Reply_UserPass;
default -> unsupported : SOCKS5_Unsupported_Authentication_Method;
} &let {
in_auth_sub_neg = $context.connection.set_v5_in_auth_sub_negotiation(false);
};
type SOCKS5_Auth_Reply_UserPass = record {
version: uint8;
msg: case version of {
1 -> v1: SOCKS5_Auth_Reply_UserPass_v1;
default -> unsupported: SOCKS5_Unsupported_Authentication_Version(version);
};
};
type SOCKS5_Auth_Reply_UserPass_v1 = record {
code : uint8; code : uint8;
}; };
@ -126,15 +158,28 @@ type SOCKS4_Reply = record {
refine connection SOCKS_Conn += { refine connection SOCKS_Conn += {
%member{ %member{
bool v5_in_auth_sub_negotiation_;
bool v5_authenticated_; bool v5_authenticated_;
uint8 selected_auth_method_; uint8 selected_auth_method_;
%} %}
%init{ %init{
v5_in_auth_sub_negotiation_ = false;
v5_authenticated_ = false; v5_authenticated_ = false;
selected_auth_method_ = 255; selected_auth_method_ = 255;
%} %}
function v5_in_auth_sub_negotiation(): bool
%{
return v5_in_auth_sub_negotiation_;
%}
function set_v5_in_auth_sub_negotiation(b: bool): bool
%{
v5_in_auth_sub_negotiation_ = b;
return true;
%}
function v5_past_authentication(): bool function v5_past_authentication(): bool
%{ %{
return v5_authenticated_; return v5_authenticated_;

View file

@ -20,7 +20,7 @@ connection SOCKS_Conn(bro_analyzer: BroAnalyzer) {
%include socks-protocol.pac %include socks-protocol.pac
flow SOCKS_Flow(is_orig: bool) { flow SOCKS_Flow(is_orig: bool) {
datagram = SOCKS_Version(is_orig) withcontext(connection, this); datagram = SOCKS_Message(is_orig) withcontext(connection, this);
}; };
%include socks-analyzer.pac %include socks-analyzer.pac

View file

@ -17,6 +17,6 @@ Demo::Foo - A Foo test logging writer (dynamic, version 1.0)
[http] 1340213020.732963|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|GET|www.osnews.com|/images/icons/17.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|- [http] 1340213020.732963|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|GET|www.osnews.com|/images/icons/17.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|-
[http] 1340213021.300269|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|6|GET|www.osnews.com|/images/left.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|- [http] 1340213021.300269|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|6|GET|www.osnews.com|/images/left.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|-
[http] 1340213021.861584|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|7|GET|www.osnews.com|/images/icons/32.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|- [http] 1340213021.861584|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|7|GET|www.osnews.com|/images/icons/32.gif|http://www.osnews.com/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0.2) Gecko/20100101 Firefox/10.0.2|0|0|304|Not Modified|-|-|-||-|-|-|-|-|-|-
[packet_filter] 1412721099.419280|bro|ip or not ip|T|T [packet_filter] 1423781675.402129|bro|ip or not ip|T|T
[socks] 1340213015.276495|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|-|succeeded|-|www.osnews.com|80|192.168.0.31|-|2688 [socks] 1340213015.276495|CjhGID4nQcgTWjvg4c|10.0.0.55|53994|60.190.189.214|8124|5|-|-|succeeded|-|www.osnews.com|80|192.168.0.31|-|2688
[tunnel] 1340213015.276495|-|10.0.0.55|0|60.190.189.214|8124|Tunnel::SOCKS|Tunnel::DISCOVER [tunnel] 1340213015.276495|-|10.0.0.55|0|60.190.189.214|8124|Tunnel::SOCKS|Tunnel::DISCOVER