Removed debug code for SSL

This commit is contained in:
Josh Liburdi 2015-02-15 09:24:28 -08:00
parent c268898e04
commit fd655aa85d
5 changed files with 80 additions and 240 deletions

View file

@ -14,7 +14,7 @@ export {
id: conn_id &log; id: conn_id &log;
## 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;
## 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.
@ -23,11 +23,8 @@ export {
client_hostname: string &log &optional; client_hostname: string &log &optional;
## Product ID of the client machine. ## Product ID of the client machine.
client_product_id: string &log &optional; client_product_id: string &log &optional;
## Name of the server. ## GCC result for the connection. This value is extracted from the payload for native encryption.
server_name: vector of string &log &optional; result: string &log &optional;
## Authentication result for the connection. This value is extracted from the payload for native authentication.
## TODO: Perform heuristic authentication determination for NLA.
authentication_result: 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.
@ -36,12 +33,6 @@ export {
done: bool &default=F; done: bool &default=F;
}; };
## Variable to track if NTLM authentication is used.
global ntlm = F;
## Size in bytes of data sent by the server at which the RDP connection is presumed to be successful (NTLM authentication only).
const authentication_data_size = 1000 &redef;
## Event that can be handled to access the rdp record as it is sent on ## Event that can be handled to access the rdp record as it is sent on
## to the loggin framework. ## to the loggin framework.
global log_rdp: event(rec: Info); global log_rdp: event(rec: Info);
@ -66,17 +57,6 @@ function rdp_done(c: connection, done: bool)
{ {
c$rdp$done = T; c$rdp$done = T;
# Not currently implemented
# if ( ntlm && use_conn_size_analyzer )
# {
# if ( c$resp$size > authentication_data_size )
# c$rdp$authentication_result = "Success (H)";
# else c$rdp$authentication_result = "Undetermined";
# }
if ( c$rdp?$authentication_result && ( ! c$rdp?$encryption_method || ! c$rdp?$encryption_level ) )
Reporter::error(fmt("Error parsing RDP security data in connection %s",c$uid));
Log::write(RDP::LOG, c$rdp); Log::write(RDP::LOG, c$rdp);
skip_further_processing(c$id); skip_further_processing(c$id);
set_record_packets(c$id, F); set_record_packets(c$id, F);
@ -110,7 +90,7 @@ event rdp_tracker(c: connection)
} }
} }
# schedule the event to run again if necessary # Schedule the event to run again if necessary
schedule +5secs { rdp_tracker(c) }; schedule +5secs { rdp_tracker(c) };
} }
@ -130,7 +110,7 @@ event connection_state_remove(c: connection) &priority=-5
rdp_done(c,T); rdp_done(c,T);
} }
event rdp_native_client_request(c: connection, cookie: string) &priority=5 event rdp_client_request(c: connection, cookie: string) &priority=5
{ {
if ( "Cookie" in clean(cookie) ) if ( "Cookie" in clean(cookie) )
{ {
@ -142,7 +122,7 @@ event rdp_native_client_request(c: connection, cookie: string) &priority=5
} }
} }
event rdp_native_client_info(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string) &priority=5 event rdp_client_data(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string) &priority=5
{ {
set_session(c); set_session(c);
c$rdp$keyboard_layout = languages[keyboard_layout]; c$rdp$keyboard_layout = languages[keyboard_layout];
@ -153,15 +133,15 @@ event rdp_native_client_info(c: connection, keyboard_layout: count, build: count
schedule +5secs { rdp_tracker(c) }; schedule +5secs { rdp_tracker(c) };
} }
event rdp_native_authentication(c: connection, result: count) &priority=5 event rdp_result(c: connection, result: count) &priority=5
{ {
set_session(c); set_session(c);
c$rdp$authentication_result = results[result]; c$rdp$result = results[result];
schedule +5secs { rdp_tracker(c) }; schedule +5secs { rdp_tracker(c) };
} }
event rdp_native_server_security(c: connection, encryption_method: count, encryption_level: count, random: string, certificate: string) &priority=5 event rdp_server_security(c: connection, encryption_method: count, encryption_level: count) &priority=5
{ {
set_session(c); set_session(c);
c$rdp$encryption_method = encryption_methods[encryption_method]; c$rdp$encryption_method = encryption_methods[encryption_method];
@ -169,32 +149,3 @@ event rdp_native_server_security(c: connection, encryption_method: count, encryp
schedule +5secs { rdp_tracker(c) }; schedule +5secs { rdp_tracker(c) };
} }
event rdp_ntlm_client_request(c: connection, server: string) &priority=5
{
set_session(c);
ntlm = T;
if ( ! c$rdp?$server_name )
c$rdp$server_name = vector();
c$rdp$server_name[|c$rdp$server_name|] = server;
schedule +5secs { rdp_tracker(c) };
}
event rdp_ntlm_server_response(c: connection, server: string) &priority=5
{
set_session(c);
ntlm = T;
if ( ! c$rdp?$server_name )
c$rdp$server_name = vector();
c$rdp$server_name[|c$rdp$server_name|] = server;
schedule +5secs { rdp_tracker(c) };
}
event rdp_debug(c: connection, remainder: string)
{
Reporter::error(fmt("Debug RDP data generated in connection %s: %s",c$uid,remainder));
}

View file

@ -1,9 +1,6 @@
#include "RDP.h" #include "RDP.h"
#include "analyzer/protocol/tcp/TCP_Reassembler.h" #include "analyzer/protocol/tcp/TCP_Reassembler.h"
#include "Reporter.h" #include "Reporter.h"
#include "events.bif.h" #include "events.bif.h"
using namespace analyzer::rdp; using namespace analyzer::rdp;

View file

@ -1,23 +1,9 @@
## Generated for client-to-server RDP requests when NTLM authentication is used.
##
## c: The connection record for the underlying transport-layer session/flow.
##
## server: The RDP server name requested by the client.
event rdp_ntlm_client_request%(c: connection, server: string%);
## Generated for server-to-client RDP responses when NTLM authentication is used.
##
## c: The connection record for the underlying transport-layer session/flow.
##
## server: The RDP server name responsed by the server.
event rdp_ntlm_server_response%(c: connection, server: string%);
## Generated for X.224 client requests when native RDP encryption is used. ## Generated for X.224 client requests when native RDP encryption is used.
## ##
## 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_native_client_request%(c: connection, cookie: string%); event rdp_client_request%(c: connection, cookie: string%);
## Generated for MCS client requests when native RDP encryption is used. ## Generated for MCS client requests when native RDP encryption is used.
## ##
@ -30,14 +16,14 @@ event rdp_native_client_request%(c: connection, cookie: string%);
## hostname: The hostname of the client machine (optional). ## hostname: The hostname of the client machine (optional).
## ##
## product_id: The product ID of the client machine (optional). ## product_id: The product ID of the client machine (optional).
event rdp_native_client_info%(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string%); event rdp_client_data%(c: connection, keyboard_layout: count, build: count, hostname: string, product_id: string%);
## Generated for MCS server responses when native RDP encryption is used. ## Generated for MCS server responses when native RDP encryption is used.
## ##
## 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_native_authentication%(c: connection, result: count%); event rdp_result%(c: connection, result: count%);
## Generated for MCS server responses when native RDP encryption is used. ## Generated for MCS server responses when native RDP encryption is used.
## ##
@ -46,15 +32,4 @@ event rdp_native_authentication%(c: connection, result: count%);
## encryption_method: The 32-bit integer representing the encryption method used in the connection. ## encryption_method: The 32-bit integer representing the encryption method used in the connection.
## ##
## 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%);
## random: The random value used to derive session keys (optional).
##
## certificate: The certificate containing the server's public key information.
event rdp_native_server_security%(c: connection, encryption_method: count, encryption_level: count, random: string, certificate: string%);
## Generated for unknown elements in RDP connections. Used for debugging and development purposes only.
##
## c: The connection record for the underlying transport-layer session/flow.
##
## remainder: The data to be debugged.
event rdp_debug%(c: connection, remainder: string%);

View file

@ -1,101 +1,59 @@
refine flow RDP_Flow += { refine flow RDP_Flow += {
function proc_rdp_debug(debug: Debug): bool function proc_rdp_client_request(client_request: ClientRequest): bool
%{ %{
BifEvent::generate_rdp_debug(connection()->bro_analyzer(), BifEvent::generate_rdp_client_request(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
bytestring_to_val(${debug.remainder})); bytestring_to_val(${client_request.cookie}));
return true; return true;
%} %}
function proc_rdp_ntlm_server_response(ntlm_server: NTLMServerResponse): bool function proc_rdp_result(gcc_response: GCC_Server_CreateResponse): bool
%{ %{
BifEvent::generate_rdp_ntlm_server_response(connection()->bro_analyzer(), BifEvent::generate_rdp_result(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
bytestring_to_val(${ntlm_server.server_name})); ${gcc_response.result});
return true;
%}
function proc_rdp_ntlm_client_request(ntlm_client: NTLMClientRequest): bool
%{
BifEvent::generate_rdp_ntlm_client_request(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
bytestring_to_val(${ntlm_client.server_name}));
return true;
%}
function proc_rdp_native_client_request(client_request: ClientRequest): bool
%{
BifEvent::generate_rdp_native_client_request(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
bytestring_to_val(${client_request.cookie}));
return true;
%}
function proc_rdp_native_authentication(gcc_response: GCC_Server_CreateResponse): bool
%{
BifEvent::generate_rdp_native_authentication(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
${gcc_response.result});
return true; return true;
%} %}
function proc_rdp_native_client_info(ccore: ClientCore): bool function proc_rdp_client_data(ccore: ClientCore): bool
%{ %{
BifEvent::generate_rdp_native_client_info(connection()->bro_analyzer(), BifEvent::generate_rdp_client_data(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
${ccore.keyboard_layout}, ${ccore.keyboard_layout},
${ccore.client_build}, ${ccore.client_build},
bytestring_to_val(${ccore.client_name}), bytestring_to_val(${ccore.client_name}),
bytestring_to_val(${ccore.dig_product_id})); bytestring_to_val(${ccore.dig_product_id}));
return true; return true;
%} %}
function proc_rdp_native_server_security(ssd: ServerSecurityData): bool function proc_rdp_server_security(ssd: ServerSecurityData): bool
%{ %{
BifEvent::generate_rdp_native_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});
bytestring_to_val(${ssd.server_random}),
bytestring_to_val(${ssd.server_certificate}));
return true; return true;
%} %}
}; };
refine typeattr Debug += &let {
proc: bool = $context.flow.proc_rdp_debug(this);
};
refine typeattr NTLMServerResponse += &let {
proc: bool = $context.flow.proc_rdp_ntlm_server_response(this);
};
refine typeattr NTLMClientRequest += &let {
proc: bool = $context.flow.proc_rdp_ntlm_client_request(this);
};
refine typeattr ClientRequest += &let { refine typeattr ClientRequest += &let {
proc: bool = $context.flow.proc_rdp_native_client_request(this); proc: bool = $context.flow.proc_rdp_client_request(this);
}; };
refine typeattr ClientCore += &let { refine typeattr ClientCore += &let {
proc: bool = $context.flow.proc_rdp_native_client_info(this); proc: bool = $context.flow.proc_rdp_client_data(this);
}; };
refine typeattr GCC_Server_CreateResponse += &let { refine typeattr GCC_Server_CreateResponse += &let {
proc: bool = $context.flow.proc_rdp_native_authentication(this); proc: bool = $context.flow.proc_rdp_result(this);
}; };
refine typeattr ServerSecurityData += &let { refine typeattr ServerSecurityData += &let {
proc: bool = $context.flow.proc_rdp_native_server_security(this); proc: bool = $context.flow.proc_rdp_server_security(this);
}; };

