diff --git a/scripts/base/protocols/rdp/consts.bro b/scripts/base/protocols/rdp/consts.bro index a37e1d3188..19a7c44c5a 100644 --- a/scripts/base/protocols/rdp/consts.bro +++ b/scripts/base/protocols/rdp/consts.bro @@ -19,6 +19,27 @@ export { [25282] = "RDP 8.0 (Mac)" } &default = function(n: count): string { return fmt("client_build-%d", n); }; + const security_protocols = { + [0x00] = "RDP", + [0x01] = "SSL", + [0x02] = "HYBRID", + [0x08] = "HYBRID_EX" + } &default = function(n: count): string { return fmt("security_protocol-%d", n); }; + + const failure_codes = { + [0x01] = "SSL_REQUIRED_BY_SERVER", + [0x02] = "SSL_NOT_ALLOWED_BY_SERVER", + [0x03] = "SSL_CERT_NOT_ON_SERVER", + [0x04] = "INCONSISTENT_FLAGS", + [0x05] = "HYBRID_REQUIRED_BY_SERVER", + [0x06] = "SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER" + } &default = function(n: count): string { return fmt("failure_code-%d", n); }; + + const cert_types = { + [1] = "RSA", + [2] = "X.509" + } &default = function(n: count): string { return fmt("cert_type-%d", n); }; + const encryption_methods = { [0] = "None", [1] = "40bit", diff --git a/scripts/base/protocols/rdp/main.bro b/scripts/base/protocols/rdp/main.bro index 9297ec83a3..f8fb15382d 100644 --- a/scripts/base/protocols/rdp/main.bro +++ b/scripts/base/protocols/rdp/main.bro @@ -15,6 +15,11 @@ export { ## Cookie value used by the client machine. ## This is typically a username. cookie: string &log &optional; + ## Status result for the connection. It's a mix between + ## RDP negotation failure messages and GCC server create + ## response messages. + result: string &log &optional; + ## Keyboard layout (language) of the client machine. keyboard_layout: string &log &optional; ## RDP client version used by the client machine. @@ -30,8 +35,19 @@ export { ## The color depth requested by the client in ## the high_color_depth field. requested_color_depth: string &log &optional; - ## GCC result for the connection. - result: string &log &optional; + + ## If the connection is being encrypted with native + ## RDP encryption, this is the type of cert + ## being used. + cert_type: string &log &optional; + ## The number of certs seen. X.509 can transfer an + ## entire certificate chain. + cert_count: count &log &default=0; + ## Indicates if the provided certificate or certificate + ## chain is permanent or temporary. + cert_permanent: bool &log &optional; + ## Security protocol chosen by the server. + selected_security_protocol: string &log &optional; ## Encryption level of the connection. encryption_level: string &log &optional; ## Encryption method of the connection. @@ -132,13 +148,27 @@ function set_session(c: connection) } } -event rdp_client_request(c: connection, cookie: string) &priority=5 +event rdp_connect_request(c: connection, cookie: string) &priority=5 { set_session(c); c$rdp$cookie = cookie; } +event rdp_negotiation_response(c: connection, selected_security_protocol: count) &priority=5 + { + set_session(c); + + c$rdp$selected_security_protocol = security_protocols[selected_security_protocol]; + } + +event rdp_negotiation_failure(c: connection, failure_code: count) &priority=5 + { + set_session(c); + + c$rdp$result = failure_codes[failure_code]; + } + event rdp_client_core_data(c: connection, data: RDP::ClientCoreData) &priority=5 { set_session(c); @@ -150,12 +180,12 @@ event rdp_client_core_data(c: connection, data: RDP::ClientCoreData) &priority=5 c$rdp$desktop_width = data$desktop_width; c$rdp$desktop_height = data$desktop_height; if ( data?$ec_flags && data$ec_flags$want_32bpp_session ) - c$rdp$requested_color_depth = "32-bit"; + c$rdp$requested_color_depth = "32bit"; else c$rdp$requested_color_depth = RDP::high_color_depths[data$high_color_depth]; } -event rdp_result(c: connection, result: count) &priority=5 +event rdp_gcc_server_create_response(c: connection, result: count) &priority=5 { set_session(c); @@ -170,13 +200,31 @@ event rdp_server_security(c: connection, encryption_method: count, encryption_le c$rdp$encryption_level = RDP::encryption_levels[encryption_level]; } -event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) +event rdp_server_certificate(c: connection, cert_type: count, permanently_issued: bool) &priority=5 { - Files::add_analyzer(f, Files::ANALYZER_X509); - # always calculate hashes. They are not necessary for base scripts - # but very useful for identification, and required for policy scripts - Files::add_analyzer(f, Files::ANALYZER_MD5); - Files::add_analyzer(f, Files::ANALYZER_SHA1); + set_session(c); + + c$rdp$cert_type = RDP::cert_types[cert_type]; + + # There are no events for proprietary/RSA certs right + # now so we manually count this one. + if ( c$rdp$cert_type == "RSA" ) + ++c$rdp$cert_count; + + c$rdp$cert_permanent = permanently_issued; + } + +event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5 + { + if ( c?$rdp && f$source == "RDP" ) + { + ## Count up X509 certs. + ++c$rdp$cert_count; + + Files::add_analyzer(f, Files::ANALYZER_X509); + Files::add_analyzer(f, Files::ANALYZER_MD5); + Files::add_analyzer(f, Files::ANALYZER_SHA1); + } } event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5 diff --git a/src/analyzer/protocol/rdp/RDP.cc b/src/analyzer/protocol/rdp/RDP.cc index c38292ad21..dafa7f4c2f 100644 --- a/src/analyzer/protocol/rdp/RDP.cc +++ b/src/analyzer/protocol/rdp/RDP.cc @@ -51,34 +51,26 @@ void RDP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) // we'll just move this over to the PIA analyzer. // Like the comment below says, this is probably the wrong // way to handle this. - if ( len > 0 && data[0] >= 0x14 && data[0] <= 0x17 ) + if ( interp->is_encrypted() ) { - if ( ! pia ) + if ( len > 0 && data[0] >= 0x14 && data[0] <= 0x17 ) { - pia = new pia::PIA_TCP(Conn()); - - if ( AddChildAnalyzer(pia) ) + if ( ! pia ) { - pia->FirstPacket(true, 0); - pia->FirstPacket(false, 0); - } - } + pia = new pia::PIA_TCP(Conn()); - if ( pia ) - { - ForwardStream(len, data, orig); + if ( AddChildAnalyzer(pia) ) + { + pia->FirstPacket(true, 0); + pia->FirstPacket(false, 0); + } + } + + if ( pia ) + ForwardStream(len, data, orig); } } - else if ( pia ) - { - // This is data that doesn't seem to match - // an SSL record, but we've moved into SSL mode. - // This is probably the wrong way to handle this - // situation but I don't know what these records - // are that don't appear to be SSL/TLS. - return; - } - else + else // if not encrypted { try { diff --git a/src/analyzer/protocol/rdp/events.bif b/src/analyzer/protocol/rdp/events.bif index 4885377d57..80546780f5 100644 --- a/src/analyzer/protocol/rdp/events.bif +++ b/src/analyzer/protocol/rdp/events.bif @@ -1,25 +1,39 @@ -## Generated for X.224 client requests when native RDP encryption is used. +## Generated for X.224 client requests. ## ## c: The connection record for the underlying transport-layer session/flow. ## ## cookie: The cookie included in the request. -event rdp_client_request%(c: connection, cookie: string%); +event rdp_connect_request%(c: connection, cookie: string%); -## Generated for MCS client requests when native RDP encryption is used. +## Generated for RDP Negotiation Response messages. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## selected_security_protocol: The security protocol selected by the server. +event rdp_negotiation_response%(c: connection, selected_security_protocol: count%); + +## Generated for RDP Negotiation Failure messages. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## failure_code: The failure code sent by the server. +event rdp_negotiation_failure%(c: connection, failure_code: count%); + +## Generated for MCS client requests. ## ## c: The connection record for the underlying transport-layer session/flow. ## ## data: The data contained in the client core data structure. event rdp_client_core_data%(c: connection, data: RDP::ClientCoreData%); -## Generated for MCS server responses when native RDP encryption is used. +## Generated for MCS server responses. ## ## c: The connection record for the underlying transport-layer session/flow. ## ## result: The 8-bit integer representing the GCC Conference Create Response result. -event rdp_result%(c: connection, result: count%); +event rdp_gcc_server_create_response%(c: connection, result: count%); -## Generated for MCS server responses when native RDP encryption is used. +## Generated for MCS server responses. ## ## c: The connection record for the underlying transport-layer session/flow. ## @@ -27,3 +41,14 @@ event rdp_result%(c: connection, result: count%); ## ## encryption_level: The 32-bit integer representing the encryption level used in the connection. event rdp_server_security%(c: connection, encryption_method: count, encryption_level: count%); + +## Generated for a server certificate section. If multiple X.509 +## certificates are included in chain, this event will still +## only be generated a single time. +## +## c: The connection record for the underlying transport-layer session/flow. +## +## cert_type: Indicates the type of certificate. +## +## permanently_issued: Value will be true is the certificate(s) is permanent on the server. +event rdp_server_certificate%(c: connection, cert_type: count, permanently_issued: bool%); \ No newline at end of file diff --git a/src/analyzer/protocol/rdp/rdp-analyzer.pac b/src/analyzer/protocol/rdp/rdp-analyzer.pac index 01e4115970..b594172333 100644 --- a/src/analyzer/protocol/rdp/rdp-analyzer.pac +++ b/src/analyzer/protocol/rdp/rdp-analyzer.pac @@ -8,11 +8,14 @@ refine flow RDP_Flow += { function utf16_to_utf8_val(utf16: bytestring): StringVal %{ - size_t utf8size = 3 * utf16.length() + 1; - char* utf8stringnative = new char[utf8size]; + std::string resultstring; + size_t widesize = utf16.length(); + + size_t utf8size = 3 * widesize + 1; + resultstring.resize(utf8size, '\0'); const UTF16* sourcestart = reinterpret_cast(utf16.begin()); - const UTF16* sourceend = sourcestart + utf16.length(); - UTF8* targetstart = reinterpret_cast(utf8stringnative); + const UTF16* sourceend = sourcestart + widesize; + UTF8* targetstart = reinterpret_cast(&resultstring[0]); UTF8* targetend = targetstart + utf8size; ConversionResult res = ConvertUTF16toUTF8(&sourcestart, @@ -20,33 +23,63 @@ refine flow RDP_Flow += { &targetstart, targetend, strictConversion); - *targetstart = 0; - if ( res != conversionOK ) { connection()->bro_analyzer()->Weird("Failed UTF-16 to UTF-8 conversion"); return new StringVal(utf16.length(), (const char *) utf16.begin()); } + *targetstart = 0; // We're relying on no nulls being in the string. - return new StringVal(utf8stringnative); + return new StringVal(resultstring.c_str()); %} - function proc_rdp_client_request(client_request: Client_Request): bool + function proc_rdp_connect_request(cr: Connect_Request): bool %{ - connection()->bro_analyzer()->ProtocolConfirmation(); - BifEvent::generate_rdp_client_request(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - bytestring_to_val(${client_request.cookie_value})); + if ( rdp_connect_request ) + { + BifEvent::generate_rdp_connect_request(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + bytestring_to_val(${cr.cookie_value})); + } + return true; %} - function proc_rdp_result(gcc_response: GCC_Server_Create_Response): bool + function proc_rdp_negotiation_response(nr: RDP_Negotiation_Response): bool + %{ + if ( rdp_negotiation_response ) + { + BifEvent::generate_rdp_negotiation_response(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${nr.selected_protocol}); + } + + return true; + %} + + function proc_rdp_negotiation_failure(nf: RDP_Negotiation_Failure): bool + %{ + if ( rdp_negotiation_failure ) + { + BifEvent::generate_rdp_negotiation_failure(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${nf.failure_code}); + } + + return true; + %} + + + function proc_rdp_gcc_server_create_response(gcc_response: GCC_Server_Create_Response): bool %{ connection()->bro_analyzer()->ProtocolConfirmation(); - BifEvent::generate_rdp_result(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - ${gcc_response.result}); + + if ( rdp_gcc_server_create_response ) + BifEvent::generate_rdp_gcc_server_create_response(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${gcc_response.result}); + return true; %} @@ -55,56 +88,76 @@ refine flow RDP_Flow += { %{ connection()->bro_analyzer()->ProtocolConfirmation(); - RecordVal* ec_flags = new RecordVal(BifType::Record::RDP::EarlyCapabilityFlags); - ec_flags->Assign(0, new Val(${ccore.SUPPORT_ERRINFO_PDU}, TYPE_BOOL)); - ec_flags->Assign(1, new Val(${ccore.WANT_32BPP_SESSION}, TYPE_BOOL)); - ec_flags->Assign(2, new Val(${ccore.SUPPORT_STATUSINFO_PDU}, TYPE_BOOL)); - ec_flags->Assign(3, new Val(${ccore.STRONG_ASYMMETRIC_KEYS}, TYPE_BOOL)); - ec_flags->Assign(4, new Val(${ccore.SUPPORT_MONITOR_LAYOUT_PDU}, TYPE_BOOL)); - ec_flags->Assign(5, new Val(${ccore.SUPPORT_NETCHAR_AUTODETECT}, TYPE_BOOL)); - ec_flags->Assign(6, new Val(${ccore.SUPPORT_DYNVC_GFX_PROTOCOL}, TYPE_BOOL)); - ec_flags->Assign(7, new Val(${ccore.SUPPORT_DYNAMIC_TIME_ZONE}, TYPE_BOOL)); - ec_flags->Assign(8, new Val(${ccore.SUPPORT_HEARTBEAT_PDU}, TYPE_BOOL)); + if ( rdp_client_core_data ) + { + RecordVal* ec_flags = new RecordVal(BifType::Record::RDP::EarlyCapabilityFlags); + ec_flags->Assign(0, new Val(${ccore.SUPPORT_ERRINFO_PDU}, TYPE_BOOL)); + ec_flags->Assign(1, new Val(${ccore.WANT_32BPP_SESSION}, TYPE_BOOL)); + ec_flags->Assign(2, new Val(${ccore.SUPPORT_STATUSINFO_PDU}, TYPE_BOOL)); + ec_flags->Assign(3, new Val(${ccore.STRONG_ASYMMETRIC_KEYS}, TYPE_BOOL)); + ec_flags->Assign(4, new Val(${ccore.SUPPORT_MONITOR_LAYOUT_PDU}, TYPE_BOOL)); + ec_flags->Assign(5, new Val(${ccore.SUPPORT_NETCHAR_AUTODETECT}, TYPE_BOOL)); + ec_flags->Assign(6, new Val(${ccore.SUPPORT_DYNVC_GFX_PROTOCOL}, TYPE_BOOL)); + ec_flags->Assign(7, new Val(${ccore.SUPPORT_DYNAMIC_TIME_ZONE}, TYPE_BOOL)); + ec_flags->Assign(8, new Val(${ccore.SUPPORT_HEARTBEAT_PDU}, TYPE_BOOL)); - RecordVal* ccd = new RecordVal(BifType::Record::RDP::ClientCoreData); - ccd->Assign(0, new Val(${ccore.version_major}, TYPE_COUNT)); - ccd->Assign(1, new Val(${ccore.version_minor}, TYPE_COUNT)); - ccd->Assign(2, new Val(${ccore.desktop_width}, TYPE_COUNT)); - ccd->Assign(3, new Val(${ccore.desktop_height}, TYPE_COUNT)); - ccd->Assign(4, new Val(${ccore.color_depth}, TYPE_COUNT)); - ccd->Assign(5, new Val(${ccore.sas_sequence}, TYPE_COUNT)); - ccd->Assign(6, new Val(${ccore.keyboard_layout}, TYPE_COUNT)); - ccd->Assign(7, new Val(${ccore.client_build}, TYPE_COUNT)); - ccd->Assign(8, utf16_to_utf8_val(${ccore.client_name})); - ccd->Assign(9, new Val(${ccore.keyboard_type}, TYPE_COUNT)); - ccd->Assign(10, new Val(${ccore.keyboard_sub}, TYPE_COUNT)); - ccd->Assign(11, new Val(${ccore.keyboard_function_key}, TYPE_COUNT)); - ccd->Assign(12, utf16_to_utf8_val(${ccore.ime_file_name})); - ccd->Assign(13, new Val(${ccore.post_beta2_color_depth}, TYPE_COUNT)); - ccd->Assign(14, new Val(${ccore.client_product_id}, TYPE_COUNT)); - ccd->Assign(15, new Val(${ccore.serial_number}, TYPE_COUNT)); - ccd->Assign(16, new Val(${ccore.high_color_depth}, TYPE_COUNT)); - ccd->Assign(17, new Val(${ccore.supported_color_depths}, TYPE_COUNT)); - ccd->Assign(18, ec_flags); - ccd->Assign(19, utf16_to_utf8_val(${ccore.dig_product_id})); + RecordVal* ccd = new RecordVal(BifType::Record::RDP::ClientCoreData); + ccd->Assign(0, new Val(${ccore.version_major}, TYPE_COUNT)); + ccd->Assign(1, new Val(${ccore.version_minor}, TYPE_COUNT)); + ccd->Assign(2, new Val(${ccore.desktop_width}, TYPE_COUNT)); + ccd->Assign(3, new Val(${ccore.desktop_height}, TYPE_COUNT)); + ccd->Assign(4, new Val(${ccore.color_depth}, TYPE_COUNT)); + ccd->Assign(5, new Val(${ccore.sas_sequence}, TYPE_COUNT)); + ccd->Assign(6, new Val(${ccore.keyboard_layout}, TYPE_COUNT)); + ccd->Assign(7, new Val(${ccore.client_build}, TYPE_COUNT)); + ccd->Assign(8, utf16_to_utf8_val(${ccore.client_name})); + ccd->Assign(9, new Val(${ccore.keyboard_type}, TYPE_COUNT)); + ccd->Assign(10, new Val(${ccore.keyboard_sub}, TYPE_COUNT)); + ccd->Assign(11, new Val(${ccore.keyboard_function_key}, TYPE_COUNT)); + ccd->Assign(12, utf16_to_utf8_val(${ccore.ime_file_name})); + ccd->Assign(13, new Val(${ccore.post_beta2_color_depth}, TYPE_COUNT)); + ccd->Assign(14, new Val(${ccore.client_product_id}, TYPE_COUNT)); + ccd->Assign(15, new Val(${ccore.serial_number}, TYPE_COUNT)); + ccd->Assign(16, new Val(${ccore.high_color_depth}, TYPE_COUNT)); + ccd->Assign(17, new Val(${ccore.supported_color_depths}, TYPE_COUNT)); + ccd->Assign(18, ec_flags); + ccd->Assign(19, utf16_to_utf8_val(${ccore.dig_product_id})); + + BifEvent::generate_rdp_client_core_data(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ccd); + } - BifEvent::generate_rdp_client_core_data(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - ccd); return true; %} function proc_rdp_server_security(ssd: Server_Security_Data): bool %{ connection()->bro_analyzer()->ProtocolConfirmation(); - BifEvent::generate_rdp_server_security(connection()->bro_analyzer(), - connection()->bro_analyzer()->Conn(), - ${ssd.encryption_method}, - ${ssd.encryption_level}); + + if ( rdp_server_security ) + BifEvent::generate_rdp_server_security(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${ssd.encryption_method}, + ${ssd.encryption_level}); + return true; %} - function proc_x509_cert(x509: X509): bool + function proc_rdp_server_certificate(cert: Server_Certificate): bool + %{ + if ( rdp_server_certificate ) + { + BifEvent::generate_rdp_server_certificate(connection()->bro_analyzer(), + connection()->bro_analyzer()->Conn(), + ${cert.cert_type}, + ${cert.permanently_issued}); + } + + return true; + %} + + function proc_x509_cert_data(x509: X509_Cert_Data): bool %{ const bytestring& cert = ${x509.cert}; @@ -126,8 +179,16 @@ refine flow RDP_Flow += { %} }; -refine typeattr Client_Request += &let { - proc: bool = $context.flow.proc_rdp_client_request(this); +refine typeattr Connect_Request += &let { + proc: bool = $context.flow.proc_rdp_connect_request(this); +}; + +refine typeattr RDP_Negotiation_Response += &let { + proc: bool = $context.flow.proc_rdp_negotiation_response(this); +}; + +refine typeattr RDP_Negotiation_Failure += &let { + proc: bool = $context.flow.proc_rdp_negotiation_failure(this); }; refine typeattr Client_Core_Data += &let { @@ -135,13 +196,17 @@ refine typeattr Client_Core_Data += &let { }; refine typeattr GCC_Server_Create_Response += &let { - proc: bool = $context.flow.proc_rdp_result(this); + proc: bool = $context.flow.proc_rdp_gcc_server_create_response(this); }; refine typeattr Server_Security_Data += &let { proc: bool = $context.flow.proc_rdp_server_security(this); }; -refine typeattr X509 += &let { - proc: bool = $context.flow.proc_x509_cert(this); +refine typeattr Server_Certificate += &let { + proc: bool = $context.flow.proc_rdp_server_certificate(this); +}; + +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 8d24fb05b9..d2efcc6194 100644 --- a/src/analyzer/protocol/rdp/rdp-protocol.pac +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -14,12 +14,10 @@ type TPKT(is_orig: bool) = record { type COTP = record { cotp_len: uint8; pdu: uint8; - # Probably should do something with this eventually. - #cotp_crap: padding[cotp_len-2]; switch: case pdu of { - #0xd0 -> cConfirm: Connect_Confirm; - 0xe0 -> c_request: Client_Request; - 0xf0 -> data: DT_Data; + 0xd0 -> connect_confirm: Connect_Confirm; + 0xe0 -> client_request: Connect_Request; + 0xf0 -> data: DT_Data; # In case we don't support the PDU we just # consume the rest of it and throw it away. @@ -75,14 +73,59 @@ type Data_Block = record { # Client X.224 ###################################################################### -type Client_Request = record { +type Connect_Request = record { destination_reference: uint16; source_reference: uint16; flow_control: uint8; cookie_mstshash: RE/Cookie: mstshash\=/; - cookie_value: RE/[^\x0d]*/; + cookie_value: RE/[^\x0d]+/; + cookie_terminator: RE/\x0d\x0a/; + rdp_neg_req: RDP_Negotiation_Request; +} &byteorder=littleendian; + +type RDP_Negotiation_Request = record { + type: uint8; + flags: uint8; + length: uint16; # must be set to 8 + requested_protocols: uint32; +} &let { + PROTOCOL_RDP: bool = requested_protocols & 0x00; + PROTOCOL_SSL: bool = requested_protocols & 0x01; + PROTOCOL_HYBRID: bool = requested_protocols & 0x02; + PROTOCOL_HYBRID_EX: bool = requested_protocols & 0x08; +} &byteorder=littleendian; + +###################################################################### +# Server X.224 +###################################################################### + +type Connect_Confirm = record { + destination_reference: uint16; + source_reference: uint16; + flags: uint8; + response_type: uint8; + response_switch: case response_type of { + 0x02 -> neg_resp: RDP_Negotiation_Response; + 0x03 -> neg_fail: RDP_Negotiation_Failure; + }; }; +type RDP_Negotiation_Response = record { + flags: uint8; + length: uint16; # must be set to 8 + selected_protocol: uint32; +} &let { + # Seems to be encrypted after this message if + # selected_protocol > 0 + enc: bool = $context.connection.go_encrypted(selected_protocol>0); +} &byteorder=littleendian; + +type RDP_Negotiation_Failure = record { + flags: uint8; + length: uint16; + failure_code: uint32; +} &byteorder=littleendian; + ###################################################################### # Client MCS ###################################################################### @@ -93,11 +136,11 @@ type Client_Header = record { called_domain_selector: ASN1OctetString; upward_flag: ASN1Boolean; target_parameters: ASN1SequenceMeta; - targ_parameters_pad: padding[target_parameters.encoding.length]; + targ_parameters_pad: bytestring &length=target_parameters.encoding.length &transient; minimum_parameters: ASN1SequenceMeta; - min_parameters_pad: padding[minimum_parameters.encoding.length]; + min_parameters_pad: bytestring &length=minimum_parameters.encoding.length &transient; maximum_parameters: ASN1SequenceMeta; - max_parameters_pad: padding[maximum_parameters.encoding.length]; + max_parameters_pad: bytestring &length=maximum_parameters.encoding.length &transient; # BER encoded OctetString and long variant, can be safely skipped for now user_data_length: uint32; gcc_connection_data: GCC_Client_Connection_Data; @@ -174,7 +217,7 @@ type Server_Header = record { connect_response_called_id: ASN1Integer; connect_response_domain_parameters: ASN1SequenceMeta; # Skipping over domain parameters for now. - domain_parameters: padding[connect_response_domain_parameters.encoding.length]; + domain_parameters: bytestring &length=connect_response_domain_parameters.encoding.length &transient; # I think this is another definite length encoded value. user_data_length: uint32; gcc_connection_data: GCC_Server_Connection_Data; @@ -219,20 +262,24 @@ type Server_Security_Data = record { server_cert_length: uint32; server_random: bytestring &length=server_random_length; server_certificate: Server_Certificate &length=server_cert_length; +} &let { + # Seems to be encrypted after this message if + # encryption level is >0 + enc: bool = $context.connection.go_encrypted(encryption_level>0); } &byteorder=littleendian; type Server_Certificate = record { version: uint32; switch: case cert_type of { - 0x01 -> proprietary: Server_Proprietary; + 0x01 -> proprietary: Server_Proprietary_Cert(this); 0x02 -> x509: X509; }; } &let { - cert_type: uint32 = version & 0x7FFFFFFF; - permanent_issue: bool = (version & 0x80000000) == 0; + cert_type: uint32 = version & 0x7FFFFFFF; + permanently_issued: bool = (version & 0x80000000) == 0; } &byteorder=littleendian; -type Server_Proprietary = record { +type Server_Proprietary_Cert(cert: Server_Certificate) = record { signature_algorithm: uint32; key_algorithm: uint32; public_key_blob_type: uint16; @@ -252,8 +299,13 @@ type Public_Key_Blob = record { } &byteorder=littleendian; type X509 = record { - pad1: padding[8]; - cert: bytestring &restofdata; + num_of_certs: uint32; + certs: X509_Cert_Data[num_of_certs]; +} &byteorder=littleendian; + +type X509_Cert_Data = record { + cert_len: uint32; + cert: bytestring &length=cert_len; } &byteorder=littleendian; ###################################################################### @@ -314,3 +366,28 @@ function binary_to_int64(bs: bytestring): int64 return rval; %} +refine connection RDP_Conn += { + + %member{ + bool is_encrypted_; + %} + + %init{ + is_encrypted_ = false; + %} + + function go_encrypted(should_we: bool): bool + %{ + if ( should_we ) + { + printf("going encrypted\n"); + is_encrypted_ = true; + } + return is_encrypted_; + %} + + function is_encrypted(): bool + %{ + return is_encrypted_; + %} +}; \ 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 3a1fcec5ee..f263ae8fbb 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 2015-03-04-17-59-16 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth result encryption_level encryption_method -#types time string addr port addr port string string string string string count count string string string string -1193369797.582740 CjhGID4nQcgTWjvg4c 172.21.128.16 1312 10.226.24.52 3389 FTBCO\A70 English - United States RDP 6.0 FROG-POND (empty) 1152 864 32-bit Success High 128bit -1193369795.014346 CXWv6p3arKYeMETxOg 172.21.128.16 1311 10.226.24.52 3389 FTBCO\A70 - - - - - - - - - - -#close 2015-03-04-17-59-16 +#open 2015-03-05-06-05-01 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent selected_security_protocol encryption_level encryption_method +#types time string addr port addr port string string string string string string count count string string count bool string string string +1193369795.014346 CXWv6p3arKYeMETxOg 172.21.128.16 1311 10.226.24.52 3389 FTBCO\A70 SSL_NOT_ALLOWED_BY_SERVER - - - - - - - - 0 - - - - +1193369797.582740 CjhGID4nQcgTWjvg4c 172.21.128.16 1312 10.226.24.52 3389 FTBCO\A70 Success English - United States RDP 6.0 FROG-POND (empty) 1152 864 32bit RSA 1 T RDP High 128bit +#close 2015-03-05-06-05-01 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 cfcbc9453b..82fac39a72 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 2015-03-04-17-53-51 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth result encryption_level encryption_method -#types time string addr port addr port string string string string string count count string string string string -1297551041.284715 CXWv6p3arKYeMETxOg 192.168.1.200 49206 192.168.1.150 3389 AWAKECODI - - - - - - - - - - -1297551078.958821 CjhGID4nQcgTWjvg4c 192.168.1.200 49207 192.168.1.150 3389 AWAKECODI - - - - - - - - - - -#close 2015-03-04-17-53-51 +#open 2015-03-05-05-25-45 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent selected_security_protocol encryption_level encryption_method +#types time string addr port addr port string string string string string string count count string string count bool string string string +1297551041.284715 CXWv6p3arKYeMETxOg 192.168.1.200 49206 192.168.1.150 3389 AWAKECODI - - - - - - - - - 0 - HYBRID - - +1297551078.958821 CjhGID4nQcgTWjvg4c 192.168.1.200 49207 192.168.1.150 3389 AWAKECODI - - - - - - - - - 0 - HYBRID - - +#close 2015-03-05-05-25-45 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 e17efa3f31..dee1e42cee 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 2015-03-04-17-56-41 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth result encryption_level encryption_method -#types time string addr port addr port string string string string string count count string string string string -1423755598.202845 CXWv6p3arKYeMETxOg 192.168.1.1 54990 192.168.1.2 3389 JOHN-PC English - United States RDP 8.1 JOHN-PC-LAPTOP 3c571ed0-3415-474b-ae94-74e151b 1920 1080 16bit Success Client compatible 128bit -#close 2015-03-04-17-56-41 +#open 2015-03-05-05-26-13 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cookie result keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth cert_type cert_count cert_permanent selected_security_protocol encryption_level encryption_method +#types time string addr port addr port string string string string string string count count string string count bool string string string +1423755598.202845 CXWv6p3arKYeMETxOg 192.168.1.1 54990 192.168.1.2 3389 JOHN-PC Success English - United States RDP 8.1 JOHN-PC-LAPTOP 3c571ed0-3415-474b-ae94-74e151b 1920 1080 16bit X.509 2 F RDP Client compatible 128bit +#close 2015-03-05-05-26-13 diff --git a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/x509.log b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/x509.log index 2e1ad5bb02..31e42b000e 100644 --- a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/x509.log +++ b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-x509/x509.log @@ -3,8 +3,9 @@ #empty_field (empty) #unset_field - #path x509 -#open 2015-03-04-17-56-41 +#open 2015-03-05-05-26-13 #fields ts id certificate.version certificate.serial certificate.subject certificate.issuer certificate.not_valid_before certificate.not_valid_after certificate.key_alg certificate.sig_alg certificate.key_type certificate.key_length certificate.exponent certificate.curve san.dns san.uri san.email san.ip basic_constraints.ca basic_constraints.path_len #types time string count string string string time time string string string count string string vector[string] vector[string] vector[string] vector[addr] bool count 1423755602.103140 F71ADVSn3rOqVhNh1 3 59EB28CB02B1A0D4 L=TURNBKL+CN=SERVR L=TURNBKL+CN=SERVR 1423664106.000000 1431388800.000000 rsaEncryption sha1WithRSA rsa 512 65537 - - - - - T 0 -#close 2015-03-04-17-56-41 +1423755602.103140 F71ADVSn3rOqVhNh1 3 0100000001 serialNumber=1BcKefYSF97EvkaiCqahPY8uPd0=\0D\0A+L=ncalrpc:SERVR+CN=ncalrpc:SERVR L=TURNBKL+CN=SERVR 1365174955.000000 1483228799.000000 md5WithRSAEncryption sha1WithRSA - - - - - - - - - - +#close 2015-03-05-05-26-13