diff --git a/CHANGES b/CHANGES index ba02da81ff..a6d443053d 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,9 @@ * Update intel framework plugin for ssl server_name extension API changes. (Bernhard Amann, Justin Azoff) + * Fix expression errors in SSL/x509 scripts when unparseable data + is in certificate chain. (Bernhard Amann) + 2.2-478 | 2014-05-19 15:31:33 -0500 * Change record ctors to only allow record-field-assignment diff --git a/scripts/base/protocols/ssl/files.bro b/scripts/base/protocols/ssl/files.bro index fbdd6e454e..65f43ed772 100644 --- a/scripts/base/protocols/ssl/files.bro +++ b/scripts/base/protocols/ssl/files.bro @@ -121,13 +121,15 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori event ssl_established(c: connection) &priority=6 { # update subject and issuer information - if ( c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 ) + if ( c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 && + c$ssl$cert_chain[0]?$x509 ) { c$ssl$subject = c$ssl$cert_chain[0]$x509$certificate$subject; c$ssl$issuer = c$ssl$cert_chain[0]$x509$certificate$issuer; } - if ( c$ssl?$client_cert_chain && |c$ssl$client_cert_chain| > 0 ) + if ( c$ssl?$client_cert_chain && |c$ssl$client_cert_chain| > 0 && + c$ssl$client_cert_chain[0]?$x509 ) { c$ssl$client_subject = c$ssl$client_cert_chain[0]$x509$certificate$subject; c$ssl$client_issuer = c$ssl$client_cert_chain[0]$x509$certificate$issuer; diff --git a/scripts/policy/protocols/ssl/expiring-certs.bro b/scripts/policy/protocols/ssl/expiring-certs.bro index 9c02c63784..9428923331 100644 --- a/scripts/policy/protocols/ssl/expiring-certs.bro +++ b/scripts/policy/protocols/ssl/expiring-certs.bro @@ -38,7 +38,8 @@ event ssl_established(c: connection) &priority=3 { # If there are no certificates or we are not interested in the server, just return. if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || - ! addr_matches_host(c$id$resp_h, notify_certs_expiration) ) + ! addr_matches_host(c$id$resp_h, notify_certs_expiration) || + ! c$ssl$cert_chain[0]?$x509 ) return; local fuid = c$ssl$cert_chain_fuids[0]; diff --git a/scripts/policy/protocols/ssl/extract-certs-pem.bro b/scripts/policy/protocols/ssl/extract-certs-pem.bro index 549c6943e6..18de3cbb7d 100644 --- a/scripts/policy/protocols/ssl/extract-certs-pem.bro +++ b/scripts/policy/protocols/ssl/extract-certs-pem.bro @@ -29,7 +29,8 @@ global extracted_certs: set[string] = set() &read_expire=1hr &redef; event ssl_established(c: connection) &priority=5 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$x509 ) return; if ( ! addr_matches_host(c$id$resp_h, extract_certs_pem) ) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index b1dfff867d..77a5e9832a 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -136,7 +136,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) ]); else if ( duration < 1min ) NOTICE([$note=SSL_Heartbeat_Attack, - $msg=fmt("Heartbeat within first minute. Possible attack or scan. Length: %d, is_orig: %d, time: %d", length, is_orig, duration), + $msg=fmt("Heartbeat within first minute. Possible attack or scan. Length: %d, is_orig: %d, time: %s", length, is_orig, duration), $conn=c, $n=length, $identifier=fmt("%s%s", c$uid, "early") @@ -225,6 +225,9 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, length: count) { + if ( !c?$ssl ) + return; + if ( content_type == SSL::HEARTBEAT ) event ssl_encrypted_heartbeat(c, is_orig, length); else if ( (content_type == SSL::APPLICATION_DATA) && (length > 0) ) diff --git a/scripts/policy/protocols/ssl/known-certs.bro b/scripts/policy/protocols/ssl/known-certs.bro index 739b11e767..298c665459 100644 --- a/scripts/policy/protocols/ssl/known-certs.bro +++ b/scripts/policy/protocols/ssl/known-certs.bro @@ -48,7 +48,8 @@ event bro_init() &priority=5 event ssl_established(c: connection) &priority=3 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| < 1 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| < 1 || + ! c$ssl$cert_chain[0]?$x509 ) return; local fuid = c$ssl$cert_chain_fuids[0]; diff --git a/scripts/policy/protocols/ssl/notary.bro b/scripts/policy/protocols/ssl/notary.bro index 3646a4d43e..e2b0bb2faf 100644 --- a/scripts/policy/protocols/ssl/notary.bro +++ b/scripts/policy/protocols/ssl/notary.bro @@ -39,7 +39,8 @@ function clear_waitlist(digest: string) event ssl_established(c: connection) &priority=3 { - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$sha1 ) return; local digest = c$ssl$cert_chain[0]$sha1; diff --git a/scripts/policy/protocols/ssl/validate-certs.bro b/scripts/policy/protocols/ssl/validate-certs.bro index de22e2d30d..414f0d2a54 100644 --- a/scripts/policy/protocols/ssl/validate-certs.bro +++ b/scripts/policy/protocols/ssl/validate-certs.bro @@ -28,7 +28,8 @@ export { event ssl_established(c: connection) &priority=3 { # If there aren't any certs we can't very well do certificate validation. - if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 ) + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! c$ssl$cert_chain[0]?$x509 ) return; local chain_id = join_string_vec(c$ssl$cert_chain_fuids, "."); @@ -36,7 +37,8 @@ event ssl_established(c: connection) &priority=3 local chain: vector of opaque of x509 = vector(); for ( i in c$ssl$cert_chain ) { - chain[i] = c$ssl$cert_chain[i]$x509$handle; + if ( c$ssl$cert_chain[i]?$x509 ) + chain[i] = c$ssl$cert_chain[i]$x509$handle; } if ( chain_id in recently_validated_certs ) @@ -49,7 +51,7 @@ event ssl_established(c: connection) &priority=3 c$ssl$validation_status = result$result_string; recently_validated_certs[chain_id] = result$result_string; } - + if ( c$ssl$validation_status != "ok" ) { local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status); diff --git a/scripts/policy/protocols/ssl/validate-ocsp.bro b/scripts/policy/protocols/ssl/validate-ocsp.bro index 70205c5a49..01b6853226 100644 --- a/scripts/policy/protocols/ssl/validate-ocsp.bro +++ b/scripts/policy/protocols/ssl/validate-ocsp.bro @@ -39,7 +39,10 @@ event ssl_established(c: connection) &priority=3 local chain: vector of opaque of x509 = vector(); for ( i in c$ssl$cert_chain ) - chain[i] = c$ssl$cert_chain[i]$x509$handle; + { + if ( c$ssl$cert_chain[i]?$x509 ) + chain[i] = c$ssl$cert_chain[i]$x509$handle; + } local reply_id = cat(md5_hash(c$ssl$ocsp_response), join_string_vec(c$ssl$cert_chain_fuids, ".")); diff --git a/scripts/policy/protocols/ssl/weak-keys.bro b/scripts/policy/protocols/ssl/weak-keys.bro index 47bb7a8316..f11fb9da5e 100644 --- a/scripts/policy/protocols/ssl/weak-keys.bro +++ b/scripts/policy/protocols/ssl/weak-keys.bro @@ -37,7 +37,8 @@ event ssl_established(c: connection) &priority=3 { # If there are no certificates or we are not interested in the server, just return. if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || - ! addr_matches_host(c$id$resp_h, notify_weak_keys) ) + ! addr_matches_host(c$id$resp_h, notify_weak_keys) || + ! c$ssl$cert_chain[0]?$x509 ) return; local fuid = c$ssl$cert_chain_fuids[0]; diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index b02ce5eea2..9a8a8e78b7 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -86,8 +86,10 @@ STACK_OF(X509)* x509_get_untrusted_stack(VectorVal* certs_vec) { Val *sv = certs_vec->Lookup(i); - // Fixme: check type + if ( ! sv ) + continue; + // Fixme: check type X509* x = ((file_analysis::X509Val*) sv)->GetCertificate(); if ( ! x ) {