diff --git a/CHANGES b/CHANGES index 341609c748..e497b035ed 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ +2.6-487 | 2019-06-20 20:38:26 -0700 + + * Add new RDP event: rdp_client_cluster_data (Jeff Atkinson) + + * Added "options" field to RDP::ClientChannelDef (Jeff Atkinson) + 2.6-482 | 2019-06-20 19:57:20 -0700 * Make configure complain if submodules are not checked out. (Johanna Amann, Corelight) diff --git a/NEWS b/NEWS index 85c01507a4..ccf210f304 100644 --- a/NEWS +++ b/NEWS @@ -87,6 +87,7 @@ New Functionality - New events: - rdp_client_network_data - rdp_client_security_data + - rdp_client_cluster_data - rdp_native_encrypted_data - Add a new "client_channels" field to rdp.log based on data parsed from diff --git a/VERSION b/VERSION index e7b0a1a59f..0744123abb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.6-482 +2.6-487 diff --git a/doc b/doc index a5f2286834..e401ba24d8 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit a5f2286834e404df5eb8291fe078732c6b5763ab +Subproject commit e401ba24d8ecc5914ceb2f65bbe7f11458679e1e diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 1a57375d4c..568e5c32a7 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -4279,6 +4279,8 @@ export { type RDP::ClientChannelDef: record { ## A unique name for the channel name: string; + ## Channel Def raw options as count + options: count; ## Absence of this flag indicates that this channel is ## a placeholder and that the server MUST NOT set it up. initialized: bool; @@ -4304,6 +4306,30 @@ export { persistent: bool; }; + ## The TS_UD_CS_CLUSTER data block is sent by the client to the server + ## either to advertise that it can support the Server Redirection PDUs + ## or to request a connection to a given session identifier. + type RDP::ClientClusterData: record { + ## Cluster information flags. + flags: count; + ## If the *redir_sessionid_field_valid* flag is set, this field + ## contains a valid session identifier to which the client requests + ## to connect. + redir_session_id: count; + ## The client can receive server session redirection packets. + ## If this flag is set, the *svr_session_redir_version_mask* + ## field MUST contain the server session redirection version that + ## the client supports. + redir_supported: bool; + ## The server session redirection version that the client supports. + svr_session_redir_version_mask: count; + ## Whether the *redir_session_id* field identifies a session on + ## the server to associate with the connection. + redir_sessionid_field_valid: bool; + ## The client logged on with a smart card. + redir_smartcard: bool; + }; + ## The list of channels requested by the client. type RDP::ClientChannelList: vector of ClientChannelDef; } diff --git a/src/analyzer/protocol/rdp/events.bif b/src/analyzer/protocol/rdp/events.bif index 0931365dc6..178860bd42 100644 --- a/src/analyzer/protocol/rdp/events.bif +++ b/src/analyzer/protocol/rdp/events.bif @@ -49,6 +49,13 @@ event rdp_client_security_data%(c: connection, data: RDP::ClientSecurityData%); ## channels: The channels that were requested event rdp_client_network_data%(c: connection, channels: RDP::ClientChannelList%); +## Generated for client cluster data packets. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## data: The data contained in the client security data structure. +event rdp_client_cluster_data%(c: connection, data: RDP::ClientClusterData%); + ## Generated for MCS server responses. ## ## c: The connection record for the underlying transport-layer session/flow. diff --git a/src/analyzer/protocol/rdp/rdp-analyzer.pac b/src/analyzer/protocol/rdp/rdp-analyzer.pac index 7b7552642f..dd76d07a87 100644 --- a/src/analyzer/protocol/rdp/rdp-analyzer.pac +++ b/src/analyzer/protocol/rdp/rdp-analyzer.pac @@ -130,18 +130,19 @@ refine flow RDP_Flow += { RecordVal* channel_def = new RecordVal(BifType::Record::RDP::ClientChannelDef); channel_def->Assign(0, bytestring_to_val(${cnetwork.channel_def_array[i].name})); + channel_def->Assign(1, val_mgr->GetCount(${cnetwork.channel_def_array[i].options})); - channel_def->Assign(1, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_INITIALIZED})); - channel_def->Assign(2, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_ENCRYPT_RDP})); - channel_def->Assign(3, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_ENCRYPT_SC})); - channel_def->Assign(4, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_ENCRYPT_CS})); - channel_def->Assign(5, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_PRI_HIGH})); - channel_def->Assign(6, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_PRI_MED})); - channel_def->Assign(7, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_PRI_LOW})); - channel_def->Assign(8, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_COMPRESS_RDP})); - channel_def->Assign(9, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_COMPRESS})); - channel_def->Assign(10, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_SHOW_PROTOCOL})); - channel_def->Assign(11, val_mgr->GetBool(${cnetwork.channel_def_array[i].REMOTE_CONTROL_PERSISTENT})); + channel_def->Assign(2, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_INITIALIZED})); + channel_def->Assign(3, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_ENCRYPT_RDP})); + channel_def->Assign(4, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_ENCRYPT_SC})); + channel_def->Assign(5, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_ENCRYPT_CS})); + channel_def->Assign(6, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_PRI_HIGH})); + channel_def->Assign(7, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_PRI_MED})); + channel_def->Assign(8, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_PRI_LOW})); + channel_def->Assign(9, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_COMPRESS_RDP})); + channel_def->Assign(10, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_COMPRESS})); + channel_def->Assign(11, val_mgr->GetBool(${cnetwork.channel_def_array[i].CHANNEL_OPTION_SHOW_PROTOCOL})); + channel_def->Assign(12, val_mgr->GetBool(${cnetwork.channel_def_array[i].REMOTE_CONTROL_PERSISTENT})); channels->Assign(channels->Size(), channel_def); } @@ -154,6 +155,25 @@ refine flow RDP_Flow += { return true; %} + function proc_rdp_client_cluster_data(ccluster: Client_Cluster_Data): bool + %{ + if ( ! rdp_client_cluster_data ) + return false; + + RecordVal* ccld = new RecordVal(BifType::Record::RDP::ClientClusterData); + ccld->Assign(0, val_mgr->GetCount(${ccluster.flags})); + ccld->Assign(1, val_mgr->GetCount(${ccluster.redir_session_id})); + ccld->Assign(2, val_mgr->GetBool(${ccluster.REDIRECTION_SUPPORTED})); + ccld->Assign(3, val_mgr->GetCount(${ccluster.SERVER_SESSION_REDIRECTION_VERSION_MASK})); + ccld->Assign(4, val_mgr->GetBool(${ccluster.REDIRECTED_SESSIONID_FIELD_VALID})); + ccld->Assign(5, val_mgr->GetBool(${ccluster.REDIRECTED_SMARTCARD})); + + BifEvent::generate_rdp_client_cluster_data(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ccld); + return true; + %} + function proc_rdp_server_security(ssd: Server_Security_Data): bool %{ connection()->bro_analyzer()->ProtocolConfirmation(); @@ -226,6 +246,10 @@ refine typeattr Client_Network_Data += &let { proc: bool = $context.flow.proc_rdp_client_network_data(this); }; +refine typeattr Client_Cluster_Data += &let { + proc: bool = $context.flow.proc_rdp_client_cluster_data(this); +}; + refine typeattr GCC_Server_Create_Response += &let { proc: bool = $context.flow.proc_rdp_gcc_server_create_response(this); }; diff --git a/src/analyzer/protocol/rdp/rdp-protocol.pac b/src/analyzer/protocol/rdp/rdp-protocol.pac index 442a0d1292..12eb5aee94 100644 --- a/src/analyzer/protocol/rdp/rdp-protocol.pac +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -54,7 +54,7 @@ type Data_Block = record { 0xc001 -> client_core: Client_Core_Data; 0xc002 -> client_security: Client_Security_Data; 0xc003 -> client_network: Client_Network_Data; - #0xc004 -> client_cluster: Client_Cluster_Data; + 0xc004 -> client_cluster: Client_Cluster_Data; #0xc005 -> client_monitor: Client_Monitor_Data; #0xc006 -> client_msgchannel: Client_MsgChannel_Data; #0xc008 -> client_monitor_ex: Client_MonitorExtended_Data; @@ -230,6 +230,16 @@ type Client_Network_Data = record { channel_def_array: Client_Channel_Def[channel_count]; } &byteorder=littleendian; +type Client_Cluster_Data = record { + flags: uint32; + redir_session_id: uint32; +} &let { + REDIRECTION_SUPPORTED: bool = redir_session_id & 0x00000001; + SERVER_SESSION_REDIRECTION_VERSION_MASK: uint8 = (redir_session_id & 0x0000003C); + REDIRECTED_SESSIONID_FIELD_VALID: bool = (redir_session_id & 0x00000002); + REDIRECTED_SMARTCARD: bool = redir_session_id & 0x00000040; +} &byteorder=littleendian; + type Client_Channel_Def = record { name: bytestring &length=8; options: uint32; diff --git a/src/analyzer/protocol/rdp/types.bif b/src/analyzer/protocol/rdp/types.bif index 69cbe14dd3..366676d017 100644 --- a/src/analyzer/protocol/rdp/types.bif +++ b/src/analyzer/protocol/rdp/types.bif @@ -5,6 +5,7 @@ type EarlyCapabilityFlags: record; type ClientCoreData: record; type ClientSecurityData: record; +type ClientClusterData: record; type ClientChannelList: vector; type ClientChannelDef: record; diff --git a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-client-cluster-data/out b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-client-cluster-data/out new file mode 100644 index 0000000000..53973a2324 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-client-cluster-data/out @@ -0,0 +1,12 @@ +RDP Client Cluster Data +Flags: 0000000d +RedirSessionId: 00000000 +Redirection Supported: 00000000 +ServerSessionRedirectionVersionMask: 00000000 +RedirectionSessionIDFieldValid: 00000000 +RedirectedSmartCard: 00000000 +RDP Client Channel List Options +80800000 +c0000000 +c0800000 +c0a00000 diff --git a/testing/btest/scripts/base/protocols/rdp/rdp-client-cluster-data.zeek b/testing/btest/scripts/base/protocols/rdp/rdp-client-cluster-data.zeek new file mode 100644 index 0000000000..7bea9c16e1 --- /dev/null +++ b/testing/btest/scripts/base/protocols/rdp/rdp-client-cluster-data.zeek @@ -0,0 +1,22 @@ +# @TEST-EXEC: zeek -r $TRACES/rdp/rdp-proprietary-encryption.pcap %INPUT >out +# @TEST-EXEC: btest-diff out + +@load base/protocols/rdp + +event rdp_client_cluster_data(c: connection, data: RDP::ClientClusterData) + { + print "RDP Client Cluster Data"; + print fmt("Flags: %08x",data$flags); + print fmt("RedirSessionId: %08x",data$redir_session_id); + print fmt("Redirection Supported: %08x",data$redir_supported); + print fmt("ServerSessionRedirectionVersionMask: %08x",data$svr_session_redir_version_mask); + print fmt("RedirectionSessionIDFieldValid: %08x",data$redir_sessionid_field_valid); + print fmt("RedirectedSmartCard: %08x",data$redir_smartcard); + } + +event rdp_client_network_data(c: connection, channels: RDP::ClientChannelList) + { + print "RDP Client Channel List Options"; + for ( i in channels ) + print fmt("%08x", channels[i]$options); + }