mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 21:18:20 +00:00
Another big RDP update.
- New fields for certificate type, number of certificates, if certificates are permanent on the server, and the selected security protocol. - Fixed some issues with X.509 certificate handling over RDP (the event handler wasn't sufficiently constrained). - Better detection of and transition into encrypted mode. No more binpac parse failures from the test traces anymore! - Some event name clean up and new events. - X.509 Certificate chains are now handled correctly (was only grabbing a single certificate).
This commit is contained in:
parent
0d04557ac4
commit
f45e057779
10 changed files with 364 additions and 135 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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%);
|
|
@ -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<const UTF16*>(utf16.begin());
|
||||
const UTF16* sourceend = sourcestart + utf16.length();
|
||||
UTF8* targetstart = reinterpret_cast<UTF8*>(utf8stringnative);
|
||||
const UTF16* sourceend = sourcestart + widesize;
|
||||
UTF8* targetstart = reinterpret_cast<UTF8*>(&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);
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
%}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue