mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
More bugfixs, cleanup, and test for SSL analyzer
- SSL related files and classes renamed to remove the "binpac" term. - A small fix for DPD scripts to make the DPD log more helpful if there are multiple continued failures. Also, fixed the SSL analyzer to make it stop doing repeated violation messages for some handshake failures. - Added a $issuer_subject to the SSL log. - Created a basic test for SSL.
This commit is contained in:
parent
88807df269
commit
0a6104fe66
12 changed files with 68 additions and 96 deletions
|
@ -105,5 +105,8 @@ event protocol_violation(c: connection, atype: count, aid: count,
|
||||||
reason: string) &priority=-5
|
reason: string) &priority=-5
|
||||||
{
|
{
|
||||||
if ( c?$dpd )
|
if ( c?$dpd )
|
||||||
|
{
|
||||||
Log::write(DPD::LOG, c$dpd);
|
Log::write(DPD::LOG, c$dpd);
|
||||||
|
delete c$dpd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ export {
|
||||||
session_id: string &log &optional;
|
session_id: string &log &optional;
|
||||||
## Subject of the X.509 certificate offered by the server.
|
## Subject of the X.509 certificate offered by the server.
|
||||||
subject: string &log &optional;
|
subject: string &log &optional;
|
||||||
|
## Subject of the signer of the X.509 certificate offered by the server.
|
||||||
|
issuer_subject: string &log &optional;
|
||||||
## NotValidBefore field value from the server certificate.
|
## NotValidBefore field value from the server certificate.
|
||||||
not_valid_before: time &log &optional;
|
not_valid_before: time &log &optional;
|
||||||
## NotValidAfter field value from the serve certificate.
|
## NotValidAfter field value from the serve certificate.
|
||||||
|
@ -146,6 +148,7 @@ event x509_certificate(c: connection, is_orig: bool, cert: X509, chain_idx: coun
|
||||||
|
|
||||||
# Also save other certificate information about the primary cert.
|
# Also save other certificate information about the primary cert.
|
||||||
c$ssl$subject = cert$subject;
|
c$ssl$subject = cert$subject;
|
||||||
|
c$ssl$issuer_subject = cert$issuer;
|
||||||
c$ssl$not_valid_before = cert$not_valid_before;
|
c$ssl$not_valid_before = cert$not_valid_before;
|
||||||
c$ssl$not_valid_after = cert$not_valid_after;
|
c$ssl$not_valid_after = cert$not_valid_after;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "Portmap.h"
|
#include "Portmap.h"
|
||||||
#include "POP3.h"
|
#include "POP3.h"
|
||||||
#include "SSH.h"
|
#include "SSH.h"
|
||||||
#include "SSL-binpac.h"
|
#include "SSL.h"
|
||||||
#include "Syslog-binpac.h"
|
#include "Syslog-binpac.h"
|
||||||
#include "ConnSizeAnalyzer.h"
|
#include "ConnSizeAnalyzer.h"
|
||||||
|
|
||||||
|
@ -121,8 +121,8 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
|
||||||
HTTP_Analyzer_binpac::InstantiateAnalyzer,
|
HTTP_Analyzer_binpac::InstantiateAnalyzer,
|
||||||
HTTP_Analyzer_binpac::Available, 0, false },
|
HTTP_Analyzer_binpac::Available, 0, false },
|
||||||
{ AnalyzerTag::SSL, "SSL",
|
{ AnalyzerTag::SSL, "SSL",
|
||||||
SSL_Analyzer_binpac::InstantiateAnalyzer,
|
SSL_Analyzer::InstantiateAnalyzer,
|
||||||
SSL_Analyzer_binpac::Available, 0, false },
|
SSL_Analyzer::Available, 0, false },
|
||||||
{ AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC",
|
{ AnalyzerTag::SYSLOG_BINPAC, "SYSLOG_BINPAC",
|
||||||
Syslog_Analyzer_binpac::InstantiateAnalyzer,
|
Syslog_Analyzer_binpac::InstantiateAnalyzer,
|
||||||
Syslog_Analyzer_binpac::Available, 0, false },
|
Syslog_Analyzer_binpac::Available, 0, false },
|
||||||
|
|
|
@ -376,7 +376,7 @@ set(bro_SRCS
|
||||||
SMB.cc
|
SMB.cc
|
||||||
SMTP.cc
|
SMTP.cc
|
||||||
SSH.cc
|
SSH.cc
|
||||||
SSL-binpac.cc
|
SSL.cc
|
||||||
Scope.cc
|
Scope.cc
|
||||||
SerializationFormat.cc
|
SerializationFormat.cc
|
||||||
SerialObj.cc
|
SerialObj.cc
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
#include "SSL-binpac.h"
|
#include "SSL.h"
|
||||||
#include "TCP_Reassembler.h"
|
#include "TCP_Reassembler.h"
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
SSL_Analyzer_binpac::SSL_Analyzer_binpac(Connection* c)
|
SSL_Analyzer::SSL_Analyzer(Connection* c)
|
||||||
: TCP_ApplicationAnalyzer(AnalyzerTag::SSL, c)
|
: TCP_ApplicationAnalyzer(AnalyzerTag::SSL, c)
|
||||||
{
|
{
|
||||||
interp = new binpac::SSL::SSL_Conn(this);
|
interp = new binpac::SSL::SSL_Conn(this);
|
||||||
had_gap = false;
|
had_gap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_Analyzer_binpac::~SSL_Analyzer_binpac()
|
SSL_Analyzer::~SSL_Analyzer()
|
||||||
{
|
{
|
||||||
delete interp;
|
delete interp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_Analyzer_binpac::Done()
|
void SSL_Analyzer::Done()
|
||||||
{
|
{
|
||||||
TCP_ApplicationAnalyzer::Done();
|
TCP_ApplicationAnalyzer::Done();
|
||||||
|
|
||||||
|
@ -23,23 +23,22 @@ void SSL_Analyzer_binpac::Done()
|
||||||
interp->FlowEOF(false);
|
interp->FlowEOF(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_Analyzer_binpac::EndpointEOF(TCP_Reassembler* endp)
|
void SSL_Analyzer::EndpointEOF(TCP_Reassembler* endp)
|
||||||
{
|
{
|
||||||
TCP_ApplicationAnalyzer::EndpointEOF(endp);
|
TCP_ApplicationAnalyzer::EndpointEOF(endp);
|
||||||
interp->FlowEOF(endp->IsOrig());
|
interp->FlowEOF(endp->IsOrig());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig)
|
void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
{
|
{
|
||||||
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||||
|
|
||||||
assert(TCP());
|
assert(TCP());
|
||||||
|
|
||||||
if ( TCP()->IsPartial() )
|
if ( TCP()->IsPartial() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( had_gap )
|
if ( had_gap )
|
||||||
// XXX: If only one side had a content gap, we could still try to
|
// If only one side had a content gap, we could still try to
|
||||||
// deliver data to the other side if the script layer can handle this.
|
// deliver data to the other side if the script layer can handle this.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -53,7 +52,7 @@ void SSL_Analyzer_binpac::DeliverStream(int len, const u_char* data, bool orig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_Analyzer_binpac::Undelivered(int seq, int len, bool orig)
|
void SSL_Analyzer::Undelivered(int seq, int len, bool orig)
|
||||||
{
|
{
|
||||||
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||||
had_gap = true;
|
had_gap = true;
|
|
@ -1,14 +1,13 @@
|
||||||
#ifndef ssl_binpac_h
|
#ifndef ssl_h
|
||||||
#define ssl_binpac_h
|
#define ssl_h
|
||||||
|
|
||||||
#include "TCP.h"
|
#include "TCP.h"
|
||||||
|
|
||||||
#include "ssl_pac.h"
|
#include "ssl_pac.h"
|
||||||
|
|
||||||
class SSL_Analyzer_binpac : public TCP_ApplicationAnalyzer {
|
class SSL_Analyzer : public TCP_ApplicationAnalyzer {
|
||||||
public:
|
public:
|
||||||
SSL_Analyzer_binpac(Connection* conn);
|
SSL_Analyzer(Connection* conn);
|
||||||
virtual ~SSL_Analyzer_binpac();
|
virtual ~SSL_Analyzer();
|
||||||
|
|
||||||
// Overriden from Analyzer.
|
// Overriden from Analyzer.
|
||||||
virtual void Done();
|
virtual void Done();
|
||||||
|
@ -19,7 +18,7 @@ public:
|
||||||
virtual void EndpointEOF(TCP_Reassembler* endp);
|
virtual void EndpointEOF(TCP_Reassembler* endp);
|
||||||
|
|
||||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
||||||
{ return new SSL_Analyzer_binpac(conn); }
|
{ return new SSL_Analyzer(conn); }
|
||||||
|
|
||||||
static bool Available()
|
static bool Available()
|
||||||
{
|
{
|
|
@ -25,6 +25,7 @@
|
||||||
string orig_label(bool is_orig);
|
string orig_label(bool is_orig);
|
||||||
void free_X509(void *);
|
void free_X509(void *);
|
||||||
X509* d2i_X509_binpac(X509** px, const uint8** in, int len);
|
X509* d2i_X509_binpac(X509** px, const uint8** in, int len);
|
||||||
|
string handshake_type_label(int type);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%code{
|
%code{
|
||||||
|
@ -46,6 +47,27 @@ string orig_label(bool is_orig)
|
||||||
return d2i_X509(px, (u_char**) in, len);
|
return d2i_X509(px, (u_char**) in, len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string handshake_type_label(int type)
|
||||||
|
{
|
||||||
|
switch ( type ) {
|
||||||
|
case HELLO_REQUEST: return string("HELLO_REQUEST");
|
||||||
|
case CLIENT_HELLO: return string("CLIENT_HELLO");
|
||||||
|
case SERVER_HELLO: return string("SERVER_HELLO");
|
||||||
|
case SESSION_TICKET: return string("SESSION_TICKET");
|
||||||
|
case CERTIFICATE: return string("CERTIFICATE");
|
||||||
|
case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE");
|
||||||
|
case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST");
|
||||||
|
case SERVER_HELLO_DONE: return string("SERVER_HELLO_DONE");
|
||||||
|
case CERTIFICATE_VERIFY: return string("CERTIFICATE_VERIFY");
|
||||||
|
case CLIENT_KEY_EXCHANGE: return string("CLIENT_KEY_EXCHANGE");
|
||||||
|
case FINISHED: return string("FINISHED");
|
||||||
|
case CERTIFICATE_URL: return string("CERTIFICATE_URL");
|
||||||
|
case CERTIFICATE_STATUS: return string("CERTIFICATE_STATUS");
|
||||||
|
default: return string(fmt("UNKNOWN (%d)", type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,15 +110,15 @@ refine connection SSL_Conn += {
|
||||||
eof=0;
|
eof=0;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%eof{
|
#%eof{
|
||||||
if ( ! eof &&
|
# if ( ! eof &&
|
||||||
state_ != STATE_CONN_ESTABLISHED &&
|
# state_ != STATE_CONN_ESTABLISHED &&
|
||||||
state_ != STATE_TRACK_LOST &&
|
# state_ != STATE_TRACK_LOST &&
|
||||||
state_ != STATE_INITIAL )
|
# state_ != STATE_INITIAL )
|
||||||
bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s",
|
# bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s",
|
||||||
state_label(state_).c_str()));
|
# state_label(state_).c_str()));
|
||||||
++eof;
|
# ++eof;
|
||||||
%}
|
#%}
|
||||||
|
|
||||||
%cleanup{
|
%cleanup{
|
||||||
%}
|
%}
|
||||||
|
@ -133,11 +155,6 @@ refine connection SSL_Conn += {
|
||||||
cipher_suites16 : uint16[],
|
cipher_suites16 : uint16[],
|
||||||
cipher_suites24 : uint24[]) : bool
|
cipher_suites24 : uint24[]) : bool
|
||||||
%{
|
%{
|
||||||
if ( state_ == STATE_TRACK_LOST )
|
|
||||||
bro_analyzer()->ProtocolViolation(fmt("unexpected client hello message from %s in state %s",
|
|
||||||
orig_label(${rec.is_orig}).c_str(),
|
|
||||||
state_label(old_state_).c_str()));
|
|
||||||
|
|
||||||
if ( ! version_ok(version) )
|
if ( ! version_ok(version) )
|
||||||
bro_analyzer()->ProtocolViolation(fmt("unsupported client SSL version 0x%04x", version));
|
bro_analyzer()->ProtocolViolation(fmt("unsupported client SSL version 0x%04x", version));
|
||||||
|
|
||||||
|
@ -175,11 +192,6 @@ refine connection SSL_Conn += {
|
||||||
cipher_suites24 : uint24[],
|
cipher_suites24 : uint24[],
|
||||||
comp_method : uint8) : bool
|
comp_method : uint8) : bool
|
||||||
%{
|
%{
|
||||||
if ( state_ == STATE_TRACK_LOST )
|
|
||||||
bro_analyzer()->ProtocolViolation(fmt("unexpected server hello message from %s in state %s",
|
|
||||||
orig_label(${rec.is_orig}).c_str(),
|
|
||||||
state_label(old_state_).c_str()));
|
|
||||||
|
|
||||||
if ( ! version_ok(version) )
|
if ( ! version_ok(version) )
|
||||||
bro_analyzer()->ProtocolViolation(fmt("unsupported server SSL version 0x%04x", version));
|
bro_analyzer()->ProtocolViolation(fmt("unsupported server SSL version 0x%04x", version));
|
||||||
else
|
else
|
||||||
|
@ -229,11 +241,6 @@ refine connection SSL_Conn += {
|
||||||
|
|
||||||
function proc_certificate(rec: SSLRecord, certificates : bytestring[]) : bool
|
function proc_certificate(rec: SSLRecord, certificates : bytestring[]) : bool
|
||||||
%{
|
%{
|
||||||
if ( state_ == STATE_TRACK_LOST )
|
|
||||||
bro_analyzer()->ProtocolViolation(fmt("unexpected certificate message from %s in state %s",
|
|
||||||
orig_label(${rec.is_orig}).c_str(),
|
|
||||||
state_label(old_state_).c_str()));
|
|
||||||
|
|
||||||
if ( certificates->size() == 0 )
|
if ( certificates->size() == 0 )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -362,6 +369,7 @@ refine connection SSL_Conn += {
|
||||||
handshake_type_label(${hs.msg_type}).c_str(),
|
handshake_type_label(${hs.msg_type}).c_str(),
|
||||||
orig_label(is_orig).c_str(),
|
orig_label(is_orig).c_str(),
|
||||||
state_label(old_state_).c_str()));
|
state_label(old_state_).c_str()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
@ -17,35 +17,6 @@ enum ContentType {
|
||||||
UNKNOWN_OR_V2_ENCRYPTED = 400
|
UNKNOWN_OR_V2_ENCRYPTED = 400
|
||||||
};
|
};
|
||||||
|
|
||||||
%code{
|
|
||||||
string* record_type_label(int type)
|
|
||||||
{
|
|
||||||
switch ( type ) {
|
|
||||||
case CHANGE_CIPHER_SPEC:
|
|
||||||
return new string("CHANGE_CIPHER_SPEC");
|
|
||||||
case ALERT:
|
|
||||||
return new string("ALERT");
|
|
||||||
case HANDSHAKE:
|
|
||||||
return new string("HANDSHAKE");
|
|
||||||
case APPLICATION_DATA:
|
|
||||||
return new string("APPLICATION_DATA");
|
|
||||||
case V2_ERROR:
|
|
||||||
return new string("V2_ERROR");
|
|
||||||
case V2_CLIENT_HELLO:
|
|
||||||
return new string("V2_CLIENT_HELLO");
|
|
||||||
case V2_CLIENT_MASTER_KEY:
|
|
||||||
return new string("V2_CLIENT_MASTER_KEY");
|
|
||||||
case V2_SERVER_HELLO:
|
|
||||||
return new string("V2_SERVER_HELLO");
|
|
||||||
case UNKNOWN_OR_V2_ENCRYPTED:
|
|
||||||
return new string("UNKNOWN_OR_V2_ENCRYPTED");
|
|
||||||
|
|
||||||
default:
|
|
||||||
return new string(fmt("UNEXPECTED (%d)", type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
enum SSLVersions {
|
enum SSLVersions {
|
||||||
UNKNOWN_VERSION = 0x0000,
|
UNKNOWN_VERSION = 0x0000,
|
||||||
SSLv20 = 0x0002,
|
SSLv20 = 0x0002,
|
||||||
|
|
|
@ -23,7 +23,6 @@ type uint24 = record {
|
||||||
|
|
||||||
string state_label(int state_nr);
|
string state_label(int state_nr);
|
||||||
double get_time_from_asn1(const ASN1_TIME * atime);
|
double get_time_from_asn1(const ASN1_TIME * atime);
|
||||||
string handshake_type_label(int type);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
extern type to_int;
|
extern type to_int;
|
||||||
|
@ -268,28 +267,6 @@ enum HandshakeType {
|
||||||
CERTIFICATE_STATUS = 22, # RFC 3546
|
CERTIFICATE_STATUS = 22, # RFC 3546
|
||||||
};
|
};
|
||||||
|
|
||||||
%code{
|
|
||||||
string handshake_type_label(int type)
|
|
||||||
{
|
|
||||||
switch ( type ) {
|
|
||||||
case HELLO_REQUEST: return string("HELLO_REQUEST");
|
|
||||||
case CLIENT_HELLO: return string("CLIENT_HELLO");
|
|
||||||
case SERVER_HELLO: return string("SERVER_HELLO");
|
|
||||||
case SESSION_TICKET: return string("SESSION_TICKET");
|
|
||||||
case CERTIFICATE: return string("CERTIFICATE");
|
|
||||||
case SERVER_KEY_EXCHANGE: return string("SERVER_KEY_EXCHANGE");
|
|
||||||
case CERTIFICATE_REQUEST: return string("CERTIFICATE_REQUEST");
|
|
||||||
case SERVER_HELLO_DONE: return string("SERVER_HELLO_DONE");
|
|
||||||
case CERTIFICATE_VERIFY: return string("CERTIFICATE_VERIFY");
|
|
||||||
case CLIENT_KEY_EXCHANGE: return string("CLIENT_KEY_EXCHANGE");
|
|
||||||
case FINISHED: return string("FINISHED");
|
|
||||||
case CERTIFICATE_URL: return string("CERTIFICATE_URL");
|
|
||||||
case CERTIFICATE_STATUS: return string("CERTIFICATE_STATUS");
|
|
||||||
default: return string(fmt("UNKNOWN (%d)", type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# V3 Change Cipher Spec Protocol (7.1.)
|
# V3 Change Cipher Spec Protocol (7.1.)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path ssl
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id subject issuer_subject not_valid_before not_valid_after last_alert
|
||||||
|
#types time string addr port addr port string string string string string string time time string
|
||||||
|
1335538392.319381 UWkUyAuUGXf 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA ssl.gstatic.com - CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US 1334102677.000000 1365639277.000000 -
|
BIN
testing/btest/Traces/tls-conn-with-extensions.trace
Normal file
BIN
testing/btest/Traces/tls-conn-with-extensions.trace
Normal file
Binary file not shown.
4
testing/btest/scripts/base/protocols/ssl/basic.test
Normal file
4
testing/btest/scripts/base/protocols/ssl/basic.test
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# This tests a normal SSL connection and the log it outputs.
|
||||||
|
|
||||||
|
# @TEST-EXEC: bro -r $TRACES/tls-conn-with-extensions.trace %INPUT
|
||||||
|
# @TEST-EXEC: btest-diff ssl.log
|
Loading…
Add table
Add a link
Reference in a new issue