Merge remote-tracking branch 'origin/topic/bernhard/ssl-analyzer'

* origin/topic/bernhard/ssl-analyzer:
  Fix a few failing tests
  Add very basic ocsp stapling support.
  Add documentation, consts and tests for the new events.
  Support parsing of several TLS extensions.
  Make SSL/TLS version detection less brittle.
  Nicer notices for heartbleed.
  rip out state handline from ssl analyzer.
  enable detection of encrypted heartbleeds.
  also extract payload data in ssl_heartbeat
  add to local.bro, add disclaimer
  make tls heartbeat messages a bit better.
  fix tabs.
  polish script and probably detect encrypted attacks too.
  detect and alert on simple case of heartbleed
  default to TLS when not being able to determine version
  add is_orig to heartbeat event
  Throw new event for heartbeat messages.

BIT-1178 #merged
This commit is contained in:
Robin Sommer 2014-04-24 16:57:54 -07:00
commit 201fc7b25a
28 changed files with 800 additions and 376 deletions

View file

@ -14,15 +14,15 @@ export {
[TLSv11] = "TLSv11",
[TLSv12] = "TLSv12",
} &default=function(i: count):string { return fmt("unknown-%d", i); };
## Mapping between numeric codes and human readable strings for alert
## Mapping between numeric codes and human readable strings for alert
## levels.
const alert_levels: table[count] of string = {
[1] = "warning",
[2] = "fatal",
} &default=function(i: count):string { return fmt("unknown-%d", i); };
## Mapping between numeric codes and human readable strings for alert
## Mapping between numeric codes and human readable strings for alert
## descriptions.
const alert_descriptions: table[count] of string = {
[0] = "close_notify",
@ -58,7 +58,7 @@ export {
[115] = "unknown_psk_identity",
[120] = "no_application_protocol",
} &default=function(i: count):string { return fmt("unknown-%d", i); };
## Mapping between numeric codes and human readable strings for SSL/TLS
## extensions.
# More information can be found here:
@ -93,7 +93,50 @@ export {
[35655] = "padding",
[65281] = "renegotiation_info"
} &default=function(i: count):string { return fmt("unknown-%d", i); };
## Mapping between numeric codes and human readable string for SSL/TLS elliptic curves.
# See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
const ec_curves: table[count] of string = {
[1] = "sect163k1",
[2] = "sect163r1",
[3] = "sect163r2",
[4] = "sect193r1",
[5] = "sect193r2",
[6] = "sect233k1",
[7] = "sect233r1",
[8] = "sect239k1",
[9] = "sect283k1",
[10] = "sect283r1",
[11] = "sect409k1",
[12] = "sect409r1",
[13] = "sect571k1",
[14] = "sect571r1",
[15] = "secp160k1",
[16] = "secp160r1",
[17] = "secp160r2",
[18] = "secp192k1",
[19] = "secp192r1",
[20] = "secp224k1",
[21] = "secp224r1",
[22] = "secp256k1",
[23] = "secp256r1",
[24] = "secp384r1",
[25] = "secp521r1",
[26] = "brainpoolP256r1",
[27] = "brainpoolP384r1",
[28] = "brainpoolP512r1",
[0xFF01] = "arbitrary_explicit_prime_curves",
[0xFF02] = "arbitrary_explicit_char2_curves"
} &default=function(i: count):string { return fmt("unknown-%d", i); };
## Mapping between numeric codes and human readable string for SSL/TLC EC point formats.
# See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-9
const ec_point_formats: table[count] of string = {
[0] = "uncompressed",
[1] = "ansiX962_compressed_prime",
[2] = "ansiX962_compressed_char2"
} &default=function(i: count):string { return fmt("unknown-%d", i); };
# SSLv2
const SSLv20_CK_RC4_128_WITH_MD5 = 0x010080;
const SSLv20_CK_RC4_128_EXPORT40_WITH_MD5 = 0x020080;
@ -458,8 +501,8 @@ export {
const SSL_RSA_WITH_DES_CBC_MD5 = 0xFF82;
const SSL_RSA_WITH_3DES_EDE_CBC_MD5 = 0xFF83;
const TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF;
## This is a table of all known cipher specs. It can be used for
## This is a table of all known cipher specs. It can be used for
## detecting unknown ciphers and for converting the cipher spec
## constants into a human readable format.
const cipher_desc: table[count] of string = {
@ -820,43 +863,5 @@ export {
[SSL_RSA_WITH_3DES_EDE_CBC_MD5] = "SSL_RSA_WITH_3DES_EDE_CBC_MD5",
[TLS_EMPTY_RENEGOTIATION_INFO_SCSV] = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
} &default=function(i: count):string { return fmt("unknown-%d", i); };
## Mapping between the constants and string values for SSL/TLS errors.
const x509_errors: table[count] of string = {
[0] = "ok",
[1] = "unable to get issuer cert",
[2] = "unable to get crl",
[3] = "unable to decrypt cert signature",
[4] = "unable to decrypt crl signature",
[5] = "unable to decode issuer public key",
[6] = "cert signature failure",
[7] = "crl signature failure",
[8] = "cert not yet valid",
[9] = "cert has expired",
[10] = "crl not yet valid",
[11] = "crl has expired",
[12] = "error in cert not before field",
[13] = "error in cert not after field",
[14] = "error in crl last update field",
[15] = "error in crl next update field",
[16] = "out of mem",
[17] = "depth zero self signed cert",
[18] = "self signed cert in chain",
[19] = "unable to get issuer cert locally",
[20] = "unable to verify leaf signature",
[21] = "cert chain too long",
[22] = "cert revoked",
[23] = "invalid ca",
[24] = "path length exceeded",
[25] = "invalid purpose",
[26] = "cert untrusted",
[27] = "cert rejected",
[28] = "subject issuer mismatch",
[29] = "akid skid mismatch",
[30] = "akid issuer serial mismatch",
[31] = "keyusage no certsign",
[32] = "unable to get crl issuer",
[33] = "unhandled critical extension",
} &default=function(i: count):string { return fmt("unknown-%d", i); };
}

View file

@ -159,12 +159,16 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, server_
c$ssl$cipher = cipher_desc[cipher];
}
event ssl_extension(c: connection, is_orig: bool, code: count, val: string) &priority=5
event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec) &priority=5
{
set_session(c);
if ( is_orig && extensions[code] == "server_name" )
c$ssl$server_name = sub_bytes(val, 6, |val|);
if ( is_orig && |names| > 0 )
{
c$ssl$server_name = names[0];
if ( |names| > 1 )
event conn_weird("SSL_many_server_names", c, cat(names));
}
}
event ssl_alert(c: connection, is_orig: bool, level: count, desc: count) &priority=5
@ -194,7 +198,7 @@ event connection_state_remove(c: connection) &priority=-5
event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5
{
if ( atype == Analyzer::ANALYZER_SSL )
if ( atype == Analyzer::ANALYZER_SSL )
{
set_session(c);
c$ssl$analyzer_id = aid;