diff --git a/src/analyzer/protocol/rdp/rdp-protocol.pac b/src/analyzer/protocol/rdp/rdp-protocol.pac index e09e54e3ad..3e2f6fde16 100644 --- a/src/analyzer/protocol/rdp/rdp-protocol.pac +++ b/src/analyzer/protocol/rdp/rdp-protocol.pac @@ -92,7 +92,7 @@ type Connect_Request(cotp: COTP) = record { type RDP_Negotiation_Request = record { type: uint8; flags: uint8; - length: uint16; # must be set to 8 + length: uint16 &enforce(length == 8); # must be set to 8 requested_protocols: uint32; } &let { PROTOCOL_RDP: bool = requested_protocols & 0x00; @@ -127,7 +127,7 @@ type Connect_Confirm_Record = record { type RDP_Negotiation_Response = record { flags: uint8; - length: uint16; # must be set to 8 + length: uint16 &enforce(length==8); # must be set to 8 selected_protocol: uint32; } &let { # Seems to be SSL encrypted (maybe CredSSP also?) @@ -310,10 +310,12 @@ type Server_Network_Data = record { channel_count: uint16; } &byteorder=littleendian; +# See MS-RDPBCGR Section 2.2.1.4.3 for reasoning for the &enforce value on +# the server_random_length field. type Server_Security_Data = record { encryption_method: uint32; encryption_level: uint32; - server_random_length: uint32; + server_random_length: uint32 &enforce((encryption_level == 0 && encryption_method == 0 && server_random_length == 0) || (server_random_length == 0x20)); server_cert_length: uint32; server_random: bytestring &length=server_random_length; server_certificate: Server_Certificate &length=server_cert_length; diff --git a/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-invalid-length/analyzer.log b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-invalid-length/analyzer.log new file mode 100644 index 0000000000..8726e1c31c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.rdp.rdp-invalid-length/analyzer.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path analyzer +#open XXXX-XX-XX-XX-XX-XX +#fields ts cause analyzer_kind analyzer_name uid fuid id.orig_h id.orig_p id.resp_h id.resp_p failure_reason failure_data +#types time string string string string string addr port addr port string string +XXXXXXXXXX.XXXXXX violation protocol RDP CHhAvVGS1DHFjwGM9 - 10.0.0.1 45257 10.0.0.2 3389 Binpac exception: binpac exception: &enforce violation : RDP_Negotiation_Response:length - +XXXXXXXXXX.XXXXXX violation protocol RDP CHhAvVGS1DHFjwGM9 - 10.0.0.1 45257 10.0.0.2 3389 Binpac exception: binpac exception: invalid index for case: Connect_Confirm_Record: 49 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/rdp/rdp-invalid-length.pcap b/testing/btest/Traces/rdp/rdp-invalid-length.pcap new file mode 100644 index 0000000000..3698412438 Binary files /dev/null and b/testing/btest/Traces/rdp/rdp-invalid-length.pcap differ diff --git a/testing/btest/scripts/base/protocols/rdp/rdp-invalid-length.zeek b/testing/btest/scripts/base/protocols/rdp/rdp-invalid-length.zeek new file mode 100644 index 0000000000..84f6dfe33d --- /dev/null +++ b/testing/btest/scripts/base/protocols/rdp/rdp-invalid-length.zeek @@ -0,0 +1,8 @@ +# Tests a pcap that has a known-invalid length in a RDP_Negotiation_Response +# header, ensuring that it throws a binpac exception and reports a notice to +# analyzer.log. The pcap used is a snippet of a pcap from OSS-Fuzz #57109. + +# @TEST-EXEC: zeek -C -b -r $TRACES/rdp/rdp-invalid-length.pcap %INPUT +# @TEST-EXEC: btest-diff analyzer.log + +@load base/protocols/rdp \ No newline at end of file