diff --git a/CHANGES b/CHANGES index e3d5ef4d67..bb3e3d3ea2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,11 @@ +2.6-345 | 2019-05-28 11:32:16 -0700 + + * RDP: Add parsing and logging of channels requested by the client. (Vlad Grigorescu) + + Can determine capabilities requested by the client, as well as attacks such + as CVE-2019-0708. + 2.6-342 | 2019-05-28 10:48:37 -0700 * GH-168: Improve type-checking for table/set list assignment. (Zeke Medley and Jon Siwek, Corelight) diff --git a/NEWS b/NEWS index e891996542..67f611a080 100644 --- a/NEWS +++ b/NEWS @@ -79,6 +79,9 @@ New Functionality - The ``//i`` convenience syntax for case-insensitive patterns is now also allowed when specifying patterns used in signature files. +- Add a new "client_channels" field to rdp.log based on data parsed from + the Client Network Data (TS_UD_CS_NET) packet. + Changed Functionality --------------------- diff --git a/VERSION b/VERSION index 9e0e1e66ea..b4b13dd274 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.6-342 +2.6-345 diff --git a/doc b/doc index 3db2ff8fa6..e38523b0ed 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 3db2ff8fa65f5acb3f7807a0302d5c81db1e2227 +Subproject commit e38523b0edf6dd1373b116bb46e16f89420e0e70 diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 7e07225a17..6cfddfeb65 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -4275,6 +4275,38 @@ export { ec_flags: RDP::EarlyCapabilityFlags &optional; dig_product_id: string &optional; }; + + ## Name and flags for a single channel requested by the client. + type RDP::ClientChannelDef: record { + ## A unique name for the channel + name: string; + ## Absence of this flag indicates that this channel is + ## a placeholder and that the server MUST NOT set it up. + initialized: bool; + ## Unused, must be ignored by the server. + encrypt_rdp: bool; + ## Unused, must be ignored by the server. + encrypt_sc: bool; + ## Unused, must be ignored by the server. + encrypt_cs: bool; + ## Channel data must be sent with high MCS priority. + pri_high: bool; + ## Channel data must be sent with medium MCS priority. + pri_med: bool; + ## Channel data must be sent with low MCS priority. + pri_low: bool; + ## Virtual channel data must be compressed if RDP data is being compressed. + compress_rdp: bool; + ## Virtual channel data must be compressed. + compress: bool; + ## Ignored by the server. + show_protocol: bool; + ## Channel must be persistent across remote control transactions. + persistent: bool; + }; + + ## The list of channels requested by the client. + type RDP::ClientChannelList: vector of ClientChannelDef; } @load base/bif/plugins/Bro_SNMP.types.bif diff --git a/scripts/base/protocols/rdp/main.zeek b/scripts/base/protocols/rdp/main.zeek index 39c3ef8fd8..4f55ad6389 100644 --- a/scripts/base/protocols/rdp/main.zeek +++ b/scripts/base/protocols/rdp/main.zeek @@ -23,6 +23,8 @@ export { result: string &log &optional; ## Security protocol chosen by the server. security_protocol: string &log &optional; + ## The channels requested by the client + client_channels: vector of string &log &optional; ## Keyboard layout (language) of the client machine. keyboard_layout: string &log &optional; @@ -189,6 +191,18 @@ event rdp_client_core_data(c: connection, data: RDP::ClientCoreData) &priority=5 c$rdp$requested_color_depth = RDP::high_color_depths[data$high_color_depth]; } +event rdp_client_network_data(c: connection, channels: ClientChannelList) + { + set_session(c); + + if ( ! c$rdp?$client_channels ) + c$rdp$client_channels = vector(); + + for ( i in channels ) + # Remove the NULs at the end + c$rdp$client_channels[i] = gsub(channels[i]$name, /\x00+$/, ""); + } + event rdp_gcc_server_create_response(c: connection, result: count) &priority=5 { set_session(c); diff --git a/src/analyzer/protocol/rdp/events.bif b/src/analyzer/protocol/rdp/events.bif index 3a86e45773..463e3b8d07 100644 --- a/src/analyzer/protocol/rdp/events.bif +++ b/src/analyzer/protocol/rdp/events.bif @@ -26,6 +26,13 @@ event rdp_negotiation_failure%(c: connection, failure_code: count%); ## data: The data contained in the client core data structure. event rdp_client_core_data%(c: connection, data: RDP::ClientCoreData%); +## Generated for Client Network Data (TS_UD_CS_NET) packets +## +## c: The connection record for the underlying transport-layer session/flow. +## +## channels: The channels that were requested +event rdp_client_network_data%(c: connection, channels: RDP::ClientChannelList%); + ## Generated for MCS server responses. ## ## c: The connection record for the underlying transport-layer session/flow. @@ -58,4 +65,4 @@ event rdp_server_certificate%(c: connection, cert_type: count, permanently_issue ## c: The connection record for the underlying transport-layer session/flow. ## ## security_protocol: The security protocol being used for the session. -event rdp_begin_encryption%(c: connection, security_protocol: count%); \ No newline at end of file +event rdp_begin_encryption%(c: connection, security_protocol: count%); diff --git a/src/analyzer/protocol/rdp/rdp-analyzer.pac b/src/analyzer/protocol/rdp/rdp-analyzer.pac index 9c370887a2..cf673e81b2 100644 --- a/src/analyzer/protocol/rdp/rdp-analyzer.pac +++ b/src/analyzer/protocol/rdp/rdp-analyzer.pac @@ -101,6 +101,44 @@ refine flow RDP_Flow += { return true; %} + function proc_rdp_client_network_data(cnetwork: Client_Network_Data): bool + %{ + if ( ! rdp_client_network_data ) + return false; + + if ( ${cnetwork.channel_def_array}->size() ) + { + VectorVal* channels = new VectorVal(BifType::Vector::RDP::ClientChannelList); + + for ( uint i = 0; i < ${cnetwork.channel_def_array}->size(); ++i ) + { + 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->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})); + + channels->Assign(channels->Size(), channel_def); + } + + BifEvent::generate_rdp_client_network_data(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + channels); + } + + return true; + %} + function proc_rdp_server_security(ssd: Server_Security_Data): bool %{ connection()->bro_analyzer()->ProtocolConfirmation(); @@ -165,6 +203,10 @@ refine typeattr Client_Core_Data += &let { proc: bool = $context.flow.proc_rdp_client_core_data(this); }; +refine typeattr Client_Network_Data += &let { + proc: bool = $context.flow.proc_rdp_client_network_data(this); +}; + refine typeattr GCC_Server_Create_Response += &let { proc: bool = $context.flow.proc_rdp_gcc_server_create_response(this); }; @@ -180,3 +222,4 @@ refine typeattr Server_Certificate += &let { refine typeattr X509_Cert_Data += &let { proc: bool = $context.flow.proc_x509_cert_data(this); }; + diff --git a/src/analyzer/protocol/rdp/rdp-protocol.pac b/src/analyzer/protocol/rdp/rdp-protocol.pac index 602e104b2a..46202f379e 100644 --- a/src/analyzer/protocol/rdp/rdp-protocol.pac +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -53,7 +53,7 @@ type Data_Block = record { block: case header.type of { 0xc001 -> client_core: Client_Core_Data; #0xc002 -> client_security: Client_Security_Data; - #0xc003 -> client_network: Client_Network_Data; + 0xc003 -> client_network: Client_Network_Data; #0xc004 -> client_cluster: Client_Cluster_Data; #0xc005 -> client_monitor: Client_Monitor_Data; #0xc006 -> client_msgchannel: Client_MsgChannel_Data; @@ -220,6 +220,28 @@ type Client_Core_Data = record { SUPPORT_HEARTBEAT_PDU: bool = early_capability_flags & 0x0400; } &byteorder=littleendian; +type Client_Network_Data = record { + channel_count: uint32; + channel_def_array: Client_Channel_Def[channel_count]; +} &byteorder=littleendian; + +type Client_Channel_Def = record { + name: bytestring &length=8; + options: uint32; +} &let { + REMOTE_CONTROL_PERSISTENT: bool = options & 0x00100000; + CHANNEL_OPTION_SHOW_PROTOCOL: bool = options & 0x00200000; + CHANNEL_OPTION_COMPRESS: bool = options & 0x00400000; + CHANNEL_OPTION_COMPRESS_RDP: bool = options & 0x00800000; + CHANNEL_OPTION_PRI_LOW: bool = options & 0x02000000; + CHANNEL_OPTION_PRI_MED: bool = options & 0x04000000; + CHANNEL_OPTION_PRI_HIGH: bool = options & 0x08000000; + CHANNEL_OPTION_ENCRYPT_CS: bool = options & 0x10000000; + CHANNEL_OPTION_ENCRYPT_SC: bool = options & 0x20000000; + CHANNEL_OPTION_ENCRYPT_RDP: bool = options & 0x40000000; + CHANNEL_OPTION_INITIALIZED: bool = options & 0x80000000; +} &byteorder=littleendian; + ###################################################################### # Server MCS ###################################################################### diff --git a/src/analyzer/protocol/rdp/types.bif b/src/analyzer/protocol/rdp/types.bif index 8222560331..d5a7f930a9 100644 --- a/src/analyzer/protocol/rdp/types.bif +++ b/src/analyzer/protocol/rdp/types.bif @@ -3,3 +3,6 @@ module RDP; type EarlyCapabilityFlags: record; type ClientCoreData: record; + +type ClientChannelList: vector; +type ClientChannelDef: record; \ No newline at end of file diff --git a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-proprietary-encryption/rdp.log b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-proprietary-encryption/rdp.log index c32ebd3fbb..bf8b038223 100644 --- a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-proprietary-encryption/rdp.log +++ b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-proprietary-encryption/rdp.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path rdp -#open 2016-07-13-16-16-47 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result security_protocol keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent encryption_level encryption_method -#types time string addr port addr port string string string string string string string count count string string count bool string string -1193369795.014346 CHhAvVGS1DHFjwGM9 172.21.128.16 1311 10.226.24.52 3389 FTBCO\\A70 SSL_NOT_ALLOWED_BY_SERVER - - - - - - - - - 0 - - - -1193369797.582740 ClEkJM2Vm5giqnMf4h 172.21.128.16 1312 10.226.24.52 3389 FTBCO\\A70 Success RDP English - United States RDP 6.0 FROG-POND (empty) 1152 864 32bit RSA 1 T High 128bit -#close 2016-07-13-16-16-48 +#open 2019-05-28-14-29-19 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result security_protocol client_channels keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent encryption_level encryption_method +#types time string addr port addr port string string string vector[string] string string string string count count string string count bool string string +1193369795.014346 CHhAvVGS1DHFjwGM9 172.21.128.16 1311 10.226.24.52 3389 FTBCO\\A70 SSL_NOT_ALLOWED_BY_SERVER - - - - - - - - - - 0 - - - +1193369797.582740 ClEkJM2Vm5giqnMf4h 172.21.128.16 1312 10.226.24.52 3389 FTBCO\\A70 Success RDP rdpdr,rdpsnd,drdynvc,cliprdr English - United States RDP 6.0 FROG-POND (empty) 1152 864 32bit RSA 1 T High 128bit +#close 2019-05-28-14-29-19 diff --git a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-to-ssl/rdp.log b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-to-ssl/rdp.log index 247e2e56f3..d6be31000c 100644 --- a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-to-ssl/rdp.log +++ b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-to-ssl/rdp.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path rdp -#open 2016-07-13-16-16-48 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result security_protocol keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent encryption_level encryption_method -#types time string addr port addr port string string string string string string string count count string string count bool string string -1297551041.284715 CHhAvVGS1DHFjwGM9 192.168.1.200 49206 192.168.1.150 3389 AWAKECODI encrypted HYBRID - - - - - - - - 0 - - - -1297551078.958821 ClEkJM2Vm5giqnMf4h 192.168.1.200 49207 192.168.1.150 3389 AWAKECODI encrypted HYBRID - - - - - - - - 0 - - - -#close 2016-07-13-16-16-48 +#open 2019-05-28-14-29-20 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result security_protocol client_channels keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent encryption_level encryption_method +#types time string addr port addr port string string string vector[string] string string string string count count string string count bool string string +1297551041.284715 CHhAvVGS1DHFjwGM9 192.168.1.200 49206 192.168.1.150 3389 AWAKECODI encrypted HYBRID - - - - - - - - - 0 - - - +1297551078.958821 ClEkJM2Vm5giqnMf4h 192.168.1.200 49207 192.168.1.150 3389 AWAKECODI encrypted HYBRID - - - - - - - - - 0 - - - +#close 2019-05-28-14-29-20 diff --git a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/rdp.log b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/rdp.log index 2ee8af8095..e3a87b0edd 100644 --- a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/rdp.log +++ b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/rdp.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path rdp -#open 2016-07-13-16-16-49 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result security_protocol keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent encryption_level encryption_method -#types time string addr port addr port string string string string string string string count count string string count bool string string -1423755598.202845 CHhAvVGS1DHFjwGM9 192.168.1.1 54990 192.168.1.2 3389 JOHN-PC Success RDP English - United States RDP 8.1 JOHN-PC-LAPTOP 3c571ed0-3415-474b-ae94-74e151b 1920 1080 16bit X.509 2 F Client compatible 128bit -#close 2016-07-13-16-16-49 +#open 2019-05-28-14-29-20 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result security_protocol client_channels keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent encryption_level encryption_method +#types time string addr port addr port string string string vector[string] string string string string count count string string count bool string string +1423755598.202845 CHhAvVGS1DHFjwGM9 192.168.1.1 54990 192.168.1.2 3389 JOHN-PC Success RDP rdpdr,rdpsnd,cliprdr,drdynvc English - United States RDP 8.1 JOHN-PC-LAPTOP 3c571ed0-3415-474b-ae94-74e151b 1920 1080 16bit X.509 2 F Client compatible 128bit +#close 2019-05-28-14-29-20