View file

@ -1,8 +1,8 @@
type RDP_PDU(is_orig: bool) = record { type RDP_PDU(is_orig: bool) = record {
type: uint16; type: uint8;
switch: case type of { switch: case type of {
0x1603 -> ntlm_authentication: NTLMAuthentication; # NTLM authentication appears to be flagged by this 16-bit integer 0x16 -> ssl_encryption: bytestring &restofdata &transient; # send to SSL analyzer in the future
default -> native_encryption: NativeEncryption; # assume native encryption, this should be the value of the TPKT version default -> native_encryption: NativeEncryption; # TPKT version
}; };
} &byteorder=bigendian; } &byteorder=bigendian;
@ -11,8 +11,9 @@ type RDP_PDU(is_orig: bool) = record {
###################################################################### ######################################################################
type NativeEncryption = record { type NativeEncryption = record {
pad: padding[2]; # remaining TPKT values tpkt_reserved: uint8;
cotp: COTP; tpkt_length: uint16;
cotp: COTP;
}; };
type COTP = record { type COTP = record {
@ -20,12 +21,12 @@ type COTP = record {
pdu: uint8; pdu: uint8;
switch: case pdu of { switch: case pdu of {
0xe0 -> cRequest: ClientRequest; 0xe0 -> cRequest: ClientRequest;
0xf0 -> hdr: Header; 0xf0 -> hdr: COTPHeader;
default -> data: bytestring &restofdata &transient; default -> data: bytestring &restofdata &transient;
}; };
} &byteorder=littleendian; } &byteorder=littleendian;
type Header = record { type COTPHeader = record {
tpdu_number: uint8; tpdu_number: uint8;
application_defined_type: uint8; # this begins a BER encoded multiple octet variant, but can be safely skipped application_defined_type: uint8; # this begins a BER encoded multiple octet variant, but can be safely skipped
application_type: uint8; # this is value for the BER encoded octet variant above application_type: uint8; # this is value for the BER encoded octet variant above
@ -36,6 +37,11 @@ type Header = record {
}; };
} &byteorder=littleendian; } &byteorder=littleendian;
type DataHdr = record {
type: uint16;
length: uint16;
} &byteorder=littleendian;
###################################################################### ######################################################################
# Client X.224 # Client X.224
###################################################################### ######################################################################
@ -130,7 +136,7 @@ type ServerHeader = record {
network_header: DataHdr; network_header: DataHdr;
net_data: padding[network_header.length - 4]; # skip this data net_data: padding[network_header.length - 4]; # skip this data
security_header: DataHdr; security_header: DataHdr;
security_data: ServerSecurityData; # there is some issue / bug where the length reported by the security header overruns the end of the packet security_data: ServerSecurityData;
}; };
type GCC_Server_ConnectionData = record { type GCC_Server_ConnectionData = record {
@ -152,11 +158,6 @@ type GCC_Server_CreateResponse = record {
user_data_value_length: uint16; user_data_value_length: uint16;
}; };
type DataHdr = record {
type: uint16;
length: uint16;
} &byteorder=littleendian;
type ServerCoreData = record { type ServerCoreData = record {
version_major: uint16; version_major: uint16;
version_minor: uint16; version_minor: uint16;
@ -174,83 +175,40 @@ type ServerSecurityData = record {
server_random_length: uint32 &byteorder=littleendian; server_random_length: uint32 &byteorder=littleendian;
server_cert_length: uint32 &byteorder=littleendian; server_cert_length: uint32 &byteorder=littleendian;
server_random: bytestring &length=server_random_length; server_random: bytestring &length=server_random_length;
server_certificate: bytestring &length=server_cert_length-8; # arbitrarily cutting off 8 chars so the certificate doesn't overrun the end of the packet server_certificate: ServerCertificate;
}; };
###################################################################### type ServerCertificate = record {
# NTLM Authentication cert_type: uint8;
###################################################################### switch: case cert_type of {
0x01 -> proprietary: ServerProprietary;
type NTLMAuthentication = record { 0x02 -> ssl: SSL;
type: uint16;
switch: case type of { # there may be further type bytes that need to be added to this switch
0x0100 -> client_request: NTLMClientRequest;
0x0300 -> client_request2: NTLMClientRequest;
0x0103 -> server_response: NTLMServerResponse;
0x0104 -> server_response2: NTLMServerResponse;
default -> data: bytestring &restofdata &transient;
}; };
} &byteorder=littleendian;
type ServerProprietary = record {
cert_type: uint8[3]; # remainder of cert_type value
signature_algorithm: uint32;
key_algorithm: uint32;
public_key_blob_type: uint16;
public_key_blob_length: uint16;
public_key_blob: PublicKeyBlob &length=public_key_blob_length;
signature_blob_type: uint16;
signature_blob_length: uint16;
signature_blob: bytestring &length=signature_blob_length;
}; };
###################################################################### type PublicKeyBlob = record {
# NTLM Client magic: bytestring &length=4;
###################################################################### key_length: uint32;
bit_length: uint32;
type NTLMClientRequest = record { public_exponent: uint32;
payload_length: uint8; # total payload length modulus: bytestring &length=key_length;
pad1: padding[3]; # arbitrary 3 bytes
remaining_length1: uint8; # remaining length of the payload
pad2: padding[36]; # arbitrary 36 bytes
unknown_length: uint8; # an unknown length value
unknown_value1: padding[unknown_length]; # arbitrary padding for the length value above
pad3: padding[3]; # arbitrary 3 bytes
remainder_length2: uint8; # remaining length of the payload
unknown: uint8; # this unknown field affects the length between here and the beginning of the requested server name
switch: case unknown of {
0x00 -> case1: uint8[7]; # jump 7 bytes
0xff -> case2: uint8[12]; # jump 12 bytes
default -> case3: Debug; # debug if an unknown value is seen
};
server_length: uint8;
server_name: bytestring &length=server_length;
data: bytestring &restofdata &transient;
}; };
###################################################################### type SSL = record {
# NTLM Server pad1: padding[11];
###################################################################### x509_cert: bytestring &restofdata &transient; # send to x509 analyzer
type NTLMServerResponse = record {
unknown_value1: uint8; # 1 variable byte
unknown_value2: uint8[3]; # 3 bytes that may be static
unknown_value3: uint8; # 1 variable byte
unknown_value4: uint8[2]; # 2 bytes that may be static
unknown_length1: uint8; # an unknown length value
pad1: padding[unknown_length1]; # arbitrary padding for the length value above
unknown_value5: uint8[3]; # 3 bytes that may be static
unknown_value6: uint8; # 1 variable byte
unknown_value7: uint8[3]; # 3 bytes that may be static
unknown_value8: uint8; # 1 variable byte
unknown_value9: uint8[7]; # 7 bytes that may be static
unknown_value10: uint8[16]; # 16 bytes that may be static
unknown_value11: uint8[16]; # 16 bytes that may be static
unknown_value12: uint8; # 1 variable byte
unknown_value13: uint8; # 1 byte that may be static
unknown_value14: uint8; # 1 variable byte
unknown_value15: uint8; # 1 byte that may be static
unknown_value16: uint8; # 1 variable byte
unknown_value17: uint8[6]; # 6 bytes that may be static
server_length: uint8; # length of server name
server_name: bytestring &length=server_length; # server name
data: bytestring &restofdata &transient;
} &byteorder=bigendian;
######################################################################
# Debugging
######################################################################
type Debug = record {
remainder: bytestring &restofdata;
}; };
###################################################################### ######################################################################
@ -311,3 +269,4 @@ function binary_to_int64(bs: bytestring): int64
return rval; return rval;
%} %}