mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +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
|
@ -19,6 +19,27 @@ export {
|
||||||
[25282] = "RDP 8.0 (Mac)"
|
[25282] = "RDP 8.0 (Mac)"
|
||||||
} &default = function(n: count): string { return fmt("client_build-%d", n); };
|
} &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 = {
|
const encryption_methods = {
|
||||||
[0] = "None",
|
[0] = "None",
|
||||||
[1] = "40bit",
|
[1] = "40bit",
|
||||||
|
|
|
@ -15,6 +15,11 @@ export {
|
||||||
## Cookie value used by the client machine.
|
## Cookie value used by the client machine.
|
||||||
## This is typically a username.
|
## This is typically a username.
|
||||||
cookie: string &log &optional;
|
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 (language) of the client machine.
|
||||||
keyboard_layout: string &log &optional;
|
keyboard_layout: string &log &optional;
|
||||||
## RDP client version used by the client machine.
|
## RDP client version used by the client machine.
|
||||||
|
@ -30,8 +35,19 @@ export {
|
||||||
## The color depth requested by the client in
|
## The color depth requested by the client in
|
||||||
## the high_color_depth field.
|
## the high_color_depth field.
|
||||||
requested_color_depth: string &log &optional;
|
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 of the connection.
|
||||||
encryption_level: string &log &optional;
|
encryption_level: string &log &optional;
|
||||||
## Encryption method of the connection.
|
## 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);
|
set_session(c);
|
||||||
|
|
||||||
c$rdp$cookie = cookie;
|
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
|
event rdp_client_core_data(c: connection, data: RDP::ClientCoreData) &priority=5
|
||||||
{
|
{
|
||||||
set_session(c);
|
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_width = data$desktop_width;
|
||||||
c$rdp$desktop_height = data$desktop_height;
|
c$rdp$desktop_height = data$desktop_height;
|
||||||
if ( data?$ec_flags && data$ec_flags$want_32bpp_session )
|
if ( data?$ec_flags && data$ec_flags$want_32bpp_session )
|
||||||
c$rdp$requested_color_depth = "32-bit";
|
c$rdp$requested_color_depth = "32bit";
|
||||||
else
|
else
|
||||||
c$rdp$requested_color_depth = RDP::high_color_depths[data$high_color_depth];
|
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);
|
set_session(c);
|
||||||
|
|
||||||
|
@ -170,14 +200,32 @@ event rdp_server_security(c: connection, encryption_method: count, encryption_le
|
||||||
c$rdp$encryption_level = RDP::encryption_levels[encryption_level];
|
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
|
||||||
{
|
{
|
||||||
|
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_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_MD5);
|
||||||
Files::add_analyzer(f, Files::ANALYZER_SHA1);
|
Files::add_analyzer(f, Files::ANALYZER_SHA1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5
|
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,8 @@ void RDP_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
// we'll just move this over to the PIA analyzer.
|
// we'll just move this over to the PIA analyzer.
|
||||||
// Like the comment below says, this is probably the wrong
|
// Like the comment below says, this is probably the wrong
|
||||||
// way to handle this.
|
// way to handle this.
|
||||||
|
if ( interp->is_encrypted() )
|
||||||
|
{
|
||||||
if ( len > 0 && data[0] >= 0x14 && data[0] <= 0x17 )
|
if ( len > 0 && data[0] >= 0x14 && data[0] <= 0x17 )
|
||||||
{
|
{
|
||||||
if ( ! pia )
|
if ( ! pia )
|
||||||
|
@ -65,20 +67,10 @@ void RDP_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pia )
|
if ( pia )
|
||||||
{
|
|
||||||
ForwardStream(len, data, orig);
|
ForwardStream(len, data, orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( pia )
|
else // if not encrypted
|
||||||
{
|
|
||||||
// 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
|
|
||||||
{
|
{
|
||||||
try
|
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.
|
## c: The connection record for the underlying transport-layer session/flow.
|
||||||
##
|
##
|
||||||
## cookie: The cookie included in the request.
|
## 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.
|
## c: The connection record for the underlying transport-layer session/flow.
|
||||||
##
|
##
|
||||||
## data: The data contained in the client core data structure.
|
## data: The data contained in the client core data structure.
|
||||||
event rdp_client_core_data%(c: connection, data: RDP::ClientCoreData%);
|
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.
|
## c: The connection record for the underlying transport-layer session/flow.
|
||||||
##
|
##
|
||||||
## result: The 8-bit integer representing the GCC Conference Create Response result.
|
## 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.
|
## 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.
|
## 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%);
|
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
|
function utf16_to_utf8_val(utf16: bytestring): StringVal
|
||||||
%{
|
%{
|
||||||
size_t utf8size = 3 * utf16.length() + 1;
|
std::string resultstring;
|
||||||
char* utf8stringnative = new char[utf8size];
|
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* sourcestart = reinterpret_cast<const UTF16*>(utf16.begin());
|
||||||
const UTF16* sourceend = sourcestart + utf16.length();
|
const UTF16* sourceend = sourcestart + widesize;
|
||||||
UTF8* targetstart = reinterpret_cast<UTF8*>(utf8stringnative);
|
UTF8* targetstart = reinterpret_cast<UTF8*>(&resultstring[0]);
|
||||||
UTF8* targetend = targetstart + utf8size;
|
UTF8* targetend = targetstart + utf8size;
|
||||||
|
|
||||||
ConversionResult res = ConvertUTF16toUTF8(&sourcestart,
|
ConversionResult res = ConvertUTF16toUTF8(&sourcestart,
|
||||||
|
@ -20,33 +23,63 @@ refine flow RDP_Flow += {
|
||||||
&targetstart,
|
&targetstart,
|
||||||
targetend,
|
targetend,
|
||||||
strictConversion);
|
strictConversion);
|
||||||
*targetstart = 0;
|
|
||||||
|
|
||||||
if ( res != conversionOK )
|
if ( res != conversionOK )
|
||||||
{
|
{
|
||||||
connection()->bro_analyzer()->Weird("Failed UTF-16 to UTF-8 conversion");
|
connection()->bro_analyzer()->Weird("Failed UTF-16 to UTF-8 conversion");
|
||||||
return new StringVal(utf16.length(), (const char *) utf16.begin());
|
return new StringVal(utf16.length(), (const char *) utf16.begin());
|
||||||
}
|
}
|
||||||
|
*targetstart = 0;
|
||||||
|
|
||||||
// We're relying on no nulls being in the string.
|
// 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();
|
if ( rdp_connect_request )
|
||||||
BifEvent::generate_rdp_client_request(connection()->bro_analyzer(),
|
{
|
||||||
|
BifEvent::generate_rdp_connect_request(connection()->bro_analyzer(),
|
||||||
connection()->bro_analyzer()->Conn(),
|
connection()->bro_analyzer()->Conn(),
|
||||||
bytestring_to_val(${client_request.cookie_value}));
|
bytestring_to_val(${cr.cookie_value}));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
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();
|
connection()->bro_analyzer()->ProtocolConfirmation();
|
||||||
BifEvent::generate_rdp_result(connection()->bro_analyzer(),
|
|
||||||
|
if ( rdp_gcc_server_create_response )
|
||||||
|
BifEvent::generate_rdp_gcc_server_create_response(connection()->bro_analyzer(),
|
||||||
connection()->bro_analyzer()->Conn(),
|
connection()->bro_analyzer()->Conn(),
|
||||||
${gcc_response.result});
|
${gcc_response.result});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -55,6 +88,8 @@ refine flow RDP_Flow += {
|
||||||
%{
|
%{
|
||||||
connection()->bro_analyzer()->ProtocolConfirmation();
|
connection()->bro_analyzer()->ProtocolConfirmation();
|
||||||
|
|
||||||
|
if ( rdp_client_core_data )
|
||||||
|
{
|
||||||
RecordVal* ec_flags = new RecordVal(BifType::Record::RDP::EarlyCapabilityFlags);
|
RecordVal* ec_flags = new RecordVal(BifType::Record::RDP::EarlyCapabilityFlags);
|
||||||
ec_flags->Assign(0, new Val(${ccore.SUPPORT_ERRINFO_PDU}, TYPE_BOOL));
|
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(1, new Val(${ccore.WANT_32BPP_SESSION}, TYPE_BOOL));
|
||||||
|
@ -91,20 +126,38 @@ refine flow RDP_Flow += {
|
||||||
BifEvent::generate_rdp_client_core_data(connection()->bro_analyzer(),
|
BifEvent::generate_rdp_client_core_data(connection()->bro_analyzer(),
|
||||||
connection()->bro_analyzer()->Conn(),
|
connection()->bro_analyzer()->Conn(),
|
||||||
ccd);
|
ccd);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function proc_rdp_server_security(ssd: Server_Security_Data): bool
|
function proc_rdp_server_security(ssd: Server_Security_Data): bool
|
||||||
%{
|
%{
|
||||||
connection()->bro_analyzer()->ProtocolConfirmation();
|
connection()->bro_analyzer()->ProtocolConfirmation();
|
||||||
|
|
||||||
|
if ( rdp_server_security )
|
||||||
BifEvent::generate_rdp_server_security(connection()->bro_analyzer(),
|
BifEvent::generate_rdp_server_security(connection()->bro_analyzer(),
|
||||||
connection()->bro_analyzer()->Conn(),
|
connection()->bro_analyzer()->Conn(),
|
||||||
${ssd.encryption_method},
|
${ssd.encryption_method},
|
||||||
${ssd.encryption_level});
|
${ssd.encryption_level});
|
||||||
|
|
||||||
return true;
|
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};
|
const bytestring& cert = ${x509.cert};
|
||||||
|
|
||||||
|
@ -126,8 +179,16 @@ refine flow RDP_Flow += {
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
|
||||||
refine typeattr Client_Request += &let {
|
refine typeattr Connect_Request += &let {
|
||||||
proc: bool = $context.flow.proc_rdp_client_request(this);
|
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 {
|
refine typeattr Client_Core_Data += &let {
|
||||||
|
@ -135,13 +196,17 @@ refine typeattr Client_Core_Data += &let {
|
||||||
};
|
};
|
||||||
|
|
||||||
refine typeattr GCC_Server_Create_Response += &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 {
|
refine typeattr Server_Security_Data += &let {
|
||||||
proc: bool = $context.flow.proc_rdp_server_security(this);
|
proc: bool = $context.flow.proc_rdp_server_security(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
refine typeattr X509 += &let {
|
refine typeattr Server_Certificate += &let {
|
||||||
proc: bool = $context.flow.proc_x509_cert(this);
|
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,11 +14,9 @@ type TPKT(is_orig: bool) = record {
|
||||||
type COTP = record {
|
type COTP = record {
|
||||||
cotp_len: uint8;
|
cotp_len: uint8;
|
||||||
pdu: uint8;
|
pdu: uint8;
|
||||||
# Probably should do something with this eventually.
|
|
||||||
#cotp_crap: padding[cotp_len-2];
|
|
||||||
switch: case pdu of {
|
switch: case pdu of {
|
||||||
#0xd0 -> cConfirm: Connect_Confirm;
|
0xd0 -> connect_confirm: Connect_Confirm;
|
||||||
0xe0 -> c_request: Client_Request;
|
0xe0 -> client_request: Connect_Request;
|
||||||
0xf0 -> data: DT_Data;
|
0xf0 -> data: DT_Data;
|
||||||
|
|
||||||
# In case we don't support the PDU we just
|
# In case we don't support the PDU we just
|
||||||
|
@ -75,14 +73,59 @@ type Data_Block = record {
|
||||||
# Client X.224
|
# Client X.224
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
type Client_Request = record {
|
type Connect_Request = record {
|
||||||
destination_reference: uint16;
|
destination_reference: uint16;
|
||||||
source_reference: uint16;
|
source_reference: uint16;
|
||||||
flow_control: uint8;
|
flow_control: uint8;
|
||||||
cookie_mstshash: RE/Cookie: mstshash\=/;
|
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
|
# Client MCS
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -93,11 +136,11 @@ type Client_Header = record {
|
||||||
called_domain_selector: ASN1OctetString;
|
called_domain_selector: ASN1OctetString;
|
||||||
upward_flag: ASN1Boolean;
|
upward_flag: ASN1Boolean;
|
||||||
target_parameters: ASN1SequenceMeta;
|
target_parameters: ASN1SequenceMeta;
|
||||||
targ_parameters_pad: padding[target_parameters.encoding.length];
|
targ_parameters_pad: bytestring &length=target_parameters.encoding.length &transient;
|
||||||
minimum_parameters: ASN1SequenceMeta;
|
minimum_parameters: ASN1SequenceMeta;
|
||||||
min_parameters_pad: padding[minimum_parameters.encoding.length];
|
min_parameters_pad: bytestring &length=minimum_parameters.encoding.length &transient;
|
||||||
maximum_parameters: ASN1SequenceMeta;
|
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
|
# BER encoded OctetString and long variant, can be safely skipped for now
|
||||||
user_data_length: uint32;
|
user_data_length: uint32;
|
||||||
gcc_connection_data: GCC_Client_Connection_Data;
|
gcc_connection_data: GCC_Client_Connection_Data;
|
||||||
|
@ -174,7 +217,7 @@ type Server_Header = record {
|
||||||
connect_response_called_id: ASN1Integer;
|
connect_response_called_id: ASN1Integer;
|
||||||
connect_response_domain_parameters: ASN1SequenceMeta;
|
connect_response_domain_parameters: ASN1SequenceMeta;
|
||||||
# Skipping over domain parameters for now.
|
# 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.
|
# I think this is another definite length encoded value.
|
||||||
user_data_length: uint32;
|
user_data_length: uint32;
|
||||||
gcc_connection_data: GCC_Server_Connection_Data;
|
gcc_connection_data: GCC_Server_Connection_Data;
|
||||||
|
@ -219,20 +262,24 @@ type Server_Security_Data = record {
|
||||||
server_cert_length: uint32;
|
server_cert_length: uint32;
|
||||||
server_random: bytestring &length=server_random_length;
|
server_random: bytestring &length=server_random_length;
|
||||||
server_certificate: Server_Certificate &length=server_cert_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;
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
type Server_Certificate = record {
|
type Server_Certificate = record {
|
||||||
version: uint32;
|
version: uint32;
|
||||||
switch: case cert_type of {
|
switch: case cert_type of {
|
||||||
0x01 -> proprietary: Server_Proprietary;
|
0x01 -> proprietary: Server_Proprietary_Cert(this);
|
||||||
0x02 -> x509: X509;
|
0x02 -> x509: X509;
|
||||||
};
|
};
|
||||||
} &let {
|
} &let {
|
||||||
cert_type: uint32 = version & 0x7FFFFFFF;
|
cert_type: uint32 = version & 0x7FFFFFFF;
|
||||||
permanent_issue: bool = (version & 0x80000000) == 0;
|
permanently_issued: bool = (version & 0x80000000) == 0;
|
||||||
} &byteorder=littleendian;
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
type Server_Proprietary = record {
|
type Server_Proprietary_Cert(cert: Server_Certificate) = record {
|
||||||
signature_algorithm: uint32;
|
signature_algorithm: uint32;
|
||||||
key_algorithm: uint32;
|
key_algorithm: uint32;
|
||||||
public_key_blob_type: uint16;
|
public_key_blob_type: uint16;
|
||||||
|
@ -252,8 +299,13 @@ type Public_Key_Blob = record {
|
||||||
} &byteorder=littleendian;
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
type X509 = record {
|
type X509 = record {
|
||||||
pad1: padding[8];
|
num_of_certs: uint32;
|
||||||
cert: bytestring &restofdata;
|
certs: X509_Cert_Data[num_of_certs];
|
||||||
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
|
type X509_Cert_Data = record {
|
||||||
|
cert_len: uint32;
|
||||||
|
cert: bytestring &length=cert_len;
|
||||||
} &byteorder=littleendian;
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -314,3 +366,28 @@ function binary_to_int64(bs: bytestring): int64
|
||||||
return rval;
|
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_;
|
||||||
|
%}
|
||||||
|
};
|
|
@ -3,9 +3,9 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path rdp
|
#path rdp
|
||||||
#open 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 keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth result encryption_level encryption_method
|
#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 count count string string string string
|
#types time string addr port addr port string string string string string string count count string string count bool 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 SSL_NOT_ALLOWED_BY_SERVER - - - - - - - - 0 - - - -
|
||||||
1193369795.014346 CXWv6p3arKYeMETxOg 172.21.128.16 1311 10.226.24.52 3389 FTBCO\A70 - - - - - - - - - -
|
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-04-17-59-16
|
#close 2015-03-05-06-05-01
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path rdp
|
#path rdp
|
||||||
#open 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 keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth result encryption_level encryption_method
|
#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 count count string string string string
|
#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 - - - - - - - - - -
|
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 - - - - - - - - - -
|
1297551078.958821 CjhGID4nQcgTWjvg4c 192.168.1.200 49207 192.168.1.150 3389 AWAKECODI - - - - - - - - - 0 - HYBRID - -
|
||||||
#close 2015-03-04-17-53-51
|
#close 2015-03-05-05-25-45
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path rdp
|
#path rdp
|
||||||
#open 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 keyboard_layout client_build client_name client_dig_product_id desktop_width desktop_height requested_color_depth result encryption_level encryption_method
|
#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 count count string string string string
|
#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 English - United States RDP 8.1 JOHN-PC-LAPTOP 3c571ed0-3415-474b-ae94-74e151b 1920 1080 16bit Success Client compatible 128bit
|
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-04-17-56-41
|
#close 2015-03-05-05-26-13
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path x509
|
#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
|
#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
|
#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
|
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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue