mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Remove variable content from weird names
This changes many weird names to move non-static content from the weird name into the "addl" field to help ensure the total number of weird names is reasonably bounded. Note the net_weird and flow_weird events do not have an "addl" parameter, so information may no longer be available in those cases -- to make it available again we'd need to either (1) define new events that contain such a parameter, or (2) change net_weird/flow_weird event signature (which is a breaking change for user-code at the moment). Also, the generic handling of binpac exceptions for analyzers which to not otherwise catch and handle them has been changed from a Weird to a ProtocolViolation. Finally, a new "file_weird" event has been added for reporting weirdness found during file analysis.
This commit is contained in:
parent
956674745b
commit
995368e68c
47 changed files with 289 additions and 152 deletions
|
@ -649,3 +649,9 @@ void File::FileEvent(EventHandlerPtr h, val_list* vl)
|
|||
analyzers.DrainModifications();
|
||||
}
|
||||
}
|
||||
|
||||
bool File::PermitWeird(const char* name, uint64 threshold, uint64 rate,
|
||||
double duration)
|
||||
{
|
||||
return ::PermitWeird(weird_state, name, threshold, rate, duration);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Tag.h"
|
||||
#include "AnalyzerSet.h"
|
||||
#include "BroString.h"
|
||||
#include "WeirdState.h"
|
||||
|
||||
namespace file_analysis {
|
||||
|
||||
|
@ -192,6 +193,13 @@ public:
|
|||
*/
|
||||
bool SetMime(const string& mime_type);
|
||||
|
||||
/**
|
||||
* Whether to permit a weird to carry on through the full reporter/weird
|
||||
* framework.
|
||||
*/
|
||||
bool PermitWeird(const char* name, uint64 threshold, uint64 rate,
|
||||
double duration);
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
friend class FileReassembler;
|
||||
|
@ -325,6 +333,8 @@ protected:
|
|||
BroString::CVec chunks;
|
||||
} bof_buffer; /**< Beginning of file buffer. */
|
||||
|
||||
WeirdStateMap weird_state;
|
||||
|
||||
static int id_idx;
|
||||
static int parent_id_idx;
|
||||
static int source_idx;
|
||||
|
|
|
@ -160,11 +160,11 @@ bool file_analysis::OCSP::EndOfFile()
|
|||
|
||||
if (!req)
|
||||
{
|
||||
reporter->Weird(fmt("OPENSSL Could not parse OCSP request (fuid %s)", GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "openssl_ocsp_request_parse_error");
|
||||
return false;
|
||||
}
|
||||
|
||||
ParseRequest(req, GetFile()->GetID().c_str());
|
||||
ParseRequest(req);
|
||||
OCSP_REQUEST_free(req);
|
||||
}
|
||||
else
|
||||
|
@ -173,12 +173,12 @@ bool file_analysis::OCSP::EndOfFile()
|
|||
|
||||
if (!resp)
|
||||
{
|
||||
reporter->Weird(fmt("OPENSSL Could not parse OCSP response (fuid %s)", GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "openssl_ocsp_response_parse_error");
|
||||
return false;
|
||||
}
|
||||
|
||||
OCSP_RESPVal* resp_val = new OCSP_RESPVal(resp); // resp_val takes ownership
|
||||
ParseResponse(resp_val, GetFile()->GetID().c_str());
|
||||
ParseResponse(resp_val);
|
||||
Unref(resp_val);
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ static uint64 parse_request_version(OCSP_REQUEST* req)
|
|||
}
|
||||
#endif
|
||||
|
||||
void file_analysis::OCSP::ParseRequest(OCSP_REQUEST* req, const char* fid)
|
||||
void file_analysis::OCSP::ParseRequest(OCSP_REQUEST* req)
|
||||
{
|
||||
char buf[OCSP_STRING_BUF_SIZE]; // we need a buffer for some of the openssl functions
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
@ -453,7 +453,7 @@ void file_analysis::OCSP::ParseRequest(OCSP_REQUEST* req, const char* fid)
|
|||
BIO_free(bio);
|
||||
}
|
||||
|
||||
void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
||||
void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val)
|
||||
{
|
||||
OCSP_RESPONSE *resp = resp_val->GetResp();
|
||||
//OCSP_RESPBYTES *resp_bytes = resp->responseBytes;
|
||||
|
@ -532,7 +532,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
|||
produced_at = OCSP_resp_get0_produced_at(basic_resp);
|
||||
#endif
|
||||
|
||||
vl->append(new Val(GetTimeFromAsn1(produced_at, fid, reporter), TYPE_TIME));
|
||||
vl->append(new Val(GetTimeFromAsn1(produced_at, GetFile(), reporter), TYPE_TIME));
|
||||
|
||||
// responses
|
||||
|
||||
|
@ -579,7 +579,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
|||
// revocation time and reason if revoked
|
||||
if ( status == V_OCSP_CERTSTATUS_REVOKED )
|
||||
{
|
||||
rvl->append(new Val(GetTimeFromAsn1(revoke_time, fid, reporter), TYPE_TIME));
|
||||
rvl->append(new Val(GetTimeFromAsn1(revoke_time, GetFile(), reporter), TYPE_TIME));
|
||||
|
||||
if ( reason != OCSP_REVOKED_STATUS_NOSTATUS )
|
||||
{
|
||||
|
@ -596,12 +596,12 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
|
|||
}
|
||||
|
||||
if ( this_update )
|
||||
rvl->append(new Val(GetTimeFromAsn1(this_update, fid, reporter), TYPE_TIME));
|
||||
rvl->append(new Val(GetTimeFromAsn1(this_update, GetFile(), reporter), TYPE_TIME));
|
||||
else
|
||||
rvl->append(new Val(0.0, TYPE_TIME));
|
||||
|
||||
if ( next_update )
|
||||
rvl->append(new Val(GetTimeFromAsn1(next_update, fid, reporter), TYPE_TIME));
|
||||
rvl->append(new Val(GetTimeFromAsn1(next_update, GetFile(), reporter), TYPE_TIME));
|
||||
else
|
||||
rvl->append(new Val(0.0, TYPE_TIME));
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ protected:
|
|||
OCSP(RecordVal* args, File* file, bool request);
|
||||
|
||||
private:
|
||||
void ParseResponse(OCSP_RESPVal*, const char* fid = 0);
|
||||
void ParseRequest(OCSP_REQUEST*, const char* fid = 0);
|
||||
void ParseResponse(OCSP_RESPVal*);
|
||||
void ParseRequest(OCSP_REQUEST*);
|
||||
void ParseExtensionsSpecific(X509_EXTENSION* ex, bool, ASN1_OBJECT*, const char*) override;
|
||||
|
||||
std::string ocsp_data;
|
||||
|
|
|
@ -47,14 +47,14 @@ bool file_analysis::X509::EndOfFile()
|
|||
::X509* ssl_cert = d2i_X509(NULL, &cert_char, cert_data.size());
|
||||
if ( ! ssl_cert )
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse X509 certificate (fuid %s)", GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "x509_cert_parse_error");
|
||||
return false;
|
||||
}
|
||||
|
||||
X509Val* cert_val = new X509Val(ssl_cert); // cert_val takes ownership of ssl_cert
|
||||
|
||||
// parse basic information into record.
|
||||
RecordVal* cert_record = ParseCertificate(cert_val, GetFile()->GetID().c_str());
|
||||
RecordVal* cert_record = ParseCertificate(cert_val, GetFile());
|
||||
|
||||
// and send the record on to scriptland
|
||||
val_list* vl = new val_list();
|
||||
|
@ -86,7 +86,7 @@ bool file_analysis::X509::EndOfFile()
|
|||
return false;
|
||||
}
|
||||
|
||||
RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, const char* fid)
|
||||
RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f)
|
||||
{
|
||||
::X509* ssl_cert = cert_val->GetCertificate();
|
||||
|
||||
|
@ -133,8 +133,8 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, const char*
|
|||
pX509Cert->Assign(3, new StringVal(len, buf));
|
||||
BIO_free(bio);
|
||||
|
||||
pX509Cert->Assign(5, new Val(GetTimeFromAsn1(X509_get_notBefore(ssl_cert), fid, reporter), TYPE_TIME));
|
||||
pX509Cert->Assign(6, new Val(GetTimeFromAsn1(X509_get_notAfter(ssl_cert), fid, reporter), TYPE_TIME));
|
||||
pX509Cert->Assign(5, new Val(GetTimeFromAsn1(X509_get_notBefore(ssl_cert), f, reporter), TYPE_TIME));
|
||||
pX509Cert->Assign(6, new Val(GetTimeFromAsn1(X509_get_notAfter(ssl_cert), f, reporter), TYPE_TIME));
|
||||
|
||||
// we only read 255 bytes because byte 256 is always 0.
|
||||
// if the string is longer than 255, that will be our null-termination,
|
||||
|
@ -236,7 +236,7 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
|
|||
}
|
||||
|
||||
else
|
||||
reporter->Weird(fmt("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "x509_invalid_basic_constraint");
|
||||
}
|
||||
|
||||
void file_analysis::X509::ParseExtensionsSpecific(X509_EXTENSION* ex, bool global, ASN1_OBJECT* ext_asn, const char* oid)
|
||||
|
@ -266,7 +266,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext)
|
|||
GENERAL_NAMES *altname = (GENERAL_NAMES*)X509V3_EXT_d2i(ext);
|
||||
if ( ! altname )
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse subject alternative names. fuid %s", GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "x509_san_parse_error");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext)
|
|||
{
|
||||
if ( ASN1_STRING_type(gen->d.ia5) != V_ASN1_IA5STRING )
|
||||
{
|
||||
reporter->Weird(fmt("DNS-field does not contain an IA5String. fuid %s", GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "x509_san_non_string");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext)
|
|||
|
||||
else
|
||||
{
|
||||
reporter->Weird(fmt("Weird IP address length %d in subject alternative name. fuid %s", gen->d.ip->length, GetFile()->GetID().c_str()));
|
||||
reporter->Weird(GetFile(), "x509_san_ip_length", fmt("%d", gen->d.ip->length));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,13 +79,13 @@ public:
|
|||
*
|
||||
* @param cert_val The certificate to converts.
|
||||
*
|
||||
* @param fid A file ID associated with the certificate, if any
|
||||
* @param f A file associated with the certificate, if any
|
||||
* (primarily for error reporting).
|
||||
*
|
||||
* @param Returns the new record value and passes ownership to
|
||||
* caller.
|
||||
*/
|
||||
static RecordVal* ParseCertificate(X509Val* cert_val, const char* fid = 0);
|
||||
static RecordVal* ParseCertificate(X509Val* cert_val, File* file = 0);
|
||||
|
||||
static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file)
|
||||
{ return new X509(args, file); }
|
||||
|
|
|
@ -20,9 +20,16 @@ X509Common::X509Common(file_analysis::Tag arg_tag, RecordVal* arg_args, File* ar
|
|||
{
|
||||
}
|
||||
|
||||
double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid, Reporter* reporter)
|
||||
static void EmitWeird(const char* name, File* file, const char* addl = "")
|
||||
{
|
||||
if ( file )
|
||||
reporter->Weird(file, name, addl);
|
||||
else
|
||||
reporter->Weird(name);
|
||||
}
|
||||
|
||||
double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, File* f, Reporter* reporter)
|
||||
{
|
||||
const char *fid = arg_fid ? arg_fid : "";
|
||||
time_t lResult = 0;
|
||||
|
||||
char lBuffer[26];
|
||||
|
@ -35,14 +42,14 @@ double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid,
|
|||
{
|
||||
if ( remaining < 11 || remaining > 17 )
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- UTCTime has wrong length", fid));
|
||||
EmitWeird("x509_utc_length", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( pString[remaining-1] != 'Z' )
|
||||
{
|
||||
// not valid according to RFC 2459 4.1.2.5.1
|
||||
reporter->Weird(fmt("Could not parse UTC time in non-YY-format in X509 certificate (x509 %s)", fid));
|
||||
EmitWeird("x509_utc_format", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -71,7 +78,7 @@ double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid,
|
|||
|
||||
if ( remaining < 12 || remaining > 23 )
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- Generalized time has wrong length", fid));
|
||||
EmitWeird("x509_gen_time_length", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -82,7 +89,7 @@ double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid,
|
|||
}
|
||||
else
|
||||
{
|
||||
reporter->Weird(fmt("Invalid time type in X509 certificate (fuid %s)", fid));
|
||||
EmitWeird("x509_invalid_time_type", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -115,7 +122,7 @@ double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid,
|
|||
|
||||
else
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- additional char after time", fid));
|
||||
EmitWeird("x509_time_add_char", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,13 +137,13 @@ double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid,
|
|||
{
|
||||
if ( remaining < 5 )
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- not enough bytes remaining for offset", fid));
|
||||
EmitWeird("x509_time_offset_underflow", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((*pString != '+') && (*pString != '-'))
|
||||
{
|
||||
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- unknown offset type", fid));
|
||||
EmitWeird("x509_time_offset_type", f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -249,7 +256,7 @@ void file_analysis::X509Common::ParseExtension(X509_EXTENSION* ex, EventHandlerP
|
|||
}
|
||||
}
|
||||
|
||||
StringVal* ext_val = GetExtensionFromBIO(bio);
|
||||
StringVal* ext_val = GetExtensionFromBIO(bio, GetFile());
|
||||
|
||||
if ( ! ext_val )
|
||||
ext_val = new StringVal(0, "");
|
||||
|
@ -282,7 +289,7 @@ void file_analysis::X509Common::ParseExtension(X509_EXTENSION* ex, EventHandlerP
|
|||
ParseExtensionsSpecific(ex, global, ext_asn, oid);
|
||||
}
|
||||
|
||||
StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio)
|
||||
StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio, File* f)
|
||||
{
|
||||
BIO_flush(bio);
|
||||
ERR_clear_error();
|
||||
|
@ -292,7 +299,7 @@ StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio)
|
|||
{
|
||||
char tmp[120];
|
||||
ERR_error_string_n(ERR_get_error(), tmp, sizeof(tmp));
|
||||
reporter->Weird(fmt("X509::GetExtensionFromBIO: %s", tmp));
|
||||
EmitWeird("x509_get_ext_from_bio", f, tmp);
|
||||
BIO_free_all(bio);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,11 +25,13 @@ public:
|
|||
* @param bio the OpenSSL BIO to read. It will be freed by the function,
|
||||
* including when an error occurs.
|
||||
*
|
||||
* @param f an associated file, if any (used for error reporting).
|
||||
*
|
||||
* @return The X509 extension value.
|
||||
*/
|
||||
static StringVal* GetExtensionFromBIO(BIO* bio);
|
||||
static StringVal* GetExtensionFromBIO(BIO* bio, File* f = 0);
|
||||
|
||||
static double GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid, Reporter* reporter);
|
||||
static double GetTimeFromAsn1(const ASN1_TIME* atime, File* f, Reporter* reporter);
|
||||
|
||||
protected:
|
||||
X509Common(file_analysis::Tag arg_tag, RecordVal* arg_args, File* arg_file);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue