Merge remote-tracking branch 'origin/topic/johanna/ocsp-sct-validate'

Closes #1830.

* origin/topic/johanna/ocsp-sct-validate: (82 commits)
  Tiny script changes for SSL.
  Update CT Log list
  SSL: Update OCSP/SCT scripts and documentation.
  Revert "add parameter 'status_type' to event ssl_stapled_ocsp"
  Revert "parse multiple OCSP stapling responses"
  SCT: Fix script error when mime type of file unknown.
  SCT: another memory leak in SCT parsing.
  SCT validation: fix small memory leak (public keys were not freed)
  Change end-of-connection handling for validation
  OCSP/TLS/SCT: Fix a number of test failures.
  SCT Validate: make caching a bit less aggressive.
  SSL: Fix type of ssl validation result
  TLS-SCT: compile on old versions of OpenSSL (1.0.1...)
  SCT: Add caching support for validation
  SCT: Add signed certificate timestamp validation script.
  SCT: Allow verification of SCTs in Certs.
  SCT: only compare correct OID/NID for Cert/OCSP.
  SCT: add validation of proofs for extensions and OCSP.
  SCT: pass timestamp as uint64 instead of time
  Add CT log information to Bro
  ...
This commit is contained in:
Robin Sommer 2017-07-30 08:49:41 -07:00
commit faa4150154
86 changed files with 2672 additions and 445 deletions

@ -1 +1 @@
Subproject commit 43f4b90bbaf87dae1a1073e7bf13301e58866011 Subproject commit 02f710a436dfe285bae0d48d7f7bc498783e11a8

View file

@ -76,6 +76,10 @@ Files
+============================+=======================================+=================================+ +============================+=======================================+=================================+
| files.log | File analysis results | :bro:type:`Files::Info` | | files.log | File analysis results | :bro:type:`Files::Info` |
+----------------------------+---------------------------------------+---------------------------------+ +----------------------------+---------------------------------------+---------------------------------+
| ocsp.log | Online Certificate Status Protocol | :bro:type:`OCSP::Info` |
| | (OCSP). Only created if policy script | |
| | is loaded. | |
+----------------------------+---------------------------------------+---------------------------------+
| pe.log | Portable Executable (PE) | :bro:type:`PE::Info` | | pe.log | Portable Executable (PE) | :bro:type:`PE::Info` |
+----------------------------+---------------------------------------+---------------------------------+ +----------------------------+---------------------------------------+---------------------------------+
| x509.log | X.509 certificate info | :bro:type:`X509::Info` | | x509.log | X.509 certificate info | :bro:type:`X509::Info` |

View file

@ -1 +1,2 @@
Support for X509 certificates with the file analysis framework. Support for X509 certificates with the file analysis framework.
Also supports parsing OCSP requests and responses.

View file

@ -10,23 +10,17 @@ export {
type Info: record { type Info: record {
## Current timestamp. ## Current timestamp.
ts: time &log; ts: time &log;
## File id of this certificate. ## File id of this certificate.
id: string &log; id: string &log;
## Basic information about the certificate. ## Basic information about the certificate.
certificate: X509::Certificate &log; certificate: X509::Certificate &log;
## The opaque wrapping the certificate. Mainly used ## The opaque wrapping the certificate. Mainly used
## for the verify operations. ## for the verify operations.
handle: opaque of x509; handle: opaque of x509;
## All extensions that were encountered in the certificate. ## All extensions that were encountered in the certificate.
extensions: vector of X509::Extension &default=vector(); extensions: vector of X509::Extension &default=vector();
## Subject alternative name extension of the certificate. ## Subject alternative name extension of the certificate.
san: X509::SubjectAlternativeName &optional &log; san: X509::SubjectAlternativeName &optional &log;
## Basic constraints extension of the certificate. ## Basic constraints extension of the certificate.
basic_constraints: X509::BasicConstraints &optional &log; basic_constraints: X509::BasicConstraints &optional &log;
}; };
@ -38,6 +32,24 @@ export {
event bro_init() &priority=5 event bro_init() &priority=5
{ {
Log::create_stream(X509::LOG, [$columns=Info, $ev=log_x509, $path="x509"]); Log::create_stream(X509::LOG, [$columns=Info, $ev=log_x509, $path="x509"]);
# We use MIME types internally to distinguish between user and CA certificates.
# The first certificate in a connection always gets tagged as user-cert, all
# following certificates get tagged as CA certificates. Certificates gotten via
# other means (e.g. identified from HTTP traffic when they are transfered in plain
# text) get tagged as application/pkix-cert.
Files::register_for_mime_type(Files::ANALYZER_X509, "application/x-x509-user-cert");
Files::register_for_mime_type(Files::ANALYZER_X509, "application/x-x509-ca-cert");
Files::register_for_mime_type(Files::ANALYZER_X509, "application/pkix-cert");
# Always calculate hashes. They are not necessary for base scripts
# but very useful for identification, and required for policy scripts
Files::register_for_mime_type(Files::ANALYZER_MD5, "application/x-x509-user-cert");
Files::register_for_mime_type(Files::ANALYZER_MD5, "application/x-x509-ca-cert");
Files::register_for_mime_type(Files::ANALYZER_MD5, "application/pkix-cert");
Files::register_for_mime_type(Files::ANALYZER_SHA1, "application/x-x509-user-cert");
Files::register_for_mime_type(Files::ANALYZER_SHA1, "application/x-x509-ca-cert");
Files::register_for_mime_type(Files::ANALYZER_SHA1, "application/pkix-cert");
} }
redef record Files::Info += { redef record Files::Info += {
@ -48,9 +60,6 @@ redef record Files::Info += {
event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate) &priority=5 event x509_certificate(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate) &priority=5
{ {
if ( ! f$info?$mime_type )
f$info$mime_type = "application/pkix-cert";
f$info$x509 = [$ts=f$info$ts, $id=f$id, $certificate=cert, $handle=cert_ref]; f$info$x509 = [$ts=f$info$ts, $id=f$id, $certificate=cert, $handle=cert_ref];
} }

View file

@ -442,10 +442,13 @@ type fa_file: record {
## Metadata that's been inferred about a particular file. ## Metadata that's been inferred about a particular file.
type fa_metadata: record { type fa_metadata: record {
## The strongest matching mime type if one was discovered. ## The strongest matching MIME type if one was discovered.
mime_type: string &optional; mime_type: string &optional;
## All matching mime types if any were discovered. ## All matching MIME types if any were discovered.
mime_types: mime_matches &optional; mime_types: mime_matches &optional;
## Specifies whether the MIME type was inferred using signatures,
## or provided directly by the protocol the file appeared in.
inferred: bool &default=T;
}; };
## Fields of a SYN packet. ## Fields of a SYN packet.

View file

@ -90,12 +90,6 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
c$krb$server_cert = f$info; c$krb$server_cert = f$info;
c$krb$server_cert_fuid = f$id; c$krb$server_cert_fuid = f$id;
} }
Files::add_analyzer(f, Files::ANALYZER_X509);
# Always calculate hashes. They are not necessary for base scripts
# but very useful for identification, and required for policy scripts
Files::add_analyzer(f, Files::ANALYZER_MD5);
Files::add_analyzer(f, Files::ANALYZER_SHA1);
} }
function fill_in_subjects(c: connection) function fill_in_subjects(c: connection)

View file

@ -236,10 +236,6 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
{ {
# Count up X509 certs. # Count up X509 certs.
++c$rdp$cert_count; ++c$rdp$cert_count;
Files::add_analyzer(f, Files::ANALYZER_X509);
Files::add_analyzer(f, Files::ANALYZER_MD5);
Files::add_analyzer(f, Files::ANALYZER_SHA1);
} }
} }

View file

@ -1 +1 @@
Support for Secure Sockets Layer (SSL) protocol analysis. Support for Secure Sockets Layer (SSL)/Transport Layer Security(TLS) protocol analysis.

View file

@ -1,6 +1,7 @@
@load ./consts @load ./consts
@load ./main @load ./main
@load ./mozilla-ca-list @load ./mozilla-ca-list
@load ./ct-list
@load ./files @load ./files
@load-sigs ./dpd.sig @load-sigs ./dpd.sig

View file

@ -0,0 +1,48 @@
#
# Do not edit this file. This file is automatically generated by gen-ct-list.pl
# File generated at Thu Jul 27 16:59:25 2017
# File generated from https://www.gstatic.com/ct/log_list/all_logs_list.json
#
@load base/protocols/ssl
module SSL;
redef ct_logs += {
["\x68\xf6\x98\xf8\x1f\x64\x82\xbe\x3a\x8c\xee\xb9\x28\x1d\x4c\xfc\x71\x51\x5d\x67\x93\xd4\x44\xd1\x0a\x67\xac\xbb\x4f\x4f\xfb\xc4"] = CTInfo($description="Google 'Aviator' log", $operator="Google", $url="ct.googleapis.com/aviator/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xf4\xcc\x69\xb2\xe4\x0e\x90\xa3\x8a\xea\x5a\x70\x09\x4f\xef\x13\x62\xd0\x8d\x49\x60\xff\x1b\x40\x50\x07\x0c\x6d\x71\x86\xda\x25\x49\x8d\x65\xe1\x08\x0d\x47\x34\x6b\xbd\x27\xbc\x96\x21\x3e\x34\xf5\x87\x76\x31\xb1\x7f\x1d\xc9\x85\x3b\x0d\xf7\x1f\x3f\xe9"),
["\x29\x3c\x51\x96\x54\xc8\x39\x65\xba\xaa\x50\xfc\x58\x07\xd4\xb7\x6f\xbf\x58\x7a\x29\x72\xdc\xa4\xc3\x0c\xf4\xe5\x45\x47\xf4\x78"] = CTInfo($description="Google 'Icarus' log", $operator="Google", $url="ct.googleapis.com/icarus/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x4e\xd2\xbc\xbf\xb3\x08\x0a\xf7\xb9\xea\xa4\xc7\x1c\x38\x61\x04\xeb\x95\xe0\x89\x54\x68\x44\xb1\x66\xbc\x82\x7e\x4f\x50\x6c\x6f\x5c\xa3\xf0\xaa\x3e\xf4\xec\x80\xf0\xdb\x0a\x9a\x7a\xa0\x5b\x72\x00\x7c\x25\x0e\x19\xef\xaf\xb2\x62\x8d\x74\x43\xf4\x26\xf6\x14"),
["\xa4\xb9\x09\x90\xb4\x18\x58\x14\x87\xbb\x13\xa2\xcc\x67\x70\x0a\x3c\x35\x98\x04\xf9\x1b\xdf\xb8\xe3\x77\xcd\x0e\xc8\x0d\xdc\x10"] = CTInfo($description="Google 'Pilot' log", $operator="Google", $url="ct.googleapis.com/pilot/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7d\xa8\x4b\x12\x29\x80\xa3\x3d\xad\xd3\x5a\x77\xb8\xcc\xe2\x88\xb3\xa5\xfd\xf1\xd3\x0c\xcd\x18\x0c\xe8\x41\x46\xe8\x81\x01\x1b\x15\xe1\x4b\xf1\x1b\x62\xdd\x36\x0a\x08\x18\xba\xed\x0b\x35\x84\xd0\x9e\x40\x3c\x2d\x9e\x9b\x82\x65\xbd\x1f\x04\x10\x41\x4c\xa0"),
["\xee\x4b\xbd\xb7\x75\xce\x60\xba\xe1\x42\x69\x1f\xab\xe1\x9e\x66\xa3\x0f\x7e\x5f\xb0\x72\xd8\x83\x00\xc4\x7b\x89\x7a\xa8\xfd\xcb"] = CTInfo($description="Google 'Rocketeer' log", $operator="Google", $url="ct.googleapis.com/rocketeer/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x5b\x18\xc8\x3c\xc1\x8b\xb3\x31\x08\x00\xbf\xa0\x90\x57\x2b\xb7\x47\x8c\x6f\xb5\x68\xb0\x8e\x90\x78\xe9\xa0\x73\xea\x4f\x28\x21\x2e\x9c\xc0\xf4\x16\x1b\xaa\xf9\xd5\xd7\xa9\x80\xc3\x4e\x2f\x52\x3c\x98\x01\x25\x46\x24\x25\x28\x23\x77\x2d\x05\xc2\x40\x7a"),
["\xbb\xd9\xdf\xbc\x1f\x8a\x71\xb5\x93\x94\x23\x97\xaa\x92\x7b\x47\x38\x57\x95\x0a\xab\x52\xe8\x1a\x90\x96\x64\x36\x8e\x1e\xd1\x85"] = CTInfo($description="Google 'Skydiver' log", $operator="Google", $url="ct.googleapis.com/skydiver/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x12\x6c\x86\x0e\xf6\x17\xb1\x12\x6c\x37\x25\xd2\xad\x87\x3d\x0e\x31\xec\x21\xad\xb1\xcd\xbe\x14\x47\xb6\x71\x56\x85\x7a\x9a\xb7\x3d\x89\x90\x7b\xc6\x32\x3a\xf8\xda\xce\x8b\x01\xfe\x3f\xfc\x71\x91\x19\x8e\x14\x6e\x89\x7a\x5d\xb4\xab\x7e\xe1\x4e\x1e\x7c\xac"),
["\xa8\x99\xd8\x78\x0c\x92\x90\xaa\xf4\x62\xf3\x18\x80\xcc\xfb\xd5\x24\x51\xe9\x70\xd0\xfb\xf5\x91\xef\x75\xb0\xd9\x9b\x64\x56\x81"] = CTInfo($description="Google 'Submariner' log", $operator="Google", $url="ct.googleapis.com/submariner/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x39\xf8\x9f\x20\x62\xd4\x57\x55\x68\xa2\xef\x49\x2d\xf0\x39\x2d\x9a\xde\x44\xb4\x94\x30\xe0\x9e\x7a\x27\x3c\xab\x70\xf0\xd1\xfa\x51\x90\x63\x16\x57\x41\xad\xab\x6d\x1f\x80\x74\x30\x79\x02\x5e\x2d\x59\x84\x07\x24\x23\xf6\x9f\x35\xb8\x85\xb8\x42\x45\xa4\x4f"),
["\x1d\x02\x4b\x8e\xb1\x49\x8b\x34\x4d\xfd\x87\xea\x3e\xfc\x09\x96\xf7\x50\x6f\x23\x5d\x1d\x49\x70\x61\xa4\x77\x3c\x43\x9c\x25\xfb"] = CTInfo($description="Google 'Daedalus' log", $operator="Google", $url="ct.googleapis.com/daedalus/", $maximum_merge_delay=604800, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6e\x0c\x1c\xba\xee\x2b\x6a\x41\x85\x60\x1d\x7b\x7e\xab\x08\x2c\xfc\x0c\x0a\xa5\x08\xb3\x3e\xd5\x70\x24\xd1\x6d\x1d\x2d\xb6\xb7\xf3\x8b\x36\xdc\x23\x4d\x95\x63\x12\xbb\xe4\x86\x8d\xcc\xe9\xd1\xee\xa1\x40\xa2\xdf\x0b\xa3\x06\x0a\x30\xca\x8d\xac\xa4\x29\x56"),
["\xb0\xcc\x83\xe5\xa5\xf9\x7d\x6b\xaf\x7c\x09\xcc\x28\x49\x04\x87\x2a\xc7\xe8\x8b\x13\x2c\x63\x50\xb7\xc6\xfd\x26\xe1\x6c\x6c\x77"] = CTInfo($description="Google 'Testtube' log", $operator="Google", $url="ct.googleapis.com/testtube/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xc3\xc8\xbc\x4b\xba\xa2\x18\x4b\x3d\x35\x7b\xf4\x64\x91\x61\xea\xeb\x8e\x99\x1d\x90\xed\xd3\xe9\xaf\x39\x3d\x5c\xd3\x46\x91\x45\xe3\xce\xac\x76\x48\x3b\xd1\x7e\x2c\x0a\x63\x00\x65\x8d\xf5\xae\x8e\x8c\xc7\x11\x25\x4f\x43\x2c\x9d\x19\xa1\xe1\x91\xa4\xb3\xfe"),
["\x56\x14\x06\x9a\x2f\xd7\xc2\xec\xd3\xf5\xe1\xbd\x44\xb2\x3e\xc7\x46\x76\xb9\xbc\x99\x11\x5c\xc0\xef\x94\x98\x55\xd6\x89\xd0\xdd"] = CTInfo($description="DigiCert Log Server", $operator="DigiCert", $url="ct1.digicert-ct.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x02\x46\xc5\xbe\x1b\xbb\x82\x40\x16\xe8\xc1\xd2\xac\x19\x69\x13\x59\xf8\xf8\x70\x85\x46\x40\xb9\x38\xb0\x23\x82\xa8\x64\x4c\x7f\xbf\xbb\x34\x9f\x4a\x5f\x28\x8a\xcf\x19\xc4\x00\xf6\x36\x06\x93\x65\xed\x4c\xf5\xa9\x21\x62\x5a\xd8\x91\xeb\x38\x24\x40\xac\xe8"),
["\x87\x75\xbf\xe7\x59\x7c\xf8\x8c\x43\x99\x5f\xbd\xf3\x6e\xff\x56\x8d\x47\x56\x36\xff\x4a\xb5\x60\xc1\xb4\xea\xff\x5e\xa0\x83\x0f"] = CTInfo($description="DigiCert Log Server 2", $operator="DigiCert", $url="ct2.digicert-ct.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xcc\x5d\x39\x2f\x66\xb8\x4c\x7f\xc1\x2e\x03\xa1\x34\xa3\xe8\x8a\x86\x02\xae\x4a\x11\xc6\xf7\x26\x6a\x37\x9b\xf0\x38\xf8\x5d\x09\x8d\x63\xe8\x31\x6b\x86\x66\xcf\x79\xb3\x25\x3c\x1e\xdf\x78\xb4\xa8\xc5\x69\xfa\xb7\xf0\x82\x79\x62\x43\xf6\xcc\xfe\x81\x66\x84"),
["\xdd\xeb\x1d\x2b\x7a\x0d\x4f\xa6\x20\x8b\x81\xad\x81\x68\x70\x7e\x2e\x8e\x9d\x01\xd5\x5c\x88\x8d\x3d\x11\xc4\xcd\xb6\xec\xbe\xcc"] = CTInfo($description="Symantec log", $operator="Symantec", $url="ct.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x96\xea\xac\x1c\x46\x0c\x1b\x55\xdc\x0d\xfc\xb5\x94\x27\x46\x57\x42\x70\x3a\x69\x18\xe2\xbf\x3b\xc4\xdb\xab\xa0\xf4\xb6\x6c\xc0\x53\x3f\x4d\x42\x10\x33\xf0\x58\x97\x8f\x6b\xbe\x72\xf4\x2a\xec\x1c\x42\xaa\x03\x2f\x1a\x7e\x28\x35\x76\x99\x08\x3d\x21\x14\x86"),
["\xbc\x78\xe1\xdf\xc5\xf6\x3c\x68\x46\x49\x33\x4d\xa1\x0f\xa1\x5f\x09\x79\x69\x20\x09\xc0\x81\xb4\xf3\xf6\x91\x7f\x3e\xd9\xb8\xa5"] = CTInfo($description="Symantec 'Vega' log", $operator="Symantec", $url="vega.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xea\x95\x9e\x02\xff\xee\xf1\x33\x6d\x4b\x87\xbc\xcd\xfd\x19\x17\x62\xff\x94\xd3\xd0\x59\x07\x3f\x02\x2d\x1c\x90\xfe\xc8\x47\x30\x3b\xf1\xdd\x0d\xb8\x11\x0c\x5d\x1d\x86\xdd\xab\xd3\x2b\x46\x66\xfb\x6e\x65\xb7\x3b\xfd\x59\x68\xac\xdf\xa6\xf8\xce\xd2\x18\x4d"),
["\xa7\xce\x4a\x4e\x62\x07\xe0\xad\xde\xe5\xfd\xaa\x4b\x1f\x86\x76\x87\x67\xb5\xd0\x02\xa5\x5d\x47\x31\x0e\x7e\x67\x0a\x95\xea\xb2"] = CTInfo($description="Symantec Deneb", $operator="Symantec", $url="deneb.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x96\x82\x1e\xa3\xcd\x3a\x80\x84\x1e\x97\xb8\xb7\x07\x19\xae\x76\x1a\x0e\xf8\x55\x76\x9d\x12\x33\x4e\x91\x88\xe4\xd0\x48\x50\x5c\xc1\x9f\x6a\x72\xd6\x01\xf5\x14\xd6\xd0\x38\x6e\xe1\x32\xbc\x67\x0d\x37\xe8\xba\x22\x10\xd1\x72\x86\x79\x28\x96\xf9\x17\x1e\x98"),
["\x15\x97\x04\x88\xd7\xb9\x97\xa0\x5b\xeb\x52\x51\x2a\xde\xe8\xd2\xe8\xb4\xa3\x16\x52\x64\x12\x1a\x9f\xab\xfb\xd5\xf8\x5a\xd9\x3f"] = CTInfo($description="Symantec 'Sirius' log", $operator="Symantec", $url="sirius.ws.symantec.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa3\x02\x64\x84\x22\xbb\x25\xec\x0d\xe3\xbc\xc2\xc9\x89\x7d\xdd\x45\xd0\xee\xe6\x15\x85\x8f\xd9\xe7\x17\x1b\x13\x80\xea\xed\xb2\x85\x37\xad\x6a\xc5\xd8\x25\x9d\xfa\xf4\xb4\xf3\x6e\x16\x28\x25\x37\xea\xa3\x37\x64\xb2\xc7\x0b\xfd\x51\xe5\xc1\x05\xf4\x0e\xb5"),
["\xcd\xb5\x17\x9b\x7f\xc1\xc0\x46\xfe\xea\x31\x13\x6a\x3f\x8f\x00\x2e\x61\x82\xfa\xf8\x89\x6f\xec\xc8\xb2\xf5\xb5\xab\x60\x49\x00"] = CTInfo($description="Certly.IO log", $operator="Certly", $url="log.certly.io/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x0b\x23\xcb\x85\x62\x98\x61\x48\x04\x73\xeb\x54\x5d\xf3\xd0\x07\x8c\x2d\x19\x2d\x8c\x36\xf5\xeb\x8f\x01\x42\x0a\x7c\x98\x26\x27\xc1\xb5\xdd\x92\x93\xb0\xae\xf8\x9b\x3d\x0c\xd8\x4c\x4e\x1d\xf9\x15\xfb\x47\x68\x7b\xba\x66\xb7\x25\x9c\xd0\x4a\xc2\x66\xdb\x48"),
["\x74\x61\xb4\xa0\x9c\xfb\x3d\x41\xd7\x51\x59\x57\x5b\x2e\x76\x49\xa4\x45\xa8\xd2\x77\x09\xb0\xcc\x56\x4a\x64\x82\xb7\xeb\x41\xa3"] = CTInfo($description="Izenpe log", $operator="Izenpe", $url="ct.izenpe.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x27\x64\x39\x0c\x2d\xdc\x50\x18\xf8\x21\x00\xa2\x0e\xed\x2c\xea\x3e\x75\xba\x9f\x93\x64\x09\x00\x11\xc4\x11\x17\xab\x5c\xcf\x0f\x74\xac\xb5\x97\x90\x93\x00\x5b\xb8\xeb\xf7\x27\x3d\xd9\xb2\x0a\x81\x5f\x2f\x0d\x75\x38\x94\x37\x99\x1e\xf6\x07\x76\xe0\xee\xbe"),
["\x89\x41\x44\x9c\x70\x74\x2e\x06\xb9\xfc\x9c\xe7\xb1\x16\xba\x00\x24\xaa\x36\xd5\x9a\xf4\x4f\x02\x04\x40\x4f\x00\xf7\xea\x85\x66"] = CTInfo($description="Izenpe 'Argi' log", $operator="Izenpe", $url="ct.izenpe.eus/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xc8\x0e\x23\x3e\x9e\x02\x3c\x9a\xb8\x07\x4a\x2a\x05\xff\x4a\x4b\x88\xd4\x8a\x4d\x39\xce\xf7\xc5\xf2\xb6\x37\xe9\xa3\xed\xe4\xf5\x45\x09\x0e\x67\x14\xfd\x53\x24\xd5\x3a\x94\xf2\xea\xb5\x13\xd9\x1d\x8b\x5c\xa7\xc3\xf3\x6b\xd8\x3f\x2d\x3b\x65\x72\x58\xd6"),
["\x9e\x4f\xf7\x3d\xc3\xce\x22\x0b\x69\x21\x7c\x89\x9e\x46\x80\x76\xab\xf8\xd7\x86\x36\xd5\xcc\xfc\x85\xa3\x1a\x75\x62\x8b\xa8\x8b"] = CTInfo($description="WoSign CT log #1", $operator="Wosign", $url="ct.wosign.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xd7\xec\x2f\x2b\x75\x4f\x37\xbc\xa3\x43\xba\x8b\x65\x66\x3c\x7d\x6a\xe5\x0c\x2a\xa6\xc2\xe5\x26\xfe\x0c\x7d\x4e\x7c\xf0\x3a\xbc\xe2\xd3\x22\xdc\x01\xd0\x1f\x6e\x43\x9c\x5c\x6e\x83\xad\x9c\x15\xf6\xc4\x8d\x60\xb5\x1d\xbb\xa3\x62\x69\x7e\xeb\xa7\xaa\x01\x9b"),
["\x41\xb2\xdc\x2e\x89\xe6\x3c\xe4\xaf\x1b\xa7\xbb\x29\xbf\x68\xc6\xde\xe6\xf9\xf1\xcc\x04\x7e\x30\xdf\xfa\xe3\xb3\xba\x25\x92\x63"] = CTInfo($description="WoSign log", $operator="Wosign", $url="ctlog.wosign.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xcc\x11\x88\x7b\x2d\x66\xcb\xae\x8f\x4d\x30\x66\x27\x19\x25\x22\x93\x21\x46\xb4\x2f\x01\xd3\xc6\xf9\x2b\xd5\xc8\xba\x73\x9b\x06\xa2\xf0\x8a\x02\x9c\xd0\x6b\x46\x18\x30\x85\xba\xe9\x24\x8b\x0e\xd1\x5b\x70\x28\x0c\x7e\xf1\x3a\x45\x7f\x5a\xf3\x82\x42\x60\x31"),
["\x63\xd0\x00\x60\x26\xdd\xe1\x0b\xb0\x60\x1f\x45\x24\x46\x96\x5e\xe2\xb6\xea\x2c\xd4\xfb\xc9\x5a\xc8\x66\xa5\x50\xaf\x90\x75\xb7"] = CTInfo($description="WoSign log 2", $operator="Wosign", $url="ctlog2.wosign.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa5\x8c\xe8\x35\x2e\x8e\xe5\x6a\x75\xad\x5c\x4b\x31\x61\x29\x9d\x30\x57\x8e\x02\x13\x5f\xe9\xca\xbb\x52\xa8\x43\x05\x60\xbf\x0d\x73\x57\x77\xb2\x05\xd8\x67\xf6\xf0\x33\xc9\xf9\x44\xde\xb6\x53\x73\xaa\x0c\x55\xc2\x83\x0a\x4b\xce\x5e\x1a\xc7\x17\x1d\xb3\xcd"),
["\xc9\xcf\x89\x0a\x21\x10\x9c\x66\x6c\xc1\x7a\x3e\xd0\x65\xc9\x30\xd0\xe0\x13\x5a\x9f\xeb\xa8\x5a\xf1\x42\x10\xb8\x07\x24\x21\xaa"] = CTInfo($description="GDCA CT log #1", $operator="Wang Shengnan", $url="ct.gdca.com.cn/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xad\x0f\x30\xad\x9e\x79\xa4\x38\x89\x26\x54\x86\xab\x41\x72\x90\x6f\xfb\xca\x17\xa6\xac\xee\xc6\x9f\x7d\x02\x05\xec\x41\xa8\xc7\x41\x9d\x32\x49\xad\xb0\x39\xbd\x3a\x87\x3e\x7c\xee\x68\x6c\x60\xd1\x47\x2a\x93\xae\xe1\x40\xf4\x0b\xc8\x35\x3c\x1d\x0f\x65\xd3"),
["\x92\x4a\x30\xf9\x09\x33\x6f\xf4\x35\xd6\x99\x3a\x10\xac\x75\xa2\xc6\x41\x72\x8e\x7f\xc2\xd6\x59\xae\x61\x88\xff\xad\x40\xce\x01"] = CTInfo($description="GDCA CT log #2", $operator="GDCA", $url="ctlog.gdca.com.cn/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x5b\x4a\xc7\x01\xb7\x74\x54\xba\x40\x9c\x43\x75\x94\x3f\xac\xef\xb3\x71\x56\xb8\xd3\xe2\x7b\xae\xa1\xb1\x3e\x53\xaa\x97\x33\xa1\x82\xbb\x5f\x5d\x1c\x0b\xfa\x85\x0d\xbc\xf7\xe5\xa0\xe0\x22\xf0\xa0\x89\xd9\x0a\x7f\x5f\x26\x94\xd3\x24\xe3\x99\x2e\xe4\x15\x8d"),
["\xdb\x76\xfd\xad\xac\x65\xe7\xd0\x95\x08\x88\x6e\x21\x59\xbd\x8b\x90\x35\x2f\x5f\xea\xd3\xe3\xdc\x5e\x22\xeb\x35\x0a\xcc\x7b\x98"] = CTInfo($description="Comodo 'Dodo' CT log", $operator="Comodo", $url="dodo.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2c\xf5\xc2\x31\xf5\x63\x43\x6a\x16\x4a\x0a\xde\xc2\xee\x1f\x21\x6e\x12\x7e\x1d\xe5\x72\x8f\x74\x0b\x02\x99\xd3\xad\x69\xbc\x02\x35\x79\xf9\x61\xe9\xcf\x00\x08\x4f\x74\xa4\xa3\x34\x9a\xe0\x43\x1c\x23\x7e\x8f\x41\xd5\xee\xc7\x1c\xa3\x82\x8a\x40\xfa\xaa\xe0"),
["\xac\x3b\x9a\xed\x7f\xa9\x67\x47\x57\x15\x9e\x6d\x7d\x57\x56\x72\xf9\xd9\x81\x00\x94\x1e\x9b\xde\xff\xec\xa1\x31\x3b\x75\x78\x2d"] = CTInfo($description="Venafi log", $operator="Venafi", $url="ctlog.api.venafi.com/", $maximum_merge_delay=86400, $key="\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xa2\x5a\x48\x1f\x17\x52\x95\x35\xcb\xa3\x5b\x3a\x1f\x53\x82\x76\x94\xa3\xff\x80\xf2\x1c\x37\x3c\xc0\xb1\xbd\xc1\x59\x8b\xab\x2d\x65\x93\xd7\xf3\xe0\x04\xd5\x9a\x6f\xbf\xd6\x23\x76\x36\x4f\x23\x99\xcb\x54\x28\xad\x8c\x15\x4b\x65\x59\x76\x41\x4a\x9c\xa6\xf7\xb3\x3b\x7e\xb1\xa5\x49\xa4\x17\x51\x6c\x80\xdc\x2a\x90\x50\x4b\x88\x24\xe9\xa5\x12\x32\x93\x04\x48\x90\x02\xfa\x5f\x0e\x30\x87\x8e\x55\x76\x05\xee\x2a\x4c\xce\xa3\x6a\x69\x09\x6e\x25\xad\x82\x76\x0f\x84\x92\xfa\x38\xd6\x86\x4e\x24\x8f\x9b\xb0\x72\xcb\x9e\xe2\x6b\x3f\xe1\x6d\xc9\x25\x75\x23\x88\xa1\x18\x58\x06\x23\x33\x78\xda\x00\xd0\x38\x91\x67\xd2\xa6\x7d\x27\x97\x67\x5a\xc1\xf3\x2f\x17\xe6\xea\xd2\x5b\xe8\x81\xcd\xfd\x92\x68\xe7\xf3\x06\xf0\xe9\x72\x84\xee\x01\xa5\xb1\xd8\x33\xda\xce\x83\xa5\xdb\xc7\xcf\xd6\x16\x7e\x90\x75\x18\xbf\x16\xdc\x32\x3b\x6d\x8d\xab\x82\x17\x1f\x89\x20\x8d\x1d\x9a\xe6\x4d\x23\x08\xdf\x78\x6f\xc6\x05\xbf\x5f\xae\x94\x97\xdb\x5f\x64\xd4\xee\x16\x8b\xa3\x84\x6c\x71\x2b\xf1\xab\x7f\x5d\x0d\x32\xee\x04\xe2\x90\xec\x41\x9f\xfb\x39\xc1\x02\x03\x01\x00\x01"),
["\x03\x01\x9d\xf3\xfd\x85\xa6\x9a\x8e\xbd\x1f\xac\xc6\xda\x9b\xa7\x3e\x46\x97\x74\xfe\x77\xf5\x79\xfc\x5a\x08\xb8\x32\x8c\x1d\x6b"] = CTInfo($description="Venafi Gen2 CT log", $operator="Venafi", $url="ctlog-gen2.api.venafi.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x8e\x27\x27\x7a\xb6\x55\x09\x74\xeb\x6c\x4b\x94\x84\x65\xbc\xe4\x15\xf1\xea\x5a\xd8\x7c\x0e\x37\xce\xba\x3f\x6c\x09\xda\xe7\x29\x96\xd3\x45\x50\x6f\xde\x1e\xb4\x1c\xd2\x83\x88\xff\x29\x2f\xce\xa9\xff\xdf\x34\xde\x75\x0f\xc0\xcc\x18\x0d\x94\x2e\xfc\x37\x01"),
["\xa5\x77\xac\x9c\xed\x75\x48\xdd\x8f\x02\x5b\x67\xa2\x41\x08\x9d\xf8\x6e\x0f\x47\x6e\xc2\x03\xc2\xec\xbe\xdb\x18\x5f\x28\x26\x38"] = CTInfo($description="CNNIC CT log", $operator="CNNIC", $url="ctserver.cnnic.cn/", $maximum_merge_delay=86400, $key="\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xbf\xb5\x08\x61\x9a\x29\x32\x04\xd3\x25\x63\xe9\xd8\x85\xe1\x86\xe0\x1f\xd6\x5e\x9a\xf7\x33\x3b\x80\x1b\xe7\xb6\x3e\x5f\x2d\xa1\x66\xf6\x95\x4a\x84\xa6\x21\x56\x79\xe8\xf7\x85\xee\x5d\xe3\x7c\x12\xc0\xe0\x89\x22\x09\x22\x3e\xba\x16\x95\x06\xbd\xa8\xb9\xb1\xa9\xb2\x7a\xd6\x61\x2e\x87\x11\xb9\x78\x40\x89\x75\xdb\x0c\xdc\x90\xe0\xa4\x79\xd6\xd5\x5e\x6e\xd1\x2a\xdb\x34\xf4\x99\x3f\x65\x89\x3b\x46\xc2\x29\x2c\x15\x07\x1c\xc9\x4b\x1a\x54\xf8\x6c\x1e\xaf\x60\x27\x62\x0a\x65\xd5\x9a\xb9\x50\x36\x16\x6e\x71\xf6\x1f\x01\xf7\x12\xa7\xfc\xbf\xf6\x21\xa3\x29\x90\x86\x2d\x77\xde\xbb\x4c\xd4\xcf\xfd\xd2\xcf\x82\x2c\x4d\xd4\xf2\xc2\x2d\xac\xa9\xbe\xea\xc3\x19\x25\x43\xb2\xe5\x9a\x6c\x0d\xc5\x1c\xa5\x8b\xf7\x3f\x30\xaf\xb9\x01\x91\xb7\x69\x12\x12\xe5\x83\x61\xfe\x34\x00\xbe\xf6\x71\x8a\xc7\xeb\x50\x92\xe8\x59\xfe\x15\x91\xeb\x96\x97\xf8\x23\x54\x3f\x2d\x8e\x07\xdf\xee\xda\xb3\x4f\xc8\x3c\x9d\x6f\xdf\x3c\x2c\x43\x57\xa1\x47\x0c\x91\x04\xf4\x75\x4d\xda\x89\x81\xa4\x14\x06\x34\xb9\x98\xc3\xda\xf1\xfd\xed\x33\x36\xd3\x16\x2d\x35\x02\x03\x01\x00\x01"),
["\x34\xbb\x6a\xd6\xc3\xdf\x9c\x03\xee\xa8\xa4\x99\xff\x78\x91\x48\x6c\x9d\x5e\x5c\xac\x92\xd0\x1f\x7b\xfd\x1b\xce\x19\xdb\x48\xef"] = CTInfo($description="StartCom log", $operator="StartSSL", $url="ct.startssl.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x48\xf3\x59\xf3\xf6\x05\x18\xd3\xdb\xb2\xed\x46\x7e\xcf\xc8\x11\xb5\x57\xb1\xa8\xd6\x4c\xe6\x9f\xb7\x4a\x1a\x14\x86\x43\xa9\x48\xb0\xcb\x5a\x3f\x3c\x4a\xca\xdf\xc4\x82\x14\x55\x9a\xf8\xf7\x8e\x40\x55\xdc\xf4\xd2\xaf\xea\x75\x74\xfb\x4e\x7f\x60\x86\x2e\x51"),
["\xe0\x12\x76\x29\xe9\x04\x96\x56\x4e\x3d\x01\x47\x98\x44\x98\xaa\x48\xf8\xad\xb1\x66\x00\xeb\x79\x02\xa1\xef\x99\x09\x90\x62\x73"] = CTInfo($description="PuChuangSiDa CT log", $operator="Beijing PuChuangSiDa Technology Ltd.", $url="www.certificatetransparency.cn/ct/", $maximum_merge_delay=86400, $key="\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xac\xcf\x2f\x4b\x70\xac\xf1\x0d\x96\xbf\xe8\x0a\xfe\x44\x9d\xd4\x8c\x17\x9d\xc3\x9a\x10\x11\x84\x13\xed\x8c\xf9\x37\x6d\x83\xe4\x00\x6f\xb1\x4b\xc0\xa6\x89\xc7\x61\x8f\x9a\x34\xbb\x56\x52\xca\x03\x56\x50\xef\x24\x7f\x4b\x49\xe9\x35\x81\xdd\xf0\xe7\x17\xf5\x72\xd2\x23\xc5\xe3\x13\x7f\xd7\x8e\x78\x35\x8f\x49\xde\x98\x04\x8a\x63\xaf\xad\xa2\x39\x70\x95\x84\x68\x4b\x91\x33\xfe\x4c\xe1\x32\x17\xc2\xf2\x61\xb8\x3a\x8d\x39\x7f\xd5\x95\x82\x3e\x56\x19\x50\x45\x6f\xcb\x08\x33\x0d\xd5\x19\x42\x08\x1a\x48\x42\x10\xf1\x68\xc3\xc3\x41\x13\xcb\x0d\x1e\xdb\x02\xb7\x24\x7a\x51\x96\x6e\xbc\x08\xea\x69\xaf\x6d\xef\x92\x98\x8e\x55\xf3\x65\xe5\xe8\x9c\xbe\x1a\x47\x60\x30\x7d\x7a\x80\xad\x56\x83\x7a\x93\xc3\xae\x93\x2b\x6a\x28\x8a\xa6\x5f\x63\x19\x0c\xbe\x7c\x7b\x21\x63\x41\x38\xb7\xf7\xe8\x76\x73\x6b\x85\xcc\xbc\x72\x2b\xc1\x52\xd0\x5b\x5d\x31\x4e\x9d\x2a\xf3\x4d\x9b\x64\x14\x99\x26\xc6\x71\xf8\x7b\xf8\x44\xd5\xe3\x23\x20\xf3\x0a\xd7\x8b\x51\x3e\x72\x80\xd2\x78\x78\x35\x2d\x4a\xe7\x40\x99\x11\x95\x34\xd4\x2f\x7f\xf9\x5f\x35\x37\x02\x03\x01\x00\x01"),
["\x55\x81\xd4\xc2\x16\x90\x36\x01\x4a\xea\x0b\x9b\x57\x3c\x53\xf0\xc0\xe4\x38\x78\x70\x25\x08\x17\x2f\xa3\xaa\x1d\x07\x13\xd3\x0c"] = CTInfo($description="Comodo 'Sabre' CT log", $operator="Comodo", $url="sabre.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\x6f\xd2\x89\x0f\x3f\xc5\xf8\x87\x1e\xab\x65\xb3\xd9\xbb\x17\x23\x8c\x06\x0e\x09\x55\x96\x3d\x0a\x08\xa2\xc5\x71\xb3\xd1\xa9\x2f\x28\x3e\x83\x10\xbf\x12\xd0\x44\x66\x15\xef\x54\xe1\x98\x80\xd0\xce\x24\x6d\x3e\x67\x9a\xe9\x37\x23\xce\x52\x93\x86\xda\x80"),
["\x6f\x53\x76\xac\x31\xf0\x31\x19\xd8\x99\x00\xa4\x51\x15\xff\x77\x15\x1c\x11\xd9\x02\xc1\x00\x29\x06\x8d\xb2\x08\x9a\x37\xd9\x13"] = CTInfo($description="Comodo 'Mammoth' CT log", $operator="Comodo", $url="mammoth.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xef\xe4\x7d\x74\x2e\x15\x15\xb6\xe9\xbb\x23\x8b\xfb\x2c\xb5\xe1\xc7\x80\x98\x47\xfb\x40\x69\x68\xfc\x49\xad\x61\x4e\x83\x47\x3c\x1a\xb7\x8d\xdf\xff\x7b\x30\xb4\xba\xff\x2f\xcb\xa0\x14\xe3\xad\xd5\x85\x3f\x44\x59\x8c\x8c\x60\x8b\xd7\xb8\xb1\xbf\xae\x8c\x67"),
["\x53\x7b\x69\xa3\x56\x43\x35\xa9\xc0\x49\x04\xe3\x95\x93\xb2\xc2\x98\xeb\x8d\x7a\x6e\x83\x02\x36\x35\xc6\x27\x24\x8c\xd6\xb4\x40"] = CTInfo($description="Nordu 'flimsy' log", $operator="NORDUnet", $url="flimsy.ct.nordu.net:8080/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe2\xa5\xaa\xe9\xa7\xe1\x05\x48\xb4\x39\xd7\x16\x51\x88\x72\x24\xb3\x57\x4e\x41\xaa\x43\xd3\xcc\x4b\x99\x6a\xa0\x28\x24\x57\x68\x75\x66\xfa\x4d\x8c\x11\xf6\xbb\xc5\x1b\x81\xc3\x90\xc2\xa0\xe8\xeb\xac\xfa\x05\x64\x09\x1a\x89\x68\xcd\x96\x26\x34\x71\x36\x91"),
["\xaa\xe7\x0b\x7f\x3c\xb8\xd5\x66\xc8\x6c\x2f\x16\x97\x9c\x9f\x44\x5f\x69\xab\x0e\xb4\x53\x55\x89\xb2\xf7\x7a\x03\x01\x04\xf3\xcd"] = CTInfo($description="Nordu 'plausible' log", $operator="NORDUnet", $url="plausible.ct.nordu.net/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf5\x45\x7d\xfa\x33\xb6\x30\x24\xf3\x91\xa6\xe8\x74\xed\x85\xec\xb3\x34\xdc\xc5\x01\x73\xc3\x2b\x74\x0b\x64\x71\x6e\xaf\xe8\x60\x3d\xb5\xa4\xd3\xc3\xd4\x09\xaa\x87\xe6\xd0\x16\xdd\x02\xc6\xed\x24\xbf\xee\x9f\x21\x1f\xd3\x32\x24\x46\x05\xe3\x8f\x36\x98\xa9"),
["\xcf\x55\xe2\x89\x23\x49\x7c\x34\x0d\x52\x06\xd0\x53\x53\xae\xb2\x58\x34\xb5\x2f\x1f\x8d\xc9\x52\x68\x09\xf2\x12\xef\xdd\x7c\xa6"] = CTInfo($description="SHECA CT log 1", $operator="SHECA", $url="ctlog.sheca.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x11\xa9\x60\x2b\xb4\x71\x45\x66\xe0\x2e\xde\xd5\x87\x3b\xd5\xfe\xf0\x92\x37\xf4\x68\xc6\x92\xdd\x3f\x1a\xe2\xbc\x0c\x22\xd6\x99\x63\x29\x6e\x32\x28\x14\xc0\x76\x2c\x80\xa8\x22\x51\x91\xd6\xeb\xa6\xd8\xf1\xec\xf0\x07\x7e\xb0\xfc\x76\x70\x76\x72\x7c\x91\xe9"),
["\x32\xdc\x59\xc2\xd4\xc4\x19\x68\xd5\x6e\x14\xbc\x61\xac\x8f\x0e\x45\xdb\x39\xfa\xf3\xc1\x55\xaa\x42\x52\xf5\x00\x1f\xa0\xc6\x23"] = CTInfo($description="SHECA CT log 2", $operator="SHECA", $url="ct.sheca.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb1\x8e\x1d\x8a\xaa\x3a\xac\xce\x86\xcb\x53\x76\xe8\xa8\x9d\x59\xbe\x17\x88\x03\x07\xf2\x27\xe0\x82\xbe\xb1\xfc\x67\x3b\x46\xee\xd3\xf1\x8d\xd6\x77\xe8\xa3\xb4\xdb\x09\x5c\xa0\x09\x43\xfc\x5f\xd0\x68\x34\x23\x24\x08\xc2\x4f\xd8\xd2\xb6\x9d\xed\xd5\x8c\xdb"),
["\x96\x06\xc0\x2c\x69\x00\x33\xaa\x1d\x14\x5f\x59\xc6\xe2\x64\x8d\x05\x49\xf0\xdf\x96\xaa\xb8\xdb\x91\x5a\x70\xd8\xec\xf3\x90\xa5"] = CTInfo($description="Akamai CT Log", $operator="Akamai", $url="ct.akamai.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x43\x79\xeb\x49\x5c\x50\x2a\x4a\x6a\x8f\x59\x93\xbc\xc3\x42\x76\xc2\x99\xf8\x27\x81\x3c\x06\x6c\xd2\xc8\x04\x8f\x74\x7b\xb4\xb5\x21\xf2\xe3\xa8\xdc\x33\xb9\xfe\x25\xe9\x3d\x04\xfc\x3f\xb4\xae\x40\xe3\x45\x7e\x84\x92\x2a\xd8\x52\xeb\x1f\x3f\x73\x13\xd0\xc8"),
["\x39\x37\x6f\x54\x5f\x7b\x46\x07\xf5\x97\x42\xd7\x68\xcd\x5d\x24\x37\xbf\x34\x73\xb6\x53\x4a\x48\x34\xbc\xf7\x2e\x68\x1c\x83\xc9"] = CTInfo($description="Alpha CT Log", $operator="Matt Palmer", $url="alpha.ctlogs.org/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa2\xf7\xed\x13\xe1\xd3\x5c\x02\x08\xc4\x8e\x8b\x9b\x8b\x3b\x39\x68\xc7\x92\x6a\x38\xa1\x4f\x23\xc5\xa5\x6f\x6f\xd7\x65\x81\xf8\xc1\x9b\xf4\x9f\xa9\x8b\x45\xf4\xb9\x4e\x1b\xc9\xa2\x69\x17\xa5\x78\x87\xd9\xce\x88\x6f\x41\x03\xbb\xa3\x2a\xe3\x77\x97\x8d\x78"),
["\x29\x6a\xfa\x2d\x56\x8b\xca\x0d\x2e\xa8\x44\x95\x6a\xe9\x72\x1f\xc3\x5f\xa3\x55\xec\xda\x99\x69\x3a\xaf\xd4\x58\xa7\x1a\xef\xdd"] = CTInfo($description="Let's Encrypt 'Clicky' log", $operator="Let's Encrypt", $url="clicky.ct.letsencrypt.org/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1f\x1a\x15\x83\x77\x00\x75\x62\xb9\x9f\xf6\x06\x05\xed\x95\x89\x83\x41\x81\x97\xe7\xe0\xd4\x33\xfe\x76\xba\x3b\xc9\x49\xc2\xcd\xf1\xcf\xfe\x12\x70\xd7\xbe\xa8\x22\x5f\xb2\xa4\x67\x02\x7b\x71\xae\x1d\xac\xa8\xe9\xd1\x08\xd5\xce\xef\x33\x7a\xc3\x5f\x00\xdc"),
["\xb0\xb7\x84\xbc\x81\xc0\xdd\xc4\x75\x44\xe8\x83\xf0\x59\x85\xbb\x90\x77\xd1\x34\xd8\xab\x88\xb2\xb2\xe5\x33\x98\x0b\x8e\x50\x8b"] = CTInfo($description="Up In The Air 'Behind the Sofa' log", $operator="Up In The Air Consulting", $url="ct.filippo.io/behindthesofa/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x59\x39\xb2\xa6\x94\xc6\x32\xb9\xfe\x63\x69\x1e\x30\x3b\xa3\x5b\xd5\xb0\x43\xc9\x50\x1e\x95\xa5\x2d\xa7\x4c\x4a\x49\x8e\x8b\x8f\xb7\xf8\xcc\xe2\x5b\x97\x72\xd5\xea\x3f\xb1\x21\x48\xe8\x44\x6b\x7f\xea\xef\x22\xff\xdf\xf4\x5f\x3b\x6d\x77\x04\xb1\xaf\x90\x8f"),
};

View file

@ -91,11 +91,26 @@ event bro_init() &priority=5
$describe = SSL::describe_file]); $describe = SSL::describe_file]);
} }
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=5 event file_sniff(f: fa_file, meta: fa_metadata) &priority=5
{ {
if ( ! c?$ssl ) if ( |f$conns| != 1 )
return; return;
if ( ! f?$info || ! f$info?$mime_type )
return;
if ( ! ( f$info$mime_type == "application/x-x509-ca-cert" || f$info$mime_type == "application/x-x509-user-cert"
|| f$info$mime_type == "application/pkix-cert" ) )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
if ( ! c$ssl?$cert_chain ) if ( ! c$ssl?$cert_chain )
{ {
c$ssl$cert_chain = vector(); c$ssl$cert_chain = vector();
@ -104,7 +119,7 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
c$ssl$client_cert_chain_fuids = string_vec(); c$ssl$client_cert_chain_fuids = string_vec();
} }
if ( is_orig ) if ( f$is_orig )
{ {
c$ssl$client_cert_chain[|c$ssl$client_cert_chain|] = f$info; c$ssl$client_cert_chain[|c$ssl$client_cert_chain|] = f$info;
c$ssl$client_cert_chain_fuids[|c$ssl$client_cert_chain_fuids|] = f$id; c$ssl$client_cert_chain_fuids[|c$ssl$client_cert_chain_fuids|] = f$id;
@ -114,12 +129,6 @@ event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priori
c$ssl$cert_chain[|c$ssl$cert_chain|] = f$info; c$ssl$cert_chain[|c$ssl$cert_chain|] = f$info;
c$ssl$cert_chain_fuids[|c$ssl$cert_chain_fuids|] = f$id; c$ssl$cert_chain_fuids[|c$ssl$cert_chain_fuids|] = f$id;
} }
Files::add_analyzer(f, Files::ANALYZER_X509);
# Always calculate hashes. They are not necessary for base scripts
# but very useful for identification, and required for policy scripts.
Files::add_analyzer(f, Files::ANALYZER_MD5);
Files::add_analyzer(f, Files::ANALYZER_SHA1);
} }
event ssl_established(c: connection) &priority=6 event ssl_established(c: connection) &priority=6

View file

@ -64,7 +64,6 @@ export {
## Flag to indicate if this ssl session has been established ## Flag to indicate if this ssl session has been established
## successfully, or if it was aborted during the handshake. ## successfully, or if it was aborted during the handshake.
established: bool &log &default=F; established: bool &log &default=F;
## Flag to indicate if this record already has been logged, to ## Flag to indicate if this record already has been logged, to
## prevent duplicates. ## prevent duplicates.
logged: bool &default=F; logged: bool &default=F;
@ -74,6 +73,26 @@ export {
## script sets this to Mozilla's root CA list. ## script sets this to Mozilla's root CA list.
const root_certs: table[string] of string = {} &redef; const root_certs: table[string] of string = {} &redef;
## The record type which contains the field for the Certificate
## Transparency log bundle.
type CTInfo: record {
## Description of the Log
description: string;
## Operator of the Log
operator: string;
## Public key of the Log.
key: string;
## Maximum merge delay of the Log
maximum_merge_delay: count;
## URL of the Log
url: string;
};
## The Certificate Transparency log bundle. By default, the ct-list.bro
## script sets this to the current list of known logs. Entries
## are indexed by (binary) log-id.
const ct_logs: table[string] of CTInfo = {} &redef;
## If true, detach the SSL analyzer from the connection to prevent ## If true, detach the SSL analyzer from the connection to prevent
## continuing to process encrypted traffic. Helps with performance ## continuing to process encrypted traffic. Helps with performance
## (especially with large file transfers). ## (especially with large file transfers).
@ -90,6 +109,10 @@ export {
## Event that can be handled to access the SSL ## Event that can be handled to access the SSL
## record as it is sent on to the logging framework. ## record as it is sent on to the logging framework.
global log_ssl: event(rec: Info); global log_ssl: event(rec: Info);
# Hook that can be used to perform actions right before the log record
# is written.
global ssl_finishing: hook(c: connection);
} }
redef record connection += { redef record connection += {
@ -281,11 +304,22 @@ event ssl_established(c: connection) &priority=7
c$ssl$established = T; c$ssl$established = T;
} }
event ssl_established(c: connection) &priority=20
{
hook ssl_finishing(c);
}
event ssl_established(c: connection) &priority=-5 event ssl_established(c: connection) &priority=-5
{ {
finish(c, T); finish(c, T);
} }
event connection_state_remove(c: connection) &priority=20
{
if ( c?$ssl && ! c$ssl$logged )
hook ssl_finishing(c);
}
event connection_state_remove(c: connection) &priority=-5 event connection_state_remove(c: connection) &priority=-5
{ {
if ( c?$ssl ) if ( c?$ssl )

View file

@ -0,0 +1,62 @@
##! Enable logging of OCSP responses.
#
# This script is in policy and not loaded by default because OCSP logging
# does not provide a lot of interesting information in most environments.
module OCSP;
export {
redef enum Log::ID += { LOG };
## The record type which contains the fields of the OCSP log.
type Info: record {
## Time when the OCSP reply was encountered.
ts: time &log;
## File id of the OCSP reply.
id: string &log;
## Hash algorithm used to generate issuerNameHash and issuerKeyHash.
hashAlgorithm: string &log;
## Hash of the issuer's distingueshed name.
issuerNameHash: string &log;
## Hash of the issuer's public key.
issuerKeyHash: string &log;
## Serial number of the affected certificate.
serialNumber: string &log;
## Status of the affected certificate.
certStatus: string &log;
## Time at which the certificate was revoked.
revoketime: time &log &optional;
## Reason for which the certificate was revoked.
revokereason: string &log &optional;
## The time at which the status being shows is known to have been correct.
thisUpdate: time &log;
## The latest time at which new information about the status of the certificate will be available.
nextUpdate: time &log &optional;
};
## Event that can be handled to access the OCSP record
## as it is sent to the logging framework.
global log_ocsp: event(rec: Info);
}
event bro_init()
{
Log::create_stream(LOG, [$columns=Info, $ev=log_ocsp, $path="ocsp"]);
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
local wr = OCSP::Info($ts=f$info$ts, $id=f$id, $hashAlgorithm=hashAlgorithm, $issuerNameHash=issuerNameHash,
$issuerKeyHash=issuerKeyHash, $serialNumber=serialNumber, $certStatus=certStatus,
$thisUpdate=thisUpdate);
if ( revokereason != "" )
wr$revokereason = revokereason;
if ( time_to_double(revoketime) != 0 )
wr$revoketime = revoketime;
if ( time_to_double(nextUpdate) != 0 )
wr$nextUpdate = nextUpdate;
Log::write(LOG, wr);
}

View file

@ -8,7 +8,7 @@ module X509;
export { export {
redef record Info += { redef record Info += {
# Logging is suppressed if field is set to F ## Logging of certificate is suppressed if set to F
logcert: bool &default=T; logcert: bool &default=T;
}; };
} }
@ -39,14 +39,29 @@ event bro_init() &priority=2
Log::add_filter(X509::LOG, f); Log::add_filter(X509::LOG, f);
} }
event file_over_new_connection(f: fa_file, c: connection, is_orig: bool) &priority=2 event file_sniff(f: fa_file, meta: fa_metadata) &priority=4
{ {
if ( ! c?$ssl ) if ( |f$conns| != 1 )
return; return;
if ( ! f?$info || ! f$info?$mime_type )
return;
if ( ! ( f$info$mime_type == "application/x-x509-ca-cert" || f$info$mime_type == "application/x-x509-user-cert"
|| f$info$mime_type == "application/pkix-cert" ) )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
local chain: vector of string; local chain: vector of string;
if ( is_orig ) if ( f$is_orig )
chain = c$ssl$client_cert_chain_fuids; chain = c$ssl$client_cert_chain_fuids;
else else
chain = c$ssl$cert_chain_fuids; chain = c$ssl$cert_chain_fuids;

View file

@ -19,12 +19,17 @@ export {
redef record Info += { redef record Info += {
## Result of certificate validation for this connection. ## Result of certificate validation for this connection.
validation_status: string &log &optional; validation_status: string &log &optional;
## Result of certificate validation for this connection, given
## as OpenSSL validation code.
validation_code: int &optional;
## Ordered chain of validated certificate, if validation succeeded.
valid_chain: vector of opaque of x509 &optional;
}; };
## MD5 hash values for recently validated chains along with the ## Result values for recently validated chains along with the
## validation status are kept in this table to avoid constant ## validation status are kept in this table to avoid constant
## validation every time the same certificate chain is seen. ## validation every time the same certificate chain is seen.
global recently_validated_certs: table[string] of string = table() global recently_validated_certs: table[string] of X509::Result = table()
&read_expire=5mins &redef; &read_expire=5mins &redef;
## Use intermediate CA certificate caching when trying to validate ## Use intermediate CA certificate caching when trying to validate
@ -39,6 +44,11 @@ export {
## that you encounter. Only disable if you want to find misconfigured servers. ## that you encounter. Only disable if you want to find misconfigured servers.
global ssl_cache_intermediate_ca: bool = T &redef; global ssl_cache_intermediate_ca: bool = T &redef;
## Store the valid chain in c$ssl$valid_chain if validation succeeds.
## This has a potentially high memory impact, depending on the local environment
## and is thus disabled by default.
global ssl_store_valid_chain: bool = F &redef;
## Event from a worker to the manager that it has encountered a new ## Event from a worker to the manager that it has encountered a new
## valid intermediate. ## valid intermediate.
global intermediate_add: event(key: string, value: vector of opaque of x509); global intermediate_add: event(key: string, value: vector of opaque of x509);
@ -83,7 +93,7 @@ event SSL::new_intermediate(key: string, value: vector of opaque of x509)
} }
@endif @endif
function cache_validate(chain: vector of opaque of x509): string function cache_validate(chain: vector of opaque of x509): X509::Result
{ {
local chain_hash: vector of string = vector(); local chain_hash: vector of string = vector();
@ -97,7 +107,10 @@ function cache_validate(chain: vector of opaque of x509): string
return recently_validated_certs[chain_id]; return recently_validated_certs[chain_id];
local result = x509_verify(chain, root_certs); local result = x509_verify(chain, root_certs);
recently_validated_certs[chain_id] = result$result_string; if ( ! ssl_store_valid_chain && result?$chain_certs )
recently_validated_certs[chain_id] = X509::Result($result=result$result, $result_string=result$result_string);
else
recently_validated_certs[chain_id] = result;
# if we have a working chain where we did not store the intermediate certs # if we have a working chain where we did not store the intermediate certs
# in our cache yet - do so # in our cache yet - do so
@ -107,8 +120,8 @@ function cache_validate(chain: vector of opaque of x509): string
|result$chain_certs| > 2 ) |result$chain_certs| > 2 )
{ {
local result_chain = result$chain_certs; local result_chain = result$chain_certs;
local icert = x509_parse(result_chain[1]); local isnh = x509_subject_name_hash(result_chain[1], 4); # SHA256
if ( icert$subject !in intermediate_cache ) if ( isnh !in intermediate_cache )
{ {
local cachechain: vector of opaque of x509; local cachechain: vector of opaque of x509;
for ( i in result_chain ) for ( i in result_chain )
@ -116,14 +129,14 @@ function cache_validate(chain: vector of opaque of x509): string
if ( i >=1 && i<=|result_chain|-2 ) if ( i >=1 && i<=|result_chain|-2 )
cachechain[i-1] = result_chain[i]; cachechain[i-1] = result_chain[i];
} }
add_to_cache(icert$subject, cachechain); add_to_cache(isnh, cachechain);
} }
} }
return result$result_string; return result;
} }
event ssl_established(c: connection) &priority=3 hook ssl_finishing(c: connection) &priority=20
{ {
# If there aren't any certs we can't very well do certificate validation. # 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 ||
@ -131,23 +144,26 @@ event ssl_established(c: connection) &priority=3
return; return;
local intermediate_chain: vector of opaque of x509 = vector(); local intermediate_chain: vector of opaque of x509 = vector();
local issuer = c$ssl$cert_chain[0]$x509$certificate$issuer; local issuer_name_hash = x509_issuer_name_hash(c$ssl$cert_chain[0]$x509$handle, 4); # SHA256
local hash = c$ssl$cert_chain[0]$sha1; local hash = c$ssl$cert_chain[0]$sha1;
local result: string; local result: X509::Result;
# Look if we already have a working chain for the issuer of this cert. # Look if we already have a working chain for the issuer of this cert.
# If yes, try this chain first instead of using the chain supplied from # If yes, try this chain first instead of using the chain supplied from
# the server. # the server.
if ( ssl_cache_intermediate_ca && issuer in intermediate_cache ) if ( ssl_cache_intermediate_ca && issuer_name_hash in intermediate_cache )
{ {
intermediate_chain[0] = c$ssl$cert_chain[0]$x509$handle; intermediate_chain[0] = c$ssl$cert_chain[0]$x509$handle;
for ( i in intermediate_cache[issuer] ) for ( i in intermediate_cache[issuer_name_hash] )
intermediate_chain[i+1] = intermediate_cache[issuer][i]; intermediate_chain[i+1] = intermediate_cache[issuer_name_hash][i];
result = cache_validate(intermediate_chain); result = cache_validate(intermediate_chain);
if ( result == "ok" ) if ( result$result_string == "ok" )
{ {
c$ssl$validation_status = result; c$ssl$validation_status = result$result_string;
c$ssl$validation_code = result$result;
if ( result?$chain_certs )
c$ssl$valid_chain = result$chain_certs;
return; return;
} }
} }
@ -163,13 +179,16 @@ event ssl_established(c: connection) &priority=3
} }
result = cache_validate(chain); result = cache_validate(chain);
c$ssl$validation_status = result; c$ssl$validation_status = result$result_string;
c$ssl$validation_code = result$result;
if ( result?$chain_certs )
c$ssl$valid_chain = result$chain_certs;
if ( result != "ok" ) if ( result$result_string != "ok" )
{ {
local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status); local message = fmt("SSL certificate validation failed with (%s)", c$ssl$validation_status);
NOTICE([$note=Invalid_Server_Cert, $msg=message, NOTICE([$note=Invalid_Server_Cert, $msg=message,
$sub=c$ssl$subject, $conn=c, $sub=c$ssl$cert_chain[0]$x509$certificate$subject, $conn=c,
$identifier=cat(c$id$resp_h,c$id$resp_p,hash,c$ssl$validation_status)]); $identifier=cat(c$id$resp_h,c$id$resp_p,hash,c$ssl$validation_code)]);
} }
} }

View file

@ -1,4 +1,9 @@
##! Perform OCSP response validation. ##! Perform validation of stapled OCSP responses.
#!
#! Note: this _only_ performs validation of stapled OCSP responsed. It does
#! not validate OCSP responses that are retrieved via HTTP, because we do not
#! have a mapping to certificates.
@load base/frameworks/notice @load base/frameworks/notice
@load base/protocols/ssl @load base/protocols/ssl
@ -15,7 +20,6 @@ export {
redef record Info += { redef record Info += {
## Result of ocsp validation for this connection. ## Result of ocsp validation for this connection.
ocsp_status: string &log &optional; ocsp_status: string &log &optional;
## ocsp response as string. ## ocsp response as string.
ocsp_response: string &optional; ocsp_response: string &optional;
}; };

View file

@ -0,0 +1,210 @@
##! Perform validation of Signed Certificate Timestamps, as used
##! for Certificate Transparency. See RFC6962 for more details.
@load base/protocols/ssl
@load protocols/ssl/validate-certs
# We need to know issuer certificates to be able to determine the IssuerKeyHash,
# which is required for validating certificate extensions.
redef SSL::ssl_store_valid_chain = T;
module SSL;
export {
## List of the different sources for Signed Certificate Timestamp
type SctSource: enum {
## Signed Certificate Timestamp was encountered in the extension of
## an X.509 certificate.
SCT_X509_EXT,
## Signed Certificate Timestamp was encountered in an TLS session
## extension.
SCT_TLS_EXT,
## Signed Certificate Timestamp was encountered in the extension of
## an stapled OCSP reply.
SCT_OCSP_EXT
};
## This record is used to store information about the SCTs that are
## encountered in a SSL connection.
type SctInfo: record {
## The version of the encountered SCT (should always be 0 for v1).
version: count;
## The ID of the log issuing this SCT.
logid: string;
## The timestamp at which this SCT was issued measured since the
## epoch (January 1, 1970, 00:00), ignoring leap seconds, in
## milliseconds. Not converted to a Bro timestamp because we need
## the exact value for validation.
timestamp: count;
## The signature algorithm used for this sct.
sig_alg: count;
## The hash algorithm used for this sct.
hash_alg: count;
## The signature of this SCT.
signature: string;
## Source of this SCT.
source: SctSource;
## Validation result of this SCT.
valid: bool &optional;
};
redef record Info += {
## Number of valid SCTs that were encountered in the connection.
valid_scts: count &optional;
## Number of SCTs that could not be validated that were encountered in the connection.
invalid_scts: count &optional;
## Number of different Logs for which valid SCTs were encountered in the connection.
valid_ct_logs: count &log &optional;
## Number of different Log operators of which valid SCTs were encountered in the connection.
valid_ct_operators: count &log &optional;
## List of operators for which valid SCTs were encountered in the connection.
valid_ct_operators_list: set[string] &optional;
## Information about all SCTs that were encountered in the connection.
ct_proofs: vector of SctInfo &default=vector();
};
}
# Used to cache validations for 5 minutes to lessen computational load.
global recently_validated_scts: table[string] of bool = table()
&read_expire=5mins &redef;
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ssl_extension_signed_certificate_timestamp(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string) &priority=5
{
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_and_hashalgorithm$SignatureAlgorithm, $hash_alg=signature_and_hashalgorithm$HashAlgorithm, $signature=signature, $source=SCT_TLS_EXT);
}
event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string) &priority=5
{
local src: SctSource;
if ( ! f?$info )
return;
if ( f$source == "SSL" && f$info$mime_type == "application/ocsp-response" )
src = SCT_OCSP_EXT;
else if ( f$source == "SSL" && f$info$mime_type == "application/x-x509-user-cert" )
src = SCT_X509_EXT;
else
return;
if ( |f$conns| != 1 )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = SctInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_algorithm, $hash_alg=hash_algorithm, $signature=signature, $source=src);
}
# Priority = 19 will be handled after validation is done
hook ssl_finishing(c: connection) &priority=19
{
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 )
return;
local cert = c$ssl$cert_chain[0]$x509$handle;
local certhash = c$ssl$cert_chain[0]$sha1;
local issuer_name_hash = x509_issuer_name_hash(cert, 4);
local valid_proofs = 0;
local invalid_proofs = 0;
c$ssl$valid_ct_operators_list = string_set();
local valid_logs = string_set();
local issuer_key_hash = "";
for ( i in c$ssl$ct_proofs )
{
local proof = c$ssl$ct_proofs[i];
if ( proof$logid !in SSL::ct_logs )
{
# Well, if we don't know the log, there is nothing to do here...
proof$valid = F;
next;
}
local log = SSL::ct_logs[proof$logid];
local valid = F;
local found_cache = F;
local validatestring = cat(certhash,proof$logid,proof$timestamp,proof$hash_alg,proof$signature,proof$source);
if ( proof$source == SCT_X509_EXT && c$ssl?$validation_code )
validatestring = cat(validatestring, c$ssl$validation_code);
local validate_hash = sha1_hash(validatestring);
if ( validate_hash in recently_validated_scts )
{
valid = recently_validated_scts[validate_hash];
found_cache = T;
}
if ( found_cache == F && ( proof$source == SCT_TLS_EXT || proof$source == SCT_OCSP_EXT ) )
{
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg);
}
else if ( found_cache == F )
{
# X.509 proof. Here things get awkward because we need information about
# the issuer cert... and we need to try a few times, because we have to see if we got
# the right issuer cert.
#
# First - Let's try if a previous round already established the correct issuer key hash.
if ( issuer_key_hash != "" )
{
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
}
# Second - let's see if we might already know the issuer cert through verification.
if ( ! valid && issuer_name_hash in intermediate_cache )
{
issuer_key_hash = x509_spki_hash(intermediate_cache[issuer_name_hash][0], 4);
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
}
if ( ! valid && c$ssl?$valid_chain && |c$ssl$valid_chain| >= 2 )
{
issuer_key_hash = x509_spki_hash(c$ssl$valid_chain[1], 4);
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
}
# ok, if it still did not work - let's just try with all the certs that were sent
# in the connection. Perhaps it will work with one of them.
if ( !valid )
for ( i in c$ssl$cert_chain )
{
if ( i == 0 ) # end-host-cert
next;
issuer_key_hash = x509_spki_hash(c$ssl$cert_chain[i]$x509$handle, 4);
valid = sct_verify(cert, proof$logid, log$key, proof$signature, proof$timestamp, proof$hash_alg, issuer_key_hash);
if ( valid )
break;
}
}
if ( ! found_cache )
recently_validated_scts[validate_hash] = valid;
proof$valid = valid;
if ( valid )
{
++valid_proofs;
add c$ssl$valid_ct_operators_list[log$operator];
add valid_logs[proof$logid];
}
else
++invalid_proofs;
}
c$ssl$valid_scts = valid_proofs;
c$ssl$invalid_scts = invalid_proofs;
c$ssl$valid_ct_operators = |c$ssl$valid_ct_operators_list|;
c$ssl$valid_ct_logs = |valid_logs|;
}

View file

@ -34,6 +34,7 @@
@load frameworks/files/entropy-test-all-files.bro @load frameworks/files/entropy-test-all-files.bro
#@load frameworks/files/extract-all-files.bro #@load frameworks/files/extract-all-files.bro
@load frameworks/files/hash-all-files.bro @load frameworks/files/hash-all-files.bro
@load files/x509/log-ocsp.bro
@load frameworks/packet-filter/shunt.bro @load frameworks/packet-filter/shunt.bro
@load frameworks/software/version-changes.bro @load frameworks/software/version-changes.bro
@load frameworks/software/vulnerable.bro @load frameworks/software/vulnerable.bro
@ -98,6 +99,7 @@
#@load protocols/ssl/notary.bro #@load protocols/ssl/notary.bro
@load protocols/ssl/validate-certs.bro @load protocols/ssl/validate-certs.bro
@load protocols/ssl/validate-ocsp.bro @load protocols/ssl/validate-ocsp.bro
@load protocols/ssl/validate-sct.bro
@load protocols/ssl/weak-keys.bro @load protocols/ssl/weak-keys.bro
@load tuning/__load__.bro @load tuning/__load__.bro
@load tuning/defaults/__load__.bro @load tuning/defaults/__load__.bro

View file

@ -115,6 +115,7 @@ SERIAL_VAL(CARDINALITY_VAL, 22)
SERIAL_VAL(X509_VAL, 23) SERIAL_VAL(X509_VAL, 23)
SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24) SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24)
SERIAL_VAL(COMM_DATA_VAL, 25) SERIAL_VAL(COMM_DATA_VAL, 25)
SERIAL_VAL(OCSP_RESP_VAL, 26)
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR) #define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
SERIAL_EXPR(EXPR, 1) SERIAL_EXPR(EXPR, 1)

View file

@ -628,6 +628,7 @@ extern OpaqueType* cardinality_type;
extern OpaqueType* topk_type; extern OpaqueType* topk_type;
extern OpaqueType* bloomfilter_type; extern OpaqueType* bloomfilter_type;
extern OpaqueType* x509_opaque_type; extern OpaqueType* x509_opaque_type;
extern OpaqueType* ocsp_resp_opaque_type;
// Returns the Bro basic (non-parameterized) type with the given type. // Returns the Bro basic (non-parameterized) type with the given type.
// The reference count of the type is not increased. // The reference count of the type is not increased.

View file

@ -76,7 +76,7 @@ VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_a
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(), cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), true, file_id); bro_analyzer->Conn(), true, file_id, "application/x-x509-user-cert");
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
break; break;
@ -100,7 +100,7 @@ VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_a
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer->GetAnalyzerTag(), cert.length(), bro_analyzer->GetAnalyzerTag(),
bro_analyzer->Conn(), false, file_id); bro_analyzer->Conn(), false, file_id, "application/x-x509-user-cert");
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
break; break;

View file

@ -142,7 +142,7 @@ refine flow RDP_Flow += {
connection()->bro_analyzer()->GetAnalyzerTag(), connection()->bro_analyzer()->GetAnalyzerTag(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
false, // It seems there are only server certs? false, // It seems there are only server certs?
file_id); file_id, "application/x-x509-user-cert");
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
return true; return true;

View file

@ -12,6 +12,7 @@ bro_plugin_pac(tls-handshake.pac tls-handshake-protocol.pac tls-handshake-analyz
proc-client-hello.pac proc-client-hello.pac
proc-server-hello.pac proc-server-hello.pac
proc-certificate.pac proc-certificate.pac
tls-handshake-signed_certificate_timestamp.pac
) )
bro_plugin_pac(ssl.pac ssl-dtls-analyzer.pac ssl-analyzer.pac ssl-dtls-protocol.pac ssl-protocol.pac ssl-defs.pac bro_plugin_pac(ssl.pac ssl-dtls-analyzer.pac ssl-analyzer.pac ssl-dtls-protocol.pac ssl-protocol.pac ssl-defs.pac
proc-client-hello.pac proc-client-hello.pac

View file

@ -198,7 +198,7 @@ event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%);
## the initial handshake. It contains the list of client supported application ## the initial handshake. It contains the list of client supported application
## protocols by the client or the server, respectively. ## protocols by the client or the server, respectively.
## ##
## At the moment it is mostly used to negotiate the use of SPDY / HTTP2-drafts. ## At the moment it is mostly used to negotiate the use of SPDY / HTTP2.
## ##
## c: The connection. ## c: The connection.
## ##
@ -211,6 +211,7 @@ event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%);
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats ## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_server_name ssl_extension_key_share ## ssl_extension_server_name ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_extension_signed_certificate_timestamp
event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%); event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%);
## Generated for an SSL/TLS Server Name extension. This SSL/TLS extension is ## Generated for an SSL/TLS Server Name extension. This SSL/TLS extension is
@ -231,8 +232,39 @@ event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_or
## ssl_extension_application_layer_protocol_negotiation ## ssl_extension_application_layer_protocol_negotiation
## ssl_extension_key_share ## ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions ## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_extension_signed_certificate_timestamp
event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec%); event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec%);
## Generated for the signed_certificate_timestamp TLS extension as defined in
## :rfc:`6962`. The extension is used to transmit signed proofs that are
## used for Certificate Transparency.
##
## c: The connection.
##
## is_orig: True if event is raised for originator side of the connection.
##
## version: the version of the protocol to which the SCT conforms. Always
## should be 0 (representing version 1)
##
## logid: 32 bit key id
##
## timestamp: the NTP Time when the entry was logged measured since
## the epoch, ignoring leap seconds, in milliseconds.
##
## signature_and_hashalgorithm: signature and hash algorithm used for the
## digitally_signed struct
##
## signature: signature part of the digitally_signed struct
##
## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello
## ssl_session_ticket_handshake ssl_extension
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_server_name ssl_extension_key_share
## ssl_extension_psk_key_exchange_modes ssl_extension_supported_versions
## ssl_extension_application_layer_protocol_negotiation
## x509_ocsp_ext_signed_certificate_timestamp sct_verify
event ssl_extension_signed_certificate_timestamp%(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string%);
## Generated for an TLS Supported Versions extension. This TLS extension ## Generated for an TLS Supported Versions extension. This TLS extension
## is defined in the TLS 1.3 rfc and sent by the client in the initial handshake. ## is defined in the TLS 1.3 rfc and sent by the client in the initial handshake.
## It contains the TLS versions that it supports. This informaion can be used by ## It contains the TLS versions that it supports. This informaion can be used by
@ -249,7 +281,7 @@ event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats ## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_application_layer_protocol_negotiation ## ssl_extension_application_layer_protocol_negotiation
## ssl_extension_key_share ssl_extension_server_name ## ssl_extension_key_share ssl_extension_server_name
## ssl_extension_psk_key_exchange_modes ## ssl_extension_psk_key_exchange_modes ssl_extension_signed_certificate_timestamp
event ssl_extension_supported_versions%(c: connection, is_orig: bool, versions: index_vec%); event ssl_extension_supported_versions%(c: connection, is_orig: bool, versions: index_vec%);
## Generated for an TLS Pre-Shared Key Exchange Modes extension. This TLS extension is defined ## Generated for an TLS Pre-Shared Key Exchange Modes extension. This TLS extension is defined
@ -266,7 +298,7 @@ event ssl_extension_supported_versions%(c: connection, is_orig: bool, versions:
## ssl_extension_elliptic_curves ssl_extension_ec_point_formats ## ssl_extension_elliptic_curves ssl_extension_ec_point_formats
## ssl_extension_application_layer_protocol_negotiation ## ssl_extension_application_layer_protocol_negotiation
## ssl_extension_key_share ssl_extension_server_name ## ssl_extension_key_share ssl_extension_server_name
## ssl_extension_supported_versions ## ssl_extension_supported_versions ssl_extension_signed_certificate_timestamp
event ssl_extension_psk_key_exchange_modes%(c: connection, is_orig: bool, modes: index_vec%); event ssl_extension_psk_key_exchange_modes%(c: connection, is_orig: bool, modes: index_vec%);
## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with ## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with

View file

@ -1,6 +1,7 @@
%%{ %%{
#include "analyzer/protocol/ssl/SSL.h" #include "analyzer/protocol/ssl/SSL.h"
#include <openssl/x509.h>
%%} %%}
## Sets if the SSL analyzer should consider the connection established (handshake ## Sets if the SSL analyzer should consider the connection established (handshake

View file

@ -9,6 +9,9 @@
common.AddRaw(is_orig ? "T" : "F", 1); common.AddRaw(is_orig ? "T" : "F", 1);
bro_analyzer()->Conn()->IDString(&common); bro_analyzer()->Conn()->IDString(&common);
static const string user_mime = "application/x-x509-user-cert";
static const string ca_mime = "application/x-x509-ca-cert";
for ( unsigned int i = 0; i < certificates->size(); ++i ) for ( unsigned int i = 0; i < certificates->size(); ++i )
{ {
const bytestring& cert = (*certificates)[i]; const bytestring& cert = (*certificates)[i];
@ -21,7 +24,7 @@
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()), file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
cert.length(), bro_analyzer()->GetAnalyzerTag(), cert.length(), bro_analyzer()->GetAnalyzerTag(),
bro_analyzer()->Conn(), is_orig, file_id); bro_analyzer()->Conn(), is_orig, file_id, i == 0 ? user_mime : ca_mime);
file_mgr->EndOfFile(file_id); file_mgr->EndOfFile(file_id);
} }
return true; return true;

View file

@ -243,12 +243,30 @@ refine connection Handshake_Conn += {
function proc_certificate_status(rec : HandshakeRecord, status_type: uint8, response: bytestring) : bool function proc_certificate_status(rec : HandshakeRecord, status_type: uint8, response: bytestring) : bool
%{ %{
ODesc common;
common.AddRaw("Analyzer::ANALYZER_SSL");
common.Add(bro_analyzer()->Conn()->StartTime());
common.AddRaw("F");
bro_analyzer()->Conn()->IDString(&common);
if ( status_type == 1 ) // ocsp if ( status_type == 1 ) // ocsp
{ {
ODesc file_handle;
file_handle.Add(common.Description());
file_handle.Add("ocsp");
string file_id = file_mgr->HashHandle(file_handle.Description());
file_mgr->DataIn(reinterpret_cast<const u_char*>(response.data()),
response.length(), bro_analyzer()->GetAnalyzerTag(),
bro_analyzer()->Conn(), false, file_id, "application/ocsp-response");
BifEvent::generate_ssl_stapled_ocsp(bro_analyzer(), BifEvent::generate_ssl_stapled_ocsp(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig}, bro_analyzer()->Conn(), ${rec.is_orig},
new StringVal(response.length(), new StringVal(response.length(),
(const char*) response.data())); (const char*) response.data()));
file_mgr->EndOfFile(file_id);
} }
return true; return true;
@ -263,6 +281,24 @@ refine connection Handshake_Conn += {
return true; return true;
%} %}
function proc_signedcertificatetimestamp(rec: HandshakeRecord, version: uint8, logid: const_bytestring, timestamp: uint64, digitally_signed_algorithms: SignatureAndHashAlgorithm, digitally_signed_signature: const_bytestring) : bool
%{
RecordVal* ha = new RecordVal(BifType::Record::SSL::SignatureAndHashAlgorithm);
ha->Assign(0, new Val(digitally_signed_algorithms->HashAlgorithm(), TYPE_COUNT));
ha->Assign(1, new Val(digitally_signed_algorithms->SignatureAlgorithm(), TYPE_COUNT));
BifEvent::generate_ssl_extension_signed_certificate_timestamp(bro_analyzer(),
bro_analyzer()->Conn(), ${rec.is_orig},
version,
new StringVal(logid.length(), reinterpret_cast<const char*>(logid.begin())),
timestamp,
ha,
new StringVal(digitally_signed_signature.length(), reinterpret_cast<const char*>(digitally_signed_signature.begin()))
);
return true;
%}
function proc_dh_server_key_exchange(rec: HandshakeRecord, p: bytestring, g: bytestring, Ys: bytestring) : bool function proc_dh_server_key_exchange(rec: HandshakeRecord, p: bytestring, g: bytestring, Ys: bytestring) : bool
%{ %{
BifEvent::generate_ssl_dh_server_params(bro_analyzer(), BifEvent::generate_ssl_dh_server_params(bro_analyzer(),
@ -283,7 +319,6 @@ refine connection Handshake_Conn += {
return true; return true;
%} %}
}; };
refine typeattr ClientHello += &let { refine typeattr ClientHello += &let {
@ -373,3 +408,6 @@ refine typeattr Handshake += &let {
proc : bool = $context.connection.proc_handshake(rec.is_orig, rec.msg_type, rec.msg_length); proc : bool = $context.connection.proc_handshake(rec.is_orig, rec.msg_type, rec.msg_length);
}; };
refine typeattr SignedCertificateTimestamp += &let {
proc : bool = $context.connection.proc_signedcertificatetimestamp(rec, version, logid, timestamp, digitally_signed_algorithms, digitally_signed_signature);
};

View file

@ -485,6 +485,7 @@ type SSLExtension(rec: HandshakeRecord) = record {
# EXT_STATUS_REQUEST -> status_request: StatusRequest(rec)[] &until($element == 0 || $element != 0); # EXT_STATUS_REQUEST -> status_request: StatusRequest(rec)[] &until($element == 0 || $element != 0);
EXT_SERVER_NAME -> server_name: ServerNameExt(rec)[] &until($element == 0 || $element != 0); EXT_SERVER_NAME -> server_name: ServerNameExt(rec)[] &until($element == 0 || $element != 0);
EXT_SIGNATURE_ALGORITHMS -> signature_algorithm: SignatureAlgorithm(rec)[] &until($element == 0 || $element != 0); EXT_SIGNATURE_ALGORITHMS -> signature_algorithm: SignatureAlgorithm(rec)[] &until($element == 0 || $element != 0);
EXT_SIGNED_CERTIFICATE_TIMESTAMP -> certificate_timestamp: SignedCertificateTimestampList(rec)[] &until($element == 0 || $element != 0);
EXT_KEY_SHARE -> key_share: KeyShare(rec)[] &until($element == 0 || $element != 0); EXT_KEY_SHARE -> key_share: KeyShare(rec)[] &until($element == 0 || $element != 0);
EXT_SUPPORTED_VERSIONS -> supported_versions: SupportedVersions(rec)[] &until($element == 0 || $element != 0); EXT_SUPPORTED_VERSIONS -> supported_versions: SupportedVersions(rec)[] &until($element == 0 || $element != 0);
EXT_PSK_KEY_EXCHANGE_MODES -> psk_key_exchange_modes: PSKKeyExchangeModes(rec)[] &until($element == 0 || $element != 0); EXT_PSK_KEY_EXCHANGE_MODES -> psk_key_exchange_modes: PSKKeyExchangeModes(rec)[] &until($element == 0 || $element != 0);
@ -492,6 +493,8 @@ type SSLExtension(rec: HandshakeRecord) = record {
}; };
} &length=data_len+4 &exportsourcedata; } &length=data_len+4 &exportsourcedata;
%include tls-handshake-signed_certificate_timestamp.pac
type SupportedVersions(rec: HandshakeRecord) = record { type SupportedVersions(rec: HandshakeRecord) = record {
length: uint8; length: uint8;
versions: uint16[] &until($input.length() == 0); versions: uint16[] &until($input.length() == 0);
@ -563,11 +566,6 @@ type KeyShare(rec: HandshakeRecord) = case rec.msg_type of {
default -> other : bytestring &restofdata &transient; default -> other : bytestring &restofdata &transient;
}; };
type SignatureAndHashAlgorithm() = record {
HashAlgorithm: uint8;
SignatureAlgorithm: uint8;
}
type SignatureAlgorithm(rec: HandshakeRecord) = record { type SignatureAlgorithm(rec: HandshakeRecord) = record {
length: uint16; length: uint16;
supported_signature_algorithms: SignatureAndHashAlgorithm[] &until($input.length() == 0); supported_signature_algorithms: SignatureAndHashAlgorithm[] &until($input.length() == 0);

View file

@ -0,0 +1,28 @@
# We keep this extension separate, because it also can be included in X.509 certificates.
# If included there, it uses the exact same syntax and we just symlink it from the X.509
# file analyzer tree.
type SignatureAndHashAlgorithm() = record {
HashAlgorithm: uint8;
SignatureAlgorithm: uint8;
}
type SignedCertificateTimestampList(rec: HandshakeRecord) = record {
length: uint16;
SCTs: SignedCertificateTimestamp(rec)[] &until($input.length() == 0);
} &length=length+2;
type SignedCertificateTimestamp(rec: HandshakeRecord) = record {
# before - framing
length: uint16;
# from here: SignedCertificateTimestamp
version: uint8;
logid: bytestring &length=32;
timestamp: uint64;
extensions_length: uint16; # extensions are not actually defined yet, so we cannot parse them
extensions: bytestring &length=extensions_length;
digitally_signed_algorithms: SignatureAndHashAlgorithm;
digitally_signed_signature_length: uint16;
digitally_signed_signature: bytestring &length=digitally_signed_signature_length;
} &length=length+2;

View file

@ -55,6 +55,7 @@ int File::bof_buffer_size_idx = -1;
int File::bof_buffer_idx = -1; int File::bof_buffer_idx = -1;
int File::meta_mime_type_idx = -1; int File::meta_mime_type_idx = -1;
int File::meta_mime_types_idx = -1; int File::meta_mime_types_idx = -1;
int File::meta_inferred_idx = -1;
void File::StaticInit() void File::StaticInit()
{ {
@ -76,6 +77,7 @@ void File::StaticInit()
bof_buffer_idx = Idx("bof_buffer", fa_file_type); bof_buffer_idx = Idx("bof_buffer", fa_file_type);
meta_mime_type_idx = Idx("mime_type", fa_metadata_type); meta_mime_type_idx = Idx("mime_type", fa_metadata_type);
meta_mime_types_idx = Idx("mime_types", fa_metadata_type); meta_mime_types_idx = Idx("mime_types", fa_metadata_type);
meta_inferred_idx = Idx("inferred", fa_metadata_type);
} }
File::File(const string& file_id, const string& source_name, Connection* conn, File::File(const string& file_id, const string& source_name, Connection* conn,
@ -290,6 +292,27 @@ void File::SetReassemblyBuffer(uint64 max)
reassembly_max_buffer = max; reassembly_max_buffer = max;
} }
bool File::SetMime(const string& mime_type)
{
if ( mime_type.empty() || bof_buffer.size != 0 )
return false;
did_metadata_inference = true;
bof_buffer.full = true;
if ( ! FileEventAvailable(file_sniff) )
return false;
val_list* vl = new val_list();
vl->append(val->Ref());
RecordVal* meta = new RecordVal(fa_metadata_type);
vl->append(meta);
meta->Assign(meta_mime_type_idx, new StringVal(mime_type));
meta->Assign(meta_inferred_idx, new Val(0, TYPE_BOOL));
FileEvent(file_sniff, vl);
return true;
}
void File::InferMetadata() void File::InferMetadata()
{ {
did_metadata_inference = true; did_metadata_inference = true;

View file

@ -171,6 +171,25 @@ public:
*/ */
void FileEvent(EventHandlerPtr h, val_list* vl); void FileEvent(EventHandlerPtr h, val_list* vl);
/**
* Sets the MIME type for a file to a specific value.
*
* Setting the MIME type has to be done before the MIME type is
* inferred from the content. After a MIME type has been set once,
* it cannot be changed anymore.
*
* This function should only be called when it does not make sense
* to perform automated MIME type detections. This is e.g. the case
* in protocols where the file type is fixed in the protocol description.
* This is for example the case for TLS and X.509 certificates.
*
* @param mime_type mime type to set
* @return true if the mime type was set. False if it could not be set because
* a mime type was already set or inferred.
*/
bool SetMime(const string& mime_type);
protected: protected:
friend class Manager; friend class Manager;
friend class FileReassembler; friend class FileReassembler;
@ -319,6 +338,7 @@ protected:
static int bof_buffer_idx; static int bof_buffer_idx;
static int mime_type_idx; static int mime_type_idx;
static int mime_types_idx; static int mime_types_idx;
static int meta_inferred_idx;
static int meta_mime_type_idx; static int meta_mime_type_idx;
static int meta_mime_types_idx; static int meta_mime_types_idx;

View file

@ -110,7 +110,7 @@ void Manager::SetHandle(const string& handle)
string Manager::DataIn(const u_char* data, uint64 len, uint64 offset, string Manager::DataIn(const u_char* data, uint64 len, uint64 offset,
analyzer::Tag tag, Connection* conn, bool is_orig, analyzer::Tag tag, Connection* conn, bool is_orig,
const string& precomputed_id) const string& precomputed_id, const string& mime_type)
{ {
string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id; string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id;
File* file = GetFile(id, conn, tag, is_orig); File* file = GetFile(id, conn, tag, is_orig);
@ -118,6 +118,9 @@ string Manager::DataIn(const u_char* data, uint64 len, uint64 offset,
if ( ! file ) if ( ! file )
return ""; return "";
if ( ! mime_type.empty() )
file->SetMime(mime_type);
file->DataIn(data, len, offset); file->DataIn(data, len, offset);
if ( file->IsComplete() ) if ( file->IsComplete() )
@ -130,7 +133,8 @@ string Manager::DataIn(const u_char* data, uint64 len, uint64 offset,
} }
string Manager::DataIn(const u_char* data, uint64 len, analyzer::Tag tag, string Manager::DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
Connection* conn, bool is_orig, const string& precomputed_id) Connection* conn, bool is_orig, const string& precomputed_id,
const string& mime_type)
{ {
string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id; string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id;
// Sequential data input shouldn't be going over multiple conns, so don't // Sequential data input shouldn't be going over multiple conns, so don't
@ -140,6 +144,9 @@ string Manager::DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
if ( ! file ) if ( ! file )
return ""; return "";
if ( ! mime_type.empty() )
file->SetMime(mime_type);
file->DataIn(data, len); file->DataIn(data, len);
if ( file->IsComplete() ) if ( file->IsComplete() )

View file

@ -93,6 +93,12 @@ public:
* or false if is being sent in the opposite direction. * or false if is being sent in the opposite direction.
* @param precomputed_file_id may be set to a previous return value in order to * @param precomputed_file_id may be set to a previous return value in order to
* bypass costly file handle lookups. * bypass costly file handle lookups.
* @param mime_type may be set to the mime type of the file, if already known due
* to the protocol. This is, e.g., the case in TLS connections where X.509
* certificates are passed as files; here the type of the file is set by
* the protocol. If this parameter is given, MIME type detection will be
* disabled.
* This parameter is only used for the first bit of data for each file.
* @return a unique file ID string which, in certain contexts, may be * @return a unique file ID string which, in certain contexts, may be
* cached and passed back in to a subsequent function call in order * cached and passed back in to a subsequent function call in order
* to avoid costly file handle lookups (which have to go through * to avoid costly file handle lookups (which have to go through
@ -101,7 +107,8 @@ public:
*/ */
std::string DataIn(const u_char* data, uint64 len, uint64 offset, std::string DataIn(const u_char* data, uint64 len, uint64 offset,
analyzer::Tag tag, Connection* conn, bool is_orig, analyzer::Tag tag, Connection* conn, bool is_orig,
const std::string& precomputed_file_id = ""); const std::string& precomputed_file_id = "",
const std::string& mime_type = "");
/** /**
* Pass in sequential file data. * Pass in sequential file data.
@ -113,6 +120,12 @@ public:
* or false if is being sent in the opposite direction. * or false if is being sent in the opposite direction.
* @param precomputed_file_id may be set to a previous return value in order to * @param precomputed_file_id may be set to a previous return value in order to
* bypass costly file handle lookups. * bypass costly file handle lookups.
* @param mime_type may be set to the mime type of the file, if already known due
* to the protocol. This is, e.g., the case in TLS connections where X.509
* certificates are passed as files; here the type of the file is set by
* the protocol. If this parameter is give, mime type detection will be
* disabled.
* This parameter is only used for the first bit of data for each file.
* @return a unique file ID string which, in certain contexts, may be * @return a unique file ID string which, in certain contexts, may be
* cached and passed back in to a subsequent function call in order * cached and passed back in to a subsequent function call in order
* to avoid costly file handle lookups (which have to go through * to avoid costly file handle lookups (which have to go through
@ -121,7 +134,8 @@ public:
*/ */
std::string DataIn(const u_char* data, uint64 len, analyzer::Tag tag, std::string DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
Connection* conn, bool is_orig, Connection* conn, bool is_orig,
const std::string& precomputed_file_id = ""); const std::string& precomputed_file_id = "",
const std::string& mime_type = "");
/** /**
* Pass in sequential file data from external source (e.g. input framework). * Pass in sequential file data from external source (e.g. input framework).

View file

@ -5,6 +5,7 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}) ${CMAKE_CURRENT_BINARY_DIR})
bro_plugin_begin(Bro X509) bro_plugin_begin(Bro X509)
bro_plugin_cc(X509.cc Plugin.cc) bro_plugin_cc(X509Common.cc X509.cc OCSP.cc Plugin.cc)
bro_plugin_bif(events.bif types.bif functions.bif) bro_plugin_bif(events.bif types.bif functions.bif ocsp_events.bif)
bro_plugin_pac(x509-extension.pac x509-signed_certificate_timestamp.pac)
bro_plugin_end() bro_plugin_end()

View file

@ -0,0 +1,403 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <string>
#include "OCSP.h"
#include "X509.h"
#include "Event.h"
#include "types.bif.h"
#include "ocsp_events.bif.h"
#include "file_analysis/Manager.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include <openssl/opensslconf.h>
#include "file_analysis/analyzer/x509/X509.h"
// helper function of sk_X509_value to avoid namespace problem
// sk_X509_value(X,Y) = > SKM_sk_value(X509,X,Y)
// X509 => file_analysis::X509
X509 *helper_sk_X509_value(STACK_OF(X509) *certs, int i)
{
return sk_X509_value(certs, i);
}
using namespace file_analysis;
IMPLEMENT_SERIAL(OCSP_RESPVal, SER_OCSP_RESP_VAL);
#define OCSP_STRING_BUF_SIZE 2048
static Val* get_ocsp_type(RecordVal* args, const char* name)
{
Val* rval = args->Lookup(name);
if ( ! rval )
reporter->Error("File extraction analyzer missing arg field: %s", name);
return rval;
}
static void OCSP_RESPID_bio(OCSP_RESPID *resp_id, BIO* bio)
{
if (resp_id->type == V_OCSP_RESPID_NAME)
X509_NAME_print_ex(bio, resp_id->value.byName, 0, XN_FLAG_ONELINE);
else if (resp_id->type == V_OCSP_RESPID_KEY)
i2a_ASN1_STRING(bio, resp_id->value.byKey, V_ASN1_OCTET_STRING);
}
void ocsp_add_cert_id(OCSP_CERTID *cert_id, val_list* vl, BIO* bio)
{
char buf[OCSP_STRING_BUF_SIZE];
memset(buf, 0, sizeof(buf));
i2a_ASN1_OBJECT(bio, cert_id->hashAlgorithm->algorithm);
int len = BIO_read(bio, buf, sizeof(buf));
vl->append(new StringVal(len, buf));
BIO_reset(bio);
i2a_ASN1_STRING(bio, cert_id->issuerNameHash, V_ASN1_OCTET_STRING);
len = BIO_read(bio, buf, sizeof(buf));
vl->append(new StringVal(len, buf));
BIO_reset(bio);
i2a_ASN1_STRING(bio, cert_id->issuerKeyHash, V_ASN1_OCTET_STRING);
len = BIO_read(bio, buf, sizeof(buf));
vl->append(new StringVal(len, buf));
BIO_reset(bio);
i2a_ASN1_INTEGER(bio, cert_id->serialNumber);
vl->append(new StringVal(len, buf));
BIO_reset(bio);
}
file_analysis::Analyzer* OCSP::InstantiateRequest(RecordVal* args, File* file)
{
return new OCSP(args, file, true);
}
file_analysis::Analyzer* OCSP::InstantiateReply(RecordVal* args, File* file)
{
return new OCSP(args, file, false);
}
file_analysis::OCSP::OCSP(RecordVal* args, file_analysis::File* file, bool arg_request)
: file_analysis::X509Common::X509Common(file_mgr->GetComponentTag("OCSP"), args, file), request(arg_request)
{
}
bool file_analysis::OCSP::DeliverStream(const u_char* data, uint64 len)
{
ocsp_data.append(reinterpret_cast<const char*>(data), len);
return true;
}
bool file_analysis::OCSP::Undelivered(uint64 offset, uint64 len)
{
return false;
}
// we parse the entire OCSP response in EOF, because we just pass it on
// to OpenSSL.
bool file_analysis::OCSP::EndOfFile()
{
const unsigned char* ocsp_char = reinterpret_cast<const unsigned char*>(ocsp_data.data());
if ( request )
{
OCSP_REQUEST *req = d2i_OCSP_REQUEST(NULL, &ocsp_char, ocsp_data.size());
if (!req)
{
reporter->Weird(fmt("OPENSSL Could not parse OCSP request (fuid %s)", GetFile()->GetID().c_str()));
return false;
}
ParseRequest(req, GetFile()->GetID().c_str());
OCSP_REQUEST_free(req);
}
else
{
OCSP_RESPONSE *resp = d2i_OCSP_RESPONSE(NULL, &ocsp_char, ocsp_data.size());
if (!resp)
{
reporter->Weird(fmt("OPENSSL Could not parse OCSP response (fuid %s)", GetFile()->GetID().c_str()));
return false;
}
OCSP_RESPVal* resp_val = new OCSP_RESPVal(resp); // resp_val takes ownership
ParseResponse(resp_val, GetFile()->GetID().c_str());
Unref(resp_val);
}
return true;
}
void file_analysis::OCSP::ParseRequest(OCSP_REQUEST *req, const char* fid)
{
OCSP_REQINFO *inf = req->tbsRequest;
char buf[OCSP_STRING_BUF_SIZE]; // we need a buffer for some of the openssl functions
memset(buf, 0, sizeof(buf));
// build up our response as we go along...
val_list* vl = new val_list();
vl->append(GetFile()->GetVal()->Ref());
vl->append(new Val((uint64)ASN1_INTEGER_get(inf->version), TYPE_COUNT));
BIO *bio = BIO_new(BIO_s_mem());
if (inf->requestorName != NULL)
{
GENERAL_NAME_print(bio, inf->requestorName);
int len = BIO_read(bio, buf, sizeof(buf));
vl->append(new StringVal(len, buf));
BIO_reset(bio);
}
else
vl->append(new StringVal(0, ""));
mgr.QueueEvent(ocsp_request, vl);
int req_count = OCSP_request_onereq_count(req);
for ( int i=0; i<req_count; i++ )
{
val_list* rvl = new val_list();
rvl->append(GetFile()->GetVal()->Ref());
OCSP_ONEREQ *one_req = OCSP_request_onereq_get0(req, i);
OCSP_CERTID *cert_id = OCSP_onereq_get0_id(one_req);
ocsp_add_cert_id(cert_id, rvl, bio);
mgr.QueueEvent(ocsp_request_certificate, rvl);
}
BIO_free(bio);
}
void file_analysis::OCSP::ParseResponse(OCSP_RESPVal *resp_val, const char* fid)
{
OCSP_RESPONSE *resp = resp_val->GetResp();
OCSP_RESPBYTES *resp_bytes = resp->responseBytes;
OCSP_BASICRESP *basic_resp = nullptr;
OCSP_RESPDATA *resp_data = nullptr;
OCSP_RESPID *resp_id = nullptr;
int resp_count, num_ext = 0;
VectorVal *certs_vector = nullptr;
int len = 0;
char buf[OCSP_STRING_BUF_SIZE];
memset(buf, 0, sizeof(buf));
val_list* vl = new val_list();
vl->append(GetFile()->GetVal()->Ref());
const char *status_str = OCSP_response_status_str(OCSP_response_status(resp));
StringVal* status_val = new StringVal(strlen(status_str), status_str);
vl->append(status_val->Ref());
mgr.QueueEvent(ocsp_response_status, vl);
vl = nullptr;
if (!resp_bytes)
{
Unref(status_val);
return;
}
BIO *bio = BIO_new(BIO_s_mem());
//i2a_ASN1_OBJECT(bio, resp_bytes->responseType);
//int len = BIO_read(bio, buf, sizeof(buf));
//BIO_reset(bio);
// get the basic response
basic_resp = OCSP_response_get1_basic(resp);
if ( !basic_resp )
goto clean_up;
resp_data = basic_resp->tbsResponseData;
if ( !resp_data )
goto clean_up;
vl = new val_list();
vl->append(GetFile()->GetVal()->Ref());
vl->append(resp_val->Ref());
vl->append(status_val);
vl->append(new Val((uint64)ASN1_INTEGER_get(resp_data->version), TYPE_COUNT));
// responderID
resp_id = resp_data->responderId;
OCSP_RESPID_bio(resp_id, bio);
len = BIO_read(bio, buf, sizeof(buf));
vl->append(new StringVal(len, buf));
BIO_reset(bio);
// producedAt
vl->append(new Val(GetTimeFromAsn1(resp_data->producedAt, fid, reporter), TYPE_TIME));
// responses
resp_count = sk_OCSP_SINGLERESP_num(resp_data->responses);
for ( int i=0; i<resp_count; i++ )
{
OCSP_SINGLERESP *single_resp = sk_OCSP_SINGLERESP_value(resp_data->responses, i);
if ( !single_resp )
continue;
val_list* rvl = new val_list();
rvl->append(GetFile()->GetVal()->Ref());
// cert id
OCSP_CERTID *cert_id = single_resp->certId;
ocsp_add_cert_id(cert_id, rvl, bio);
BIO_reset(bio);
// certStatus
OCSP_CERTSTATUS *cert_status = single_resp->certStatus;
const char* cert_status_str = OCSP_cert_status_str(cert_status->type);
rvl->append(new StringVal(strlen(cert_status_str), cert_status_str));
// revocation time and reason if revoked
if ( cert_status->type == V_OCSP_CERTSTATUS_REVOKED )
{
OCSP_REVOKEDINFO *revoked_info = cert_status->value.revoked;
rvl->append(new Val(GetTimeFromAsn1(revoked_info->revocationTime, fid, reporter), TYPE_TIME));
if ( revoked_info->revocationReason )
{
const char* revoke_reason = OCSP_crl_reason_str(ASN1_ENUMERATED_get(revoked_info->revocationReason));
rvl->append(new StringVal(strlen(revoke_reason), revoke_reason));
}
else
rvl->append(new StringVal(0, ""));
}
else
{
rvl->append(new Val(0, TYPE_TIME));
rvl->append(new StringVal(0, ""));
}
rvl->append(new Val(GetTimeFromAsn1(single_resp->thisUpdate, fid, reporter), TYPE_TIME));
if ( single_resp->nextUpdate )
rvl->append(new Val(GetTimeFromAsn1(single_resp->nextUpdate, fid, reporter), TYPE_TIME));
else
rvl->append(new Val(0, TYPE_TIME));
mgr.QueueEvent(ocsp_response_certificate, rvl);
num_ext = OCSP_SINGLERESP_get_ext_count(single_resp);
for ( int k = 0; k < num_ext; ++k )
{
X509_EXTENSION* ex = OCSP_SINGLERESP_get_ext(single_resp, k);
if ( ! ex )
continue;
ParseExtension(ex, ocsp_extension, false);
}
}
i2a_ASN1_OBJECT(bio, basic_resp->signatureAlgorithm->algorithm);
len = BIO_read(bio, buf, sizeof(buf));
vl->append(new StringVal(len, buf));
BIO_reset(bio);
//i2a_ASN1_OBJECT(bio, basic_resp->signature);
//len = BIO_read(bio, buf, sizeof(buf));
//ocsp_resp_record->Assign(7, new StringVal(len, buf));
//BIO_reset(bio);
certs_vector = new VectorVal(internal_type("x509_opaque_vector")->AsVectorType());
vl->append(certs_vector);
if ( basic_resp->certs )
{
int num_certs = sk_X509_num(basic_resp->certs);
for ( int i=0; i<num_certs; i++ )
{
::X509 *this_cert = X509_dup(helper_sk_X509_value(basic_resp->certs, i));
//::X509 *this_cert = X509_dup(sk_X509_value(basic_resp->certs, i));
if (this_cert)
certs_vector->Assign(i, new file_analysis::X509Val(this_cert));
else
reporter->Weird("OpenSSL returned null certificate");
}
}
mgr.QueueEvent(ocsp_response_bytes, vl);
// ok, now that we are done with the actual certificate - let's parse extensions :)
num_ext = OCSP_BASICRESP_get_ext_count(basic_resp);
for ( int k = 0; k < num_ext; ++k )
{
X509_EXTENSION* ex = OCSP_BASICRESP_get_ext(basic_resp, k);
if ( ! ex )
continue;
ParseExtension(ex, ocsp_extension, true);
}
clean_up:
if (basic_resp)
OCSP_BASICRESP_free(basic_resp);
BIO_free(bio);
}
void file_analysis::OCSP::ParseExtensionsSpecific(X509_EXTENSION* ex, bool global, ASN1_OBJECT* ext_asn, const char* oid)
{
#ifdef NID_ct_cert_scts
if ( OBJ_obj2nid(ext_asn) == NID_ct_cert_scts )
#else
if ( strcmp(oid, "1.3.6.1.4.1.11129.2.4.5") == 0 )
#endif
ParseSignedCertificateTimestamps(ex);
}
OCSP_RESPVal::OCSP_RESPVal(OCSP_RESPONSE* arg_ocsp_resp) : OpaqueVal(ocsp_resp_opaque_type)
{
ocsp_resp = arg_ocsp_resp;
}
OCSP_RESPVal::OCSP_RESPVal() : OpaqueVal(ocsp_resp_opaque_type)
{
ocsp_resp = nullptr;
}
OCSP_RESPVal::~OCSP_RESPVal()
{
if (ocsp_resp)
OCSP_RESPONSE_free(ocsp_resp);
}
OCSP_RESPONSE* OCSP_RESPVal::GetResp() const
{
return ocsp_resp;
}
bool OCSP_RESPVal::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_OCSP_RESP_VAL, OpaqueVal);
unsigned char *buf = nullptr;
int length = i2d_OCSP_RESPONSE(ocsp_resp, &buf);
if ( length < 0 )
return false;
bool res = SERIALIZE_STR(reinterpret_cast<const char*>(buf), length);
OPENSSL_free(buf);
return res;
}
bool OCSP_RESPVal::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(OpaqueVal)
int length;
unsigned char *ocsp_resp_buf, *opensslbuf;
if ( ! UNSERIALIZE_STR(reinterpret_cast<char **>(&ocsp_resp_buf), &length) )
return false;
opensslbuf = ocsp_resp_buf; // OpenSSL likes to shift pointers around. really.
ocsp_resp = d2i_OCSP_RESPONSE(nullptr, const_cast<const unsigned char**>(&opensslbuf), length);
delete [] ocsp_resp_buf;
if ( ! ocsp_resp )
return false;
return true;
}

View file

@ -0,0 +1,54 @@
// See the file "COPYING" in the main distribution directory for copyright.
#ifndef FILE_ANALYSIS_OCSP_H
#define FILE_ANALYSIS_OCSP_H
#include <string>
#include "Val.h"
#include "../File.h"
#include "Analyzer.h"
#include "X509Common.h"
#include <openssl/ocsp.h>
namespace file_analysis {
class OCSP_RESPVal;
class OCSP : public file_analysis::X509Common {
public:
bool DeliverStream(const u_char* data, uint64 len) override;
bool Undelivered(uint64 offset, uint64 len) override;
bool EndOfFile() override;
static file_analysis::Analyzer* InstantiateRequest(RecordVal* args, File* file);
static file_analysis::Analyzer* InstantiateReply(RecordVal* args, File* file);
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 ParseExtensionsSpecific(X509_EXTENSION* ex, bool, ASN1_OBJECT*, const char*) override;
std::string ocsp_data;
bool request = false; // true if ocsp request, false if reply
};
class OCSP_RESPVal: public OpaqueVal {
public:
explicit OCSP_RESPVal(OCSP_RESPONSE *);
~OCSP_RESPVal();
OCSP_RESPONSE *GetResp() const;
protected:
OCSP_RESPVal();
private:
OCSP_RESPONSE *ocsp_resp;
DECLARE_SERIAL(OCSP_RESPVal);
};
}
#endif

View file

@ -4,6 +4,7 @@
#include "plugin/Plugin.h" #include "plugin/Plugin.h"
#include "X509.h" #include "X509.h"
#include "OCSP.h"
namespace plugin { namespace plugin {
namespace Bro_X509 { namespace Bro_X509 {
@ -13,10 +14,12 @@ public:
plugin::Configuration Configure() plugin::Configuration Configure()
{ {
AddComponent(new ::file_analysis::Component("X509", ::file_analysis::X509::Instantiate)); AddComponent(new ::file_analysis::Component("X509", ::file_analysis::X509::Instantiate));
AddComponent(new ::file_analysis::Component("OCSP_REQUEST", ::file_analysis::OCSP::InstantiateRequest));
AddComponent(new ::file_analysis::Component("OCSP_REPLY", ::file_analysis::OCSP::InstantiateReply));
plugin::Configuration config; plugin::Configuration config;
config.name = "Bro::X509"; config.name = "Bro::X509";
config.description = "X509 analyzer"; config.description = "X509 and OCSP analyzer";
return config; return config;
} }
} plugin; } plugin;

View file

@ -21,7 +21,7 @@ using namespace file_analysis;
IMPLEMENT_SERIAL(X509Val, SER_X509_VAL); IMPLEMENT_SERIAL(X509Val, SER_X509_VAL);
file_analysis::X509::X509(RecordVal* args, file_analysis::File* file) file_analysis::X509::X509(RecordVal* args, file_analysis::File* file)
: file_analysis::Analyzer(file_mgr->GetComponentTag("X509"), args, file) : file_analysis::X509Common::X509Common(file_mgr->GetComponentTag("X509"), args, file)
{ {
cert_data.clear(); cert_data.clear();
} }
@ -72,7 +72,7 @@ bool file_analysis::X509::EndOfFile()
if ( ! ex ) if ( ! ex )
continue; continue;
ParseExtension(ex); ParseExtension(ex, x509_extension, false);
} }
// X509_free(ssl_cert); We do _not_ free the certificate here. It is refcounted // X509_free(ssl_cert); We do _not_ free the certificate here. It is refcounted
@ -133,8 +133,8 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, const char*
pX509Cert->Assign(3, new StringVal(len, buf)); pX509Cert->Assign(3, new StringVal(len, buf));
BIO_free(bio); BIO_free(bio);
pX509Cert->Assign(5, new Val(GetTimeFromAsn1(X509_get_notBefore(ssl_cert), fid), TYPE_TIME)); 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), TYPE_TIME)); pX509Cert->Assign(6, new Val(GetTimeFromAsn1(X509_get_notAfter(ssl_cert), fid, reporter), TYPE_TIME));
// we only read 255 bytes because byte 256 is always 0. // we only read 255 bytes because byte 256 is always 0.
// if the string is longer than 255, that will be our null-termination, // if the string is longer than 255, that will be our null-termination,
@ -205,101 +205,6 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, const char*
return pX509Cert; return pX509Cert;
} }
StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio)
{
BIO_flush(bio);
ERR_clear_error();
int length = BIO_pending(bio);
if ( ERR_peek_error() != 0 )
{
char tmp[120];
ERR_error_string_n(ERR_get_error(), tmp, sizeof(tmp));
reporter->Weird(fmt("X509::GetExtensionFromBIO: %s", tmp));
BIO_free_all(bio);
return 0;
}
if ( length == 0 )
{
BIO_free_all(bio);
return new StringVal("");
}
char* buffer = (char*) malloc(length);
if ( ! buffer )
{
// Just emit an error here and try to continue instead of aborting
// because it's unclear the length value is very reliable.
reporter->Error("X509::GetExtensionFromBIO malloc(%d) failed", length);
BIO_free_all(bio);
return 0;
}
BIO_read(bio, (void*) buffer, length);
StringVal* ext_val = new StringVal(length, buffer);
free(buffer);
BIO_free_all(bio);
return ext_val;
}
void file_analysis::X509::ParseExtension(X509_EXTENSION* ex)
{
char name[256];
char oid[256];
ASN1_OBJECT* ext_asn = X509_EXTENSION_get_object(ex);
const char* short_name = OBJ_nid2sn(OBJ_obj2nid(ext_asn));
OBJ_obj2txt(name, 255, ext_asn, 0);
OBJ_obj2txt(oid, 255, ext_asn, 1);
int critical = 0;
if ( X509_EXTENSION_get_critical(ex) != 0 )
critical = 1;
BIO *bio = BIO_new(BIO_s_mem());
if( ! X509V3_EXT_print(bio, ex, 0, 0))
M_ASN1_OCTET_STRING_print(bio,ex->value);
StringVal* ext_val = GetExtensionFromBIO(bio);
if ( ! ext_val )
ext_val = new StringVal(0, "");
RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension);
pX509Ext->Assign(0, new StringVal(name));
if ( short_name and strlen(short_name) > 0 )
pX509Ext->Assign(1, new StringVal(short_name));
pX509Ext->Assign(2, new StringVal(oid));
pX509Ext->Assign(3, new Val(critical, TYPE_BOOL));
pX509Ext->Assign(4, ext_val);
// send off generic extension event
//
// and then look if we have a specialized event for the extension we just
// parsed. And if we have it, we send the specialized event on top of the
// generic event that we just had. I know, that is... kind of not nice,
// but I am not sure if there is a better way to do it...
val_list* vl = new val_list();
vl->append(GetFile()->GetVal()->Ref());
vl->append(pX509Ext);
mgr.QueueEvent(x509_extension, vl);
// look if we have a specialized handler for this event...
if ( OBJ_obj2nid(ext_asn) == NID_basic_constraints )
ParseBasicConstraints(ex);
else if ( OBJ_obj2nid(ext_asn) == NID_subject_alt_name )
ParseSAN(ex);
}
void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex) void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
{ {
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_basic_constraints); assert(OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_basic_constraints);
@ -326,6 +231,23 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
reporter->Weird(fmt("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str())); reporter->Weird(fmt("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str()));
} }
void file_analysis::X509::ParseExtensionsSpecific(X509_EXTENSION* ex, bool global, ASN1_OBJECT* ext_asn, const char* oid)
{
// look if we have a specialized handler for this event...
if ( OBJ_obj2nid(ext_asn) == NID_basic_constraints )
ParseBasicConstraints(ex);
else if ( OBJ_obj2nid(ext_asn) == NID_subject_alt_name )
ParseSAN(ex);
#ifdef NID_ct_cert_scts
else if ( OBJ_obj2nid(ext_asn) == NID_ct_precert_scts )
#else
else if ( strcmp(oid, "1.3.6.1.4.1.11129.2.4.2") == 0 )
#endif
ParseSignedCertificateTimestamps(ex);
}
void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) void file_analysis::X509::ParseSAN(X509_EXTENSION* ext)
{ {
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_subject_alt_name); assert(OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_subject_alt_name);
@ -517,164 +439,6 @@ unsigned int file_analysis::X509::KeyLength(EVP_PKEY *key)
reporter->InternalError("cannot be reached"); reporter->InternalError("cannot be reached");
} }
double file_analysis::X509::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid)
{
const char *fid = arg_fid ? arg_fid : "";
time_t lResult = 0;
char lBuffer[26];
char* pBuffer = lBuffer;
const char *pString = (const char *) atime->data;
unsigned int remaining = atime->length;
if ( atime->type == V_ASN1_UTCTIME )
{
if ( remaining < 11 || remaining > 17 )
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- UTCTime has wrong length", fid));
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));
return 0;
}
// year is first two digits in YY format. Buffer expects YYYY format.
if ( pString[0] < '5' ) // RFC 2459 4.1.2.5.1
{
*(pBuffer++) = '2';
*(pBuffer++) = '0';
}
else
{
*(pBuffer++) = '1';
*(pBuffer++) = '9';
}
memcpy(pBuffer, pString, 10);
pBuffer += 10;
pString += 10;
remaining -= 10;
}
else if ( atime->type == V_ASN1_GENERALIZEDTIME )
{
// generalized time. We apparently ignore the YYYYMMDDHH case
// for now and assume we always have minutes and seconds.
// This should be ok because it is specified as a requirement in RFC 2459 4.1.2.5.2
if ( remaining < 12 || remaining > 23 )
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- Generalized time has wrong length", fid));
return 0;
}
memcpy(pBuffer, pString, 12);
pBuffer += 12;
pString += 12;
remaining -= 12;
}
else
{
reporter->Weird(fmt("Invalid time type in X509 certificate (fuid %s)", fid));
return 0;
}
if ( (remaining == 0) || (*pString == 'Z') || (*pString == '-') || (*pString == '+') )
{
*(pBuffer++) = '0';
*(pBuffer++) = '0';
}
else if ( remaining >= 2 )
{
*(pBuffer++) = *(pString++);
*(pBuffer++) = *(pString++);
remaining -= 2;
// Skip any fractional seconds...
if ( (remaining > 0) && (*pString == '.') )
{
pString++;
remaining--;
while ( (remaining > 0) && (*pString >= '0') && (*pString <= '9') )
{
pString++;
remaining--;
}
}
}
else
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- additional char after time", fid));
return 0;
}
*(pBuffer++) = 'Z';
*(pBuffer++) = '\0';
time_t lSecondsFromUTC;
if ( remaining == 0 || *pString == 'Z' )
lSecondsFromUTC = 0;
else
{
if ( remaining < 5 )
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- not enough bytes remaining for offset", fid));
return 0;
}
if ((*pString != '+') && (*pString != '-'))
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- unknown offset type", fid));
return 0;
}
lSecondsFromUTC = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
lSecondsFromUTC += (pString[3] - '0') * 10 + (pString[4] - '0');
if (*pString == '-')
lSecondsFromUTC = -lSecondsFromUTC;
}
tm lTime;
lTime.tm_sec = ((lBuffer[12] - '0') * 10) + (lBuffer[13] - '0');
lTime.tm_min = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
lTime.tm_hour = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
lTime.tm_mday = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
lTime.tm_mon = (((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0')) - 1;
lTime.tm_year = (lBuffer[0] - '0') * 1000 + (lBuffer[1] - '0') * 100 + ((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0');
if ( lTime.tm_year > 1900)
lTime.tm_year -= 1900;
lTime.tm_wday = 0;
lTime.tm_yday = 0;
lTime.tm_isdst = 0; // No DST adjustment requested
lResult = mktime(&lTime);
if ( lResult )
{
if ( lTime.tm_isdst != 0 )
lResult -= 3600; // mktime may adjust for DST (OS dependent)
lResult += lSecondsFromUTC;
}
else
lResult = 0;
return lResult;
}
X509Val::X509Val(::X509* arg_certificate) : OpaqueVal(x509_opaque_type) X509Val::X509Val(::X509* arg_certificate) : OpaqueVal(x509_opaque_type)
{ {
certificate = arg_certificate; certificate = arg_certificate;

View file

@ -6,21 +6,18 @@
#include <string> #include <string>
#include "Val.h" #include "Val.h"
#include "../File.h" #include "X509Common.h"
#include "Analyzer.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
namespace file_analysis { namespace file_analysis {
class X509Val; class X509Val;
class X509 : public file_analysis::Analyzer { class X509 : public file_analysis::X509Common {
public: public:
virtual bool DeliverStream(const u_char* data, uint64 len); bool DeliverStream(const u_char* data, uint64 len) override;
virtual bool Undelivered(uint64 offset, uint64 len); bool Undelivered(uint64 offset, uint64 len) override;
virtual bool EndOfFile(); bool EndOfFile() override;
/** /**
* Converts an X509 certificate into a \c X509::Certificate record * Converts an X509 certificate into a \c X509::Certificate record
@ -40,29 +37,17 @@ public:
static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file) static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file)
{ return new X509(args, file); } { return new X509(args, file); }
/**
* Retrieve an X509 extension value from an OpenSSL BIO to which it was
* written.
*
* @param bio the OpenSSL BIO to read. It will be freed by the function,
* including when an error occurs.
*
* @return The X509 extension value.
*/
static StringVal* GetExtensionFromBIO(BIO* bio);
protected: protected:
X509(RecordVal* args, File* file); X509(RecordVal* args, File* file);
private: private:
void ParseExtension(X509_EXTENSION* ex);
void ParseBasicConstraints(X509_EXTENSION* ex); void ParseBasicConstraints(X509_EXTENSION* ex);
void ParseSAN(X509_EXTENSION* ex); void ParseSAN(X509_EXTENSION* ex);
void ParseExtensionsSpecific(X509_EXTENSION* ex, bool, ASN1_OBJECT*, const char*) override;
std::string cert_data; std::string cert_data;
// Helpers for ParseCertificate. // Helpers for ParseCertificate.
static double GetTimeFromAsn1(const ASN1_TIME * atime, const char* fid);
static StringVal* KeyCurve(EVP_PKEY *key); static StringVal* KeyCurve(EVP_PKEY *key);
static unsigned int KeyLength(EVP_PKEY *key); static unsigned int KeyLength(EVP_PKEY *key);
}; };

View file

@ -0,0 +1,316 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "X509Common.h"
#include "x509-extension_pac.h"
#include "events.bif.h"
#include "ocsp_events.bif.h"
#include "types.bif.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
using namespace file_analysis;
X509Common::X509Common(file_analysis::Tag arg_tag, RecordVal* arg_args, File* arg_file)
: file_analysis::Analyzer(arg_tag, arg_args, arg_file)
{
}
double X509Common::GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid, Reporter* reporter)
{
const char *fid = arg_fid ? arg_fid : "";
time_t lResult = 0;
char lBuffer[26];
char* pBuffer = lBuffer;
const char *pString = (const char *) atime->data;
unsigned int remaining = atime->length;
if ( atime->type == V_ASN1_UTCTIME )
{
if ( remaining < 11 || remaining > 17 )
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- UTCTime has wrong length", fid));
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));
return 0;
}
// year is first two digits in YY format. Buffer expects YYYY format.
if ( pString[0] < '5' ) // RFC 2459 4.1.2.5.1
{
*(pBuffer++) = '2';
*(pBuffer++) = '0';
}
else
{
*(pBuffer++) = '1';
*(pBuffer++) = '9';
}
memcpy(pBuffer, pString, 10);
pBuffer += 10;
pString += 10;
remaining -= 10;
}
else if ( atime->type == V_ASN1_GENERALIZEDTIME )
{
// generalized time. We apparently ignore the YYYYMMDDHH case
// for now and assume we always have minutes and seconds.
// This should be ok because it is specified as a requirement in RFC 2459 4.1.2.5.2
if ( remaining < 12 || remaining > 23 )
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- Generalized time has wrong length", fid));
return 0;
}
memcpy(pBuffer, pString, 12);
pBuffer += 12;
pString += 12;
remaining -= 12;
}
else
{
reporter->Weird(fmt("Invalid time type in X509 certificate (fuid %s)", fid));
return 0;
}
if ( (remaining == 0) || (*pString == 'Z') || (*pString == '-') || (*pString == '+') )
{
*(pBuffer++) = '0';
*(pBuffer++) = '0';
}
else if ( remaining >= 2 )
{
*(pBuffer++) = *(pString++);
*(pBuffer++) = *(pString++);
remaining -= 2;
// Skip any fractional seconds...
if ( (remaining > 0) && (*pString == '.') )
{
pString++;
remaining--;
while ( (remaining > 0) && (*pString >= '0') && (*pString <= '9') )
{
pString++;
remaining--;
}
}
}
else
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- additional char after time", fid));
return 0;
}
*(pBuffer++) = 'Z';
*(pBuffer++) = '\0';
time_t lSecondsFromUTC;
if ( remaining == 0 || *pString == 'Z' )
lSecondsFromUTC = 0;
else
{
if ( remaining < 5 )
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- not enough bytes remaining for offset", fid));
return 0;
}
if ((*pString != '+') && (*pString != '-'))
{
reporter->Weird(fmt("Could not parse time in X509 certificate (fuid %s) -- unknown offset type", fid));
return 0;
}
lSecondsFromUTC = ((pString[1] - '0') * 10 + (pString[2] - '0')) * 60;
lSecondsFromUTC += (pString[3] - '0') * 10 + (pString[4] - '0');
if (*pString == '-')
lSecondsFromUTC = -lSecondsFromUTC;
}
tm lTime;
lTime.tm_sec = ((lBuffer[12] - '0') * 10) + (lBuffer[13] - '0');
lTime.tm_min = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
lTime.tm_hour = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
lTime.tm_mday = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
lTime.tm_mon = (((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0')) - 1;
lTime.tm_year = (lBuffer[0] - '0') * 1000 + (lBuffer[1] - '0') * 100 + ((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0');
if ( lTime.tm_year > 1900)
lTime.tm_year -= 1900;
lTime.tm_wday = 0;
lTime.tm_yday = 0;
lTime.tm_isdst = 0; // No DST adjustment requested
lResult = mktime(&lTime);
if ( lResult )
{
if ( lTime.tm_isdst != 0 )
lResult -= 3600; // mktime may adjust for DST (OS dependent)
lResult += lSecondsFromUTC;
}
else
lResult = 0;
return lResult;
}
void file_analysis::X509Common::ParseSignedCertificateTimestamps(X509_EXTENSION* ext)
{
// Ok, signed certificate timestamps are a bit of an odd case out; we don't
// want to use the (basically nonexistant) OpenSSL functionality to parse them.
// Instead we have our own, self-written binpac parser to parse just them,
// which we will initialize here and tear down immediately again.
ASN1_OCTET_STRING* ext_val = X509_EXTENSION_get_data(ext);
// the octet string of the extension contains the octet string which in turn
// contains the SCT. Obviously.
unsigned char* ext_val_copy = (unsigned char*) OPENSSL_malloc(ext_val->length);
unsigned char* ext_val_second_pointer = ext_val_copy;
memcpy(ext_val_copy, ext_val->data, ext_val->length);
ASN1_OCTET_STRING* inner = d2i_ASN1_OCTET_STRING(NULL, (const unsigned char**) &ext_val_copy, ext_val->length);
if ( !inner )
{
reporter->Error("X509::ParseSignedCertificateTimestamps could not parse inner octet string");
return;
}
binpac::X509Extension::MockConnection* conn = new binpac::X509Extension::MockConnection(this);
binpac::X509Extension::SignedCertTimestampExt* interp = new binpac::X509Extension::SignedCertTimestampExt(conn);
try
{
interp->NewData(inner->data, inner->data + inner->length);
}
catch( const binpac::Exception& e )
{
// throw a warning or sth
reporter->Error("X509::ParseSignedCertificateTimestamps could not parse SCT");
}
M_ASN1_OCTET_STRING_free(inner);
OPENSSL_free(ext_val_second_pointer);
interp->FlowEOF();
delete interp;
delete conn;
}
void file_analysis::X509Common::ParseExtension(X509_EXTENSION* ex, EventHandlerPtr h, bool global)
{
char name[256];
char oid[256];
ASN1_OBJECT* ext_asn = X509_EXTENSION_get_object(ex);
const char* short_name = OBJ_nid2sn(OBJ_obj2nid(ext_asn));
OBJ_obj2txt(name, 255, ext_asn, 0);
OBJ_obj2txt(oid, 255, ext_asn, 1);
int critical = 0;
if ( X509_EXTENSION_get_critical(ex) != 0 )
critical = 1;
BIO *bio = BIO_new(BIO_s_mem());
if( ! X509V3_EXT_print(bio, ex, 0, 0))
M_ASN1_OCTET_STRING_print(bio,ex->value);
StringVal* ext_val = GetExtensionFromBIO(bio);
if ( ! ext_val )
ext_val = new StringVal(0, "");
RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension);
pX509Ext->Assign(0, new StringVal(name));
if ( short_name and strlen(short_name) > 0 )
pX509Ext->Assign(1, new StringVal(short_name));
pX509Ext->Assign(2, new StringVal(oid));
pX509Ext->Assign(3, new Val(critical, TYPE_BOOL));
pX509Ext->Assign(4, ext_val);
// send off generic extension event
//
// and then look if we have a specialized event for the extension we just
// parsed. And if we have it, we send the specialized event on top of the
// generic event that we just had. I know, that is... kind of not nice,
// but I am not sure if there is a better way to do it...
val_list* vl = new val_list();
vl->append(GetFile()->GetVal()->Ref());
vl->append(pX509Ext);
if ( h == ocsp_extension )
vl->append(new Val(global ? 1 : 0, TYPE_BOOL));
mgr.QueueEvent(h, vl);
// let individual analyzers parse more.
ParseExtensionsSpecific(ex, global, ext_asn, oid);
}
StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio)
{
BIO_flush(bio);
ERR_clear_error();
int length = BIO_pending(bio);
if ( ERR_peek_error() != 0 )
{
char tmp[120];
ERR_error_string_n(ERR_get_error(), tmp, sizeof(tmp));
reporter->Weird(fmt("X509::GetExtensionFromBIO: %s", tmp));
BIO_free_all(bio);
return 0;
}
if ( length == 0 )
{
BIO_free_all(bio);
return new StringVal("");
}
char* buffer = (char*) malloc(length);
if ( ! buffer )
{
// Just emit an error here and try to continue instead of aborting
// because it's unclear the length value is very reliable.
reporter->Error("X509::GetExtensionFromBIO malloc(%d) failed", length);
BIO_free_all(bio);
return 0;
}
BIO_read(bio, (void*) buffer, length);
StringVal* ext_val = new StringVal(length, buffer);
free(buffer);
BIO_free_all(bio);
return ext_val;
}

View file

@ -0,0 +1,44 @@
// See the file "COPYING" in the main distribution directory for copyright.
// Common base class for the X509 and OCSP analyzer, which share a fair amount of
// code
#ifndef FILE_ANALYSIS_X509_COMMON
#define FILE_ANALYSIS_X509_COMMON
#include "../File.h"
#include "Analyzer.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
namespace file_analysis {
class X509Common : public file_analysis::Analyzer {
public:
virtual ~X509Common() {};
/**
* Retrieve an X509 extension value from an OpenSSL BIO to which it was
* written.
*
* @param bio the OpenSSL BIO to read. It will be freed by the function,
* including when an error occurs.
*
* @return The X509 extension value.
*/
static StringVal* GetExtensionFromBIO(BIO* bio);
static double GetTimeFromAsn1(const ASN1_TIME* atime, const char* arg_fid, Reporter* reporter);
protected:
X509Common(file_analysis::Tag arg_tag, RecordVal* arg_args, File* arg_file);
void ParseExtension(X509_EXTENSION* ex, EventHandlerPtr h, bool global);
void ParseSignedCertificateTimestamps(X509_EXTENSION* ext);
virtual void ParseExtensionsSpecific(X509_EXTENSION* ex, bool, ASN1_OBJECT*, const char*) = 0;
};
}
#endif /* FILE_ANALYSIS_X509_COMMON */

View file

@ -13,7 +13,7 @@
## ##
## .. bro:see:: x509_extension x509_ext_basic_constraints ## .. bro:see:: x509_extension x509_ext_basic_constraints
## x509_ext_subject_alternative_name x509_parse x509_verify ## x509_ext_subject_alternative_name x509_parse x509_verify
## x509_get_certificate_string ## x509_get_certificate_string x509_ocsp_ext_signed_certificate_timestamp
event x509_certificate%(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate%); event x509_certificate%(f: fa_file, cert_ref: opaque of x509, cert: X509::Certificate%);
## Generated for X509 extensions seen in a certificate. ## Generated for X509 extensions seen in a certificate.
@ -27,7 +27,7 @@ event x509_certificate%(f: fa_file, cert_ref: opaque of x509, cert: X509::Certif
## ##
## .. bro:see:: x509_certificate x509_ext_basic_constraints ## .. bro:see:: x509_certificate x509_ext_basic_constraints
## x509_ext_subject_alternative_name x509_parse x509_verify ## x509_ext_subject_alternative_name x509_parse x509_verify
## x509_get_certificate_string ## x509_get_certificate_string x509_ocsp_ext_signed_certificate_timestamp
event x509_extension%(f: fa_file, ext: X509::Extension%); event x509_extension%(f: fa_file, ext: X509::Extension%);
## Generated for the X509 basic constraints extension seen in a certificate. ## Generated for the X509 basic constraints extension seen in a certificate.
@ -39,7 +39,7 @@ event x509_extension%(f: fa_file, ext: X509::Extension%);
## ##
## .. bro:see:: x509_certificate x509_extension ## .. bro:see:: x509_certificate x509_extension
## x509_ext_subject_alternative_name x509_parse x509_verify ## x509_ext_subject_alternative_name x509_parse x509_verify
## x509_get_certificate_string ## x509_get_certificate_string x509_ocsp_ext_signed_certificate_timestamp
event x509_ext_basic_constraints%(f: fa_file, ext: X509::BasicConstraints%); event x509_ext_basic_constraints%(f: fa_file, ext: X509::BasicConstraints%);
## Generated for the X509 subject alternative name extension seen in a certificate. ## Generated for the X509 subject alternative name extension seen in a certificate.
@ -52,6 +52,34 @@ event x509_ext_basic_constraints%(f: fa_file, ext: X509::BasicConstraints%);
## ext: The parsed subject alternative name extension. ## ext: The parsed subject alternative name extension.
## ##
## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints ## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints
## x509_parse x509_verify ## x509_parse x509_verify x509_ocsp_ext_signed_certificate_timestamp
## x509_get_certificate_string ## x509_get_certificate_string
event x509_ext_subject_alternative_name%(f: fa_file, ext: X509::SubjectAlternativeName%); event x509_ext_subject_alternative_name%(f: fa_file, ext: X509::SubjectAlternativeName%);
## Generated for the signed_certificate_timestamp X509 extension as defined in
## :rfc:`6962`. The extension is used to transmit signed proofs that are
## used for Certificate Transparency. Raised when the extension is encountered
## in an X.509 certificate or in an OCSP reply.
##
## f: The file.
##
## version: the version of the protocol to which the SCT conforms. Always
## should be 0 (representing version 1)
##
## logid: 32 bit key id
##
## timestamp: the NTP Time when the entry was logged measured since
## the epoch, ignoring leap seconds, in milliseconds.
##
## signature_and_hashalgorithm: signature and hash algorithm used for the
## digitally_signed struct
##
## signature: signature part of the digitally_signed struct
##
## .. bro:see:: ssl_extension_signed_certificate_timestamp x509_extension x509_ext_basic_constraints
## x509_parse x509_verify x509_ext_subject_alternative_name
## x509_get_certificate_string ssl_extension_signed_certificate_timestamp
## sct_verify ocsp_request ocsp_request_certificate ocsp_response_status
## ocsp_response_bytes ocsp_response_certificate
## x509_ocsp_ext_signed_certificate_timestamp
event x509_ocsp_ext_signed_certificate_timestamp%(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string%);

View file

@ -1,6 +1,7 @@
%%{ %%{
#include "file_analysis/analyzer/x509/X509.h" #include "file_analysis/analyzer/x509/X509.h"
#include "types.bif.h" #include "types.bif.h"
#include "net_util.h"
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
@ -139,6 +140,35 @@ X509* x509_get_ocsp_signer(STACK_OF(X509) *certs, OCSP_RESPID *rid)
return 0; return 0;
} }
// Convert hash algorithm registry numbers to the OpenSSL EVP_MD.
// Mapping at https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
const EVP_MD* hash_to_evp(int hash)
{
switch ( hash )
{
case 1:
return EVP_md5();
break;
case 2:
return EVP_sha1();
break;
case 3:
return EVP_sha224();
break;
case 4:
return EVP_sha256();
break;
case 5:
return EVP_sha384();
break;
case 6:
return EVP_sha512();
break;
default:
return nullptr;
}
}
%%} %%}
## Parses a certificate into an X509::Certificate structure. ## Parses a certificate into an X509::Certificate structure.
@ -455,7 +485,7 @@ x509_ocsp_cleanup:
## ##
## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints ## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints
## x509_ext_subject_alternative_name x509_parse ## x509_ext_subject_alternative_name x509_parse
## x509_get_certificate_string x509_ocsp_verify ## x509_get_certificate_string x509_ocsp_verify sct_verify
function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result
%{ %{
X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal()); X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal());
@ -542,3 +572,297 @@ x509_verify_chainerror:
return rrecord; return rrecord;
%} %}
## Verifies a Signed Certificate Timestamp as used for Certificate Transparency.
## See RFC6962 for more details.
##
## cert: Certificate against which the SCT should be validated.
##
## logid: Log id of the SCT.
##
## log_key: Public key of the Log that issued the SCT proof.
##
## timestamp: Timestamp at which the proof was generated.
##
## hash_algorithm: Hash algorithm that was used for the SCT proof.
##
## issuer_key_hash: The SHA-256 hash of the certificate issuer's public key.
## This only has to be provided if the SCT was encountered in an X.509
## certificate extension; in that case, it is necessary for validation.
##
## Returns: T if the validation could be performed succesfully, F otherwhise.
##
## .. bro:see:: ssl_extension_signed_certificate_timestamp
## x509_ocsp_ext_signed_certificate_timestamp
## x509_verify
function sct_verify%(cert: opaque of x509, logid: string, log_key: string, signature: string, timestamp: count, hash_algorithm: count, issuer_key_hash: string &default=""%): bool
%{
assert(cert);
file_analysis::X509Val* h = (file_analysis::X509Val*) cert;
X509* x = ((file_analysis::X509Val*) h)->GetCertificate();
assert(sizeof(timestamp) >= 8);
uint64_t timestamp_network = htonll(timestamp);
bool precert = issuer_key_hash->Len() > 0;
if ( precert && issuer_key_hash->Len() != 32)
{
reporter->Error("Invalid issuer_key_hash length");
return new Val(0, TYPE_BOOL);
}
std::string data;
data.push_back(0); // version
data.push_back(0); // signature_type -> certificate_timestamp
data.append(reinterpret_cast<const char*>(&timestamp_network), sizeof(timestamp_network)); // timestamp -> 64 bits
if ( precert )
data.append("\0\1", 2); // entry-type: precert_entry
else
data.append("\0\0", 2); // entry-type: x509_entry
if ( precert )
{
x = X509_dup(x);
assert(x);
#ifdef NID_ct_precert_scts
int pos = X509_get_ext_by_NID(x, NID_ct_precert_scts, -1);
if ( pos < 0 )
{
reporter->Error("NID_ct_precert_scts not found");
return new Val(0, TYPE_BOOL);
}
#else
int num_ext = X509_get_ext_count(x);
int pos = -1;
for ( int k = 0; k < num_ext; ++k )
{
char oid[256];
X509_EXTENSION* ex = X509_get_ext(x, k);
ASN1_OBJECT* ext_asn = X509_EXTENSION_get_object(ex);
OBJ_obj2txt(oid, 255, ext_asn, 1);
if ( strcmp(oid, "1.3.6.1.4.1.11129.2.4.2") == 0 )
{
pos = k;
break;
}
}
#endif
X509_EXTENSION_free(X509_delete_ext(x, pos));
#ifdef NID_ct_precert_scts
assert( X509_get_ext_by_NID(x, NID_ct_precert_scts, -1) == -1 );
#endif
}
unsigned char *cert_out = nullptr;
uint32 cert_length;
if ( precert )
{
// we also could use i2d_re_X509_tbs, for OpenSSL >= 1.0.2
x->cert_info->enc.modified = 1;
cert_length = i2d_X509_CINF(x->cert_info, &cert_out);
data.append(reinterpret_cast<const char*>(issuer_key_hash->Bytes()), issuer_key_hash->Len());
}
else
cert_length = i2d_X509(x, &cert_out);
assert( cert_out );
uint32 cert_length_network = htonl(cert_length);
assert( sizeof(cert_length_network) == 4);
data.append(reinterpret_cast<const char*>(&cert_length_network)+1, 3); // 3 bytes certificate length
data.append(reinterpret_cast<const char*>(cert_out), cert_length); // der-encoded certificate
OPENSSL_free(cert_out);
if ( precert )
X509_free(x);
data.append("\0\0", 2); // no extensions
// key is given as a DER-encoded SubjectPublicKeyInfo.
const unsigned char *key_char = log_key->Bytes();
EVP_PKEY* key = d2i_PUBKEY(nullptr, &key_char, log_key->Len());
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
assert(mdctx);
string errstr;
int success = 0;
const EVP_MD* hash = hash_to_evp(hash_algorithm);
if ( ! hash )
{
errstr = "Unknown hash algorithm";
goto sct_verify_err;
}
if ( ! key )
{
errstr = "Could not load log key";
goto sct_verify_err;
}
if ( ! EVP_DigestVerifyInit(mdctx, NULL, hash, NULL, key) )
{
errstr = "Could not init signature verification";
goto sct_verify_err;
}
if ( ! EVP_DigestVerifyUpdate(mdctx, data.data(), data.size()) )
{
errstr = "Could not update digest for verification";
goto sct_verify_err;
}
#ifdef NID_ct_precert_scts
success = EVP_DigestVerifyFinal(mdctx, signature->Bytes(), signature->Len());
#else
// older versions of OpenSSL use a non-const-char *sigh*
// I don't think they actually manipulate the value though.
// todo - this needs a cmake test
success = EVP_DigestVerifyFinal(mdctx, (unsigned char*) signature->Bytes(), signature->Len());
#endif
EVP_MD_CTX_destroy(mdctx);
EVP_PKEY_free(key);
return new Val(success, TYPE_BOOL);
sct_verify_err:
if (mdctx)
EVP_MD_CTX_destroy(mdctx);
if (key)
EVP_PKEY_free(key);
reporter->Error("%s", errstr.c_str());
return new Val(0, TYPE_BOOL);
%}
%%{
/**
* 0 -> subject name
* 1 -> issuer name
* 2 -> pubkey
*/
StringVal* x509_entity_hash(file_analysis::X509Val *cert_handle, unsigned int hash_alg, unsigned int type)
{
assert(cert_handle);
if ( type > 2 )
{
reporter->InternalError("Unknown type in x509_entity_hash");
return nullptr;
}
X509 *cert_x509 = cert_handle->GetCertificate();
if ( cert_x509 == nullptr )
{
builtin_error("cannot get cert from opaque");
return nullptr;
}
X509_NAME *subject_name = X509_get_subject_name(cert_x509);
X509_NAME *issuer_name = X509_get_issuer_name(cert_x509);
if ( subject_name == nullptr || issuer_name == nullptr )
{
builtin_error("fail to get subject/issuer name from certificate");
return nullptr;
}
const EVP_MD *dgst = hash_to_evp(hash_alg);
if ( dgst == nullptr )
{
builtin_error("Unknown hash algorithm.");
return nullptr;
}
unsigned char md[EVP_MAX_MD_SIZE];
memset(md, 0, sizeof(md));
unsigned int len = 0;
int res = 0;
ASN1_BIT_STRING *key = X509_get0_pubkey_bitstr(cert_x509);
if ( key == 0 )
{
printf("No key in X509_get0_pubkey_bitstr\n");
}
if ( type == 0 )
res = X509_NAME_digest(subject_name, dgst, md, &len);
else if ( type == 1 )
res = X509_NAME_digest(issuer_name, dgst, md, &len);
else if ( type == 2 )
{
unsigned char *spki = nullptr;
int pklen = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert_x509), &spki);
if ( ! pklen )
{
builtin_error("Could not get SPKI");
return nullptr;
}
res = EVP_Digest(spki, pklen, md, &len, dgst, nullptr);
OPENSSL_free(spki);
}
if ( ! res )
{
builtin_error("Could not perform hash");
return nullptr;
}
assert( len <= sizeof(md) );
return new StringVal(len, reinterpret_cast<const char*>(md));
}
%%}
## Get the hash of the subject's distinguished name.
##
## cert: The X509 certificate opaque handle.
##
## hash_alg: the hash algorithm to use, according to the IANA mapping at
## https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
##
## Returns: The hash as a string.
##
## .. bro:see:: x509_issuer_name_hash x509_spki_hash
## x509_verify sct_verify
function x509_subject_name_hash%(cert: opaque of x509, hash_alg: count%): string
%{
file_analysis::X509Val *cert_handle = (file_analysis::X509Val *) cert;
return x509_entity_hash(cert_handle, hash_alg, 0);
%}
## Get the hash of the issuer's distinguished name.
##
## cert: The X509 certificate opaque handle.
##
## hash_alg: the hash algorithm to use, according to the IANA mapping at
## https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
##
## Returns: The hash as a string.
##
## .. bro:see:: x509_subject_name_hash x509_spki_hash
## x509_verify sct_verify
function x509_issuer_name_hash%(cert: opaque of x509, hash_alg: count%): string
%{
file_analysis::X509Val *cert_handle = (file_analysis::X509Val *) cert;
return x509_entity_hash(cert_handle, hash_alg, 1);
%}
## Get the hash of the Subject Public Key Information of the certificate.
##
## cert: The X509 certificate opaque handle.
##
## hash_alg: the hash algorithm to use, according to the IANA mapping at
## https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
##
## Returns: The hash as a string.
##
## .. bro:see:: x509_subject_name_hash x509_issuer_name_hash
## x509_verify sct_verify
function x509_spki_hash%(cert: opaque of x509, hash_alg: count%): string
%{
file_analysis::X509Val *cert_handle = (file_analysis::X509Val *) cert;
return x509_entity_hash(cert_handle, hash_alg, 2);
%}

View file

@ -0,0 +1,120 @@
## Event that is raised when encountering an OCSP request, e.g. in an HTTP
## connection. See :rfc:`6960` for more details.
##
## This event is raised exactly once for each OCSP Request.
##
## f: The file.
##
## req: version: the version of the OCSP request. Typically 0 (Version 1).
##
## requestorName: name of the OCSP requestor. This attribute is optional; if
## it is not set, an empty string is returned here.
##
## .. bro:see:: ocsp_request_certificate ocsp_response_status
## ocsp_response_bytes ocsp_response_certificate ocsp_extension
## x509_ocsp_ext_signed_certificate_timestamp
event ocsp_request%(f: fa_file, version: count, requestorName: string%);
## Event that is raised when encountering an OCSP request for a certificate,
## e.g. in an HTTP connection. See :rfc:`6960` for more details.
##
## Note that a single OCSP request can contain requests for several certificates.
## Thus this event can fire several times for one OCSP request, each time
## requesting information for a different (or in theory even the same) certificate.
##
## f: The file.
##
## hashAlgorithm: The hash algorithm used for the issuerKeyHash.
##
## issuerKeyHash: Hash of the issuers public key.
##
## serialNumber: Serial number of the certificate for which the status is requested.
##
## .. bro:see:: ocsp_request ocsp_response_status
## ocsp_response_bytes ocsp_response_certificate ocsp_extension
## x509_ocsp_ext_signed_certificate_timestamp
event ocsp_request_certificate%(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string%);
## This event is raised when encountering an OCSP reply, e.g. in an HTTP
## connection or a TLS extension. See :rfc:`6960` for more details.
##
## This event is raised exactly once for each OCSP reply.
##
## f: The file.
##
## status: The status of the OCSP response (e.g. succesful, malformedRequest, tryLater).
##
## .. bro:see:: ocsp_request ocsp_request_certificate
## ocsp_response_bytes ocsp_response_certificate ocsp_extension
## x509_ocsp_ext_signed_certificate_timestamp
event ocsp_response_status%(f: fa_file, status: string%);
## This event is raised when encountering an OCSP response that contains response information.
## An OCSP reply can be encountered, for example, in an HTTP connection or
## a TLS extension. See :rfc:`6960` for more details on OCSP.
##
## f: The file.
##
## req_ref: An opaque pointer to the underlying OpenSSL data structure of the
## OCSP response.
##
## status: The status of the OCSP response (e.g. succesful, malformedRequest, tryLater).
##
## version: Version of the OCSP response (typically - for version 1).
##
## responderId: The id of the OCSP responder; either a public key hash or a distinguished name.
##
## producedAt: Time at which the reply was produced.
##
## signatureAlgorithm: Algorithm used for the OCSP signature.
##
## certs: Optional list of certificates that are sent with the OCSP response; these typically
## are needed to perform validation of the reply.
##
## .. bro:see:: ocsp_request ocsp_request_certificate ocsp_response_status
## ocsp_response_certificate ocsp_extension
## x509_ocsp_ext_signed_certificate_timestamp
event ocsp_response_bytes%(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector%);
## This event is raised for each SingleResponse contained in an OCSP response.
## See :rfc:`6960` for more details on OCSP.
##
## f: The file.
##
## hashAlgorithm: The hash algorithm used for issuerNameHash and issuerKeyHash.
##
## issuerNameHash: Hash of the issuer's distinguished name.
##
## issuerKeyHash: Hash of the issuer's public key.
##
## serialNumber: Serial number of the affected certificate.
##
## certStatus: Status of the certificate.
##
## revokeTime: Time the certificate was revoked, 0 if not revoked.
##
## revokeTeason: Reason certificate was revoked; empty string if not revoked or not specified.
##
## thisUpdate: Time this response was generated.
##
## nextUpdate: Time next response will be ready; 0 if not supploed.
##
## .. bro:see:: ocsp_request ocsp_request_certificate ocsp_response_status
## ocsp_response_bytes ocsp_extension
## x509_ocsp_ext_signed_certificate_timestamp
event ocsp_response_certificate%(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revokeTime: time, revokeReason: string, thisUpdate: time, nextUpdate: time%);
## This event is raised when an OCSP extension is encountered in an OCSP response.
## See :rfc:`6960` for more details on OCSP.
##
## f: The file.
##
## ext: The parsed extension (same format as X.509 extensions).
##
## global_resp: T if extension encountered in the global response (in ResponseData),
## F when encountered in a SingleResponse.
##
## .. bro:see:: ocsp_request ocsp_request_certificate ocsp_response_status
## ocsp_response_bytes ocsp_response_certificate
## x509_ocsp_ext_signed_certificate_timestamp
event ocsp_extension%(f: fa_file, ext: X509::Extension, global_resp: bool%);

View file

@ -0,0 +1,54 @@
# Binpac analyzer for X.509 extensions
# we just use it for the SignedCertificateTimestamp at the moment
%include binpac.pac
%include bro.pac
%extern{
#include "types.bif.h"
#include "file_analysis/File.h"
#include "events.bif.h"
%}
analyzer X509Extension withcontext {
connection: MockConnection;
flow: SignedCertTimestampExt;
};
connection MockConnection(bro_analyzer: BroFileAnalyzer) {
upflow = SignedCertTimestampExt;
downflow = SignedCertTimestampExt;
};
%include x509-signed_certificate_timestamp.pac
# The base record
type HandshakeRecord() = record {
signed_certificate_timestamp_list: SignedCertificateTimestampList(this)[] &transient;
} &byteorder = bigendian;
flow SignedCertTimestampExt {
flowunit = HandshakeRecord withcontext(connection, this);
};
refine connection MockConnection += {
function proc_signedcertificatetimestamp(rec: HandshakeRecord, version: uint8, logid: const_bytestring, timestamp: uint64, digitally_signed_algorithms: SignatureAndHashAlgorithm, digitally_signed_signature: const_bytestring) : bool
%{
BifEvent::generate_x509_ocsp_ext_signed_certificate_timestamp((analyzer::Analyzer *) bro_analyzer(),
bro_analyzer()->GetFile()->GetVal()->Ref(),
version,
new StringVal(logid.length(), reinterpret_cast<const char*>(logid.begin())),
timestamp,
digitally_signed_algorithms->HashAlgorithm(),
digitally_signed_algorithms->SignatureAlgorithm(),
new StringVal(digitally_signed_signature.length(), reinterpret_cast<const char*>(digitally_signed_signature.begin()))
);
return true;
%}
};
refine typeattr SignedCertificateTimestamp += &let {
proc : bool = $context.connection.proc_signedcertificatetimestamp(rec, version, logid, timestamp, digitally_signed_algorithms, digitally_signed_signature);
};

View file

@ -0,0 +1 @@
../../../analyzer/protocol/ssl/tls-handshake-signed_certificate_timestamp.pac

View file

@ -129,6 +129,7 @@ OpaqueType* cardinality_type = 0;
OpaqueType* topk_type = 0; OpaqueType* topk_type = 0;
OpaqueType* bloomfilter_type = 0; OpaqueType* bloomfilter_type = 0;
OpaqueType* x509_opaque_type = 0; OpaqueType* x509_opaque_type = 0;
OpaqueType* ocsp_resp_opaque_type = 0;
// Keep copy of command line // Keep copy of command line
int bro_argc; int bro_argc;
@ -839,6 +840,7 @@ int main(int argc, char** argv)
topk_type = new OpaqueType("topk"); topk_type = new OpaqueType("topk");
bloomfilter_type = new OpaqueType("bloomfilter"); bloomfilter_type = new OpaqueType("bloomfilter");
x509_opaque_type = new OpaqueType("x509"); x509_opaque_type = new OpaqueType("x509");
ocsp_resp_opaque_type = new OpaqueType("ocsp_resp");
// The leak-checker tends to produce some false // The leak-checker tends to produce some false
// positives (memory which had already been // positives (memory which had already been

View file

@ -3,7 +3,7 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path loaded_scripts #path loaded_scripts
#open 2017-02-28-17-15-30 #open 2017-05-02-20-38-47
#fields name #fields name
#types string #types string
scripts/base/init-bare.bro scripts/base/init-bare.bro
@ -157,6 +157,7 @@ scripts/base/init-bare.bro
build/scripts/base/bif/plugins/Bro_X509.events.bif.bro build/scripts/base/bif/plugins/Bro_X509.events.bif.bro
build/scripts/base/bif/plugins/Bro_X509.types.bif.bro build/scripts/base/bif/plugins/Bro_X509.types.bif.bro
build/scripts/base/bif/plugins/Bro_X509.functions.bif.bro build/scripts/base/bif/plugins/Bro_X509.functions.bif.bro
build/scripts/base/bif/plugins/Bro_X509.ocsp_events.bif.bro
build/scripts/base/bif/plugins/Bro_AsciiReader.ascii.bif.bro build/scripts/base/bif/plugins/Bro_AsciiReader.ascii.bif.bro
build/scripts/base/bif/plugins/Bro_BenchmarkReader.benchmark.bif.bro build/scripts/base/bif/plugins/Bro_BenchmarkReader.benchmark.bif.bro
build/scripts/base/bif/plugins/Bro_BinaryReader.binary.bif.bro build/scripts/base/bif/plugins/Bro_BinaryReader.binary.bif.bro
@ -167,4 +168,4 @@ scripts/base/init-bare.bro
build/scripts/base/bif/plugins/Bro_SQLiteWriter.sqlite.bif.bro build/scripts/base/bif/plugins/Bro_SQLiteWriter.sqlite.bif.bro
scripts/policy/misc/loaded-scripts.bro scripts/policy/misc/loaded-scripts.bro
scripts/base/utils/paths.bro scripts/base/utils/paths.bro
#close 2017-02-28-17-15-30 #close 2017-05-02-20-38-47

View file

@ -3,7 +3,7 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path loaded_scripts #path loaded_scripts
#open 2017-02-28-17-19-41 #open 2017-05-02-20-39-05
#fields name #fields name
#types string #types string
scripts/base/init-bare.bro scripts/base/init-bare.bro
@ -157,6 +157,7 @@ scripts/base/init-bare.bro
build/scripts/base/bif/plugins/Bro_X509.events.bif.bro build/scripts/base/bif/plugins/Bro_X509.events.bif.bro
build/scripts/base/bif/plugins/Bro_X509.types.bif.bro build/scripts/base/bif/plugins/Bro_X509.types.bif.bro
build/scripts/base/bif/plugins/Bro_X509.functions.bif.bro build/scripts/base/bif/plugins/Bro_X509.functions.bif.bro
build/scripts/base/bif/plugins/Bro_X509.ocsp_events.bif.bro
build/scripts/base/bif/plugins/Bro_AsciiReader.ascii.bif.bro build/scripts/base/bif/plugins/Bro_AsciiReader.ascii.bif.bro
build/scripts/base/bif/plugins/Bro_BenchmarkReader.benchmark.bif.bro build/scripts/base/bif/plugins/Bro_BenchmarkReader.benchmark.bif.bro
build/scripts/base/bif/plugins/Bro_BinaryReader.binary.bif.bro build/scripts/base/bif/plugins/Bro_BinaryReader.binary.bif.bro
@ -284,6 +285,7 @@ scripts/base/init-default.bro
scripts/base/protocols/ssl/consts.bro scripts/base/protocols/ssl/consts.bro
scripts/base/protocols/ssl/main.bro scripts/base/protocols/ssl/main.bro
scripts/base/protocols/ssl/mozilla-ca-list.bro scripts/base/protocols/ssl/mozilla-ca-list.bro
scripts/base/protocols/ssl/ct-list.bro
scripts/base/protocols/ssl/files.bro scripts/base/protocols/ssl/files.bro
scripts/base/files/x509/__load__.bro scripts/base/files/x509/__load__.bro
scripts/base/files/x509/main.bro scripts/base/files/x509/main.bro
@ -355,4 +357,4 @@ scripts/base/init-default.bro
scripts/base/misc/find-filtered-trace.bro scripts/base/misc/find-filtered-trace.bro
scripts/base/misc/version.bro scripts/base/misc/version.bro
scripts/policy/misc/loaded-scripts.bro scripts/policy/misc/loaded-scripts.bro
#close 2017-02-28-17-19-41 #close 2017-05-02-20-39-05

View file

@ -30,6 +30,7 @@ netcontrol_shunt
notice notice
notice_alarm notice_alarm
ntlm ntlm
ocsp
open_flow open_flow
packet_filter packet_filter
pe pe

View file

@ -151,7 +151,16 @@
0.000000 MetaHookPost CallFunction(Cluster::is_enabled, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(Cluster::is_enabled, <frame>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(Cluster::is_enabled, <null>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(Cluster::is_enabled, <null>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_analyzer_add_callback, <frame>, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$last_active, -, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)FileExtract::f$info$extracted_cutoff = Fmkdir(FileExtract::prefix)})) -> <no result> 0.000000 MetaHookPost CallFunction(Files::register_analyzer_add_callback, <frame>, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$last_active, -, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)FileExtract::f$info$extracted_cutoff = Fmkdir(FileExtract::prefix)})) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_MD5, application/pkix-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_MD5, application/x-x509-ca-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_MD5, application/x-x509-user-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_PE, application/x-dosexec)) -> <no result> 0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_PE, application/x-dosexec)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_SHA1, application/pkix-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_SHA1, application/x-x509-ca-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_SHA1, application/x-x509-user-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_X509, application/pkix-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_X509, application/x-x509-ca-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_X509, application/x-x509-user-cert)) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_for_mime_types, <frame>, (Files::ANALYZER_PE, {application/x-dosexec})) -> <no result> 0.000000 MetaHookPost CallFunction(Files::register_for_mime_types, <frame>, (Files::ANALYZER_PE, {application/x-dosexec})) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_DTLS, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ <init> SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) -> <no result> 0.000000 MetaHookPost CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_DTLS, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ <init> SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) -> <no result>
0.000000 MetaHookPost CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ <init> FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) -> <no result> 0.000000 MetaHookPost CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ <init> FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) -> <no result>
@ -247,7 +256,7 @@
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1498500921.18004, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) -> <no result>
@ -377,7 +386,7 @@
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1498500921.18004, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result>
0.000000 MetaHookPost CallFunction(NetControl::check_plugins, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(NetControl::check_plugins, <frame>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(NetControl::init, <null>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(NetControl::init, <null>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(Notice::want_pp, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(Notice::want_pp, <frame>, ()) -> <no result>
@ -523,6 +532,7 @@
0.000000 MetaHookPost LoadFile(./Bro_Unified2.types.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_Unified2.types.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./Bro_X509.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_X509.events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./Bro_X509.functions.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_X509.functions.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./Bro_X509.ocsp_events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./Bro_X509.types.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_X509.types.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./Bro_XMPP.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./Bro_XMPP.events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./acld) -> -1 0.000000 MetaHookPost LoadFile(./acld) -> -1
@ -542,6 +552,7 @@
0.000000 MetaHookPost LoadFile(./consts) -> -1 0.000000 MetaHookPost LoadFile(./consts) -> -1
0.000000 MetaHookPost LoadFile(./consts.bro) -> -1 0.000000 MetaHookPost LoadFile(./consts.bro) -> -1
0.000000 MetaHookPost LoadFile(./contents) -> -1 0.000000 MetaHookPost LoadFile(./contents) -> -1
0.000000 MetaHookPost LoadFile(./ct-list) -> -1
0.000000 MetaHookPost LoadFile(./data.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(./data.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(./dcc-send) -> -1 0.000000 MetaHookPost LoadFile(./dcc-send) -> -1
0.000000 MetaHookPost LoadFile(./debug) -> -1 0.000000 MetaHookPost LoadFile(./debug) -> -1
@ -870,7 +881,16 @@
0.000000 MetaHookPre CallFunction(Cluster::is_enabled, <frame>, ()) 0.000000 MetaHookPre CallFunction(Cluster::is_enabled, <frame>, ())
0.000000 MetaHookPre CallFunction(Cluster::is_enabled, <null>, ()) 0.000000 MetaHookPre CallFunction(Cluster::is_enabled, <null>, ())
0.000000 MetaHookPre CallFunction(Files::register_analyzer_add_callback, <frame>, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$last_active, -, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)FileExtract::f$info$extracted_cutoff = Fmkdir(FileExtract::prefix)})) 0.000000 MetaHookPre CallFunction(Files::register_analyzer_add_callback, <frame>, (Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$last_active, -, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)FileExtract::f$info$extracted_cutoff = Fmkdir(FileExtract::prefix)}))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_MD5, application/pkix-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_MD5, application/x-x509-ca-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_MD5, application/x-x509-user-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_PE, application/x-dosexec)) 0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_PE, application/x-dosexec))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_SHA1, application/pkix-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_SHA1, application/x-x509-ca-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_SHA1, application/x-x509-user-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_X509, application/pkix-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_X509, application/x-x509-ca-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_type, <frame>, (Files::ANALYZER_X509, application/x-x509-user-cert))
0.000000 MetaHookPre CallFunction(Files::register_for_mime_types, <frame>, (Files::ANALYZER_PE, {application/x-dosexec})) 0.000000 MetaHookPre CallFunction(Files::register_for_mime_types, <frame>, (Files::ANALYZER_PE, {application/x-dosexec}))
0.000000 MetaHookPre CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_DTLS, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ <init> SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])) 0.000000 MetaHookPre CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_DTLS, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ <init> SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}]))
0.000000 MetaHookPre CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ <init> FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])) 0.000000 MetaHookPre CallFunction(Files::register_protocol, <frame>, (Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ <init> FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}]))
@ -966,7 +986,7 @@
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]))
0.000000 MetaHookPre CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1498500921.18004, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Communication::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Conn::LOG))
@ -1096,7 +1116,7 @@
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]))
0.000000 MetaHookPre CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1498500921.18004, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(NetControl::check_plugins, <frame>, ()) 0.000000 MetaHookPre CallFunction(NetControl::check_plugins, <frame>, ())
0.000000 MetaHookPre CallFunction(NetControl::init, <null>, ()) 0.000000 MetaHookPre CallFunction(NetControl::init, <null>, ())
0.000000 MetaHookPre CallFunction(Notice::want_pp, <frame>, ()) 0.000000 MetaHookPre CallFunction(Notice::want_pp, <frame>, ())
@ -1242,6 +1262,7 @@
0.000000 MetaHookPre LoadFile(./Bro_Unified2.types.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_Unified2.types.bif.bro)
0.000000 MetaHookPre LoadFile(./Bro_X509.events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_X509.events.bif.bro)
0.000000 MetaHookPre LoadFile(./Bro_X509.functions.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_X509.functions.bif.bro)
0.000000 MetaHookPre LoadFile(./Bro_X509.ocsp_events.bif.bro)
0.000000 MetaHookPre LoadFile(./Bro_X509.types.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_X509.types.bif.bro)
0.000000 MetaHookPre LoadFile(./Bro_XMPP.events.bif.bro) 0.000000 MetaHookPre LoadFile(./Bro_XMPP.events.bif.bro)
0.000000 MetaHookPre LoadFile(./acld) 0.000000 MetaHookPre LoadFile(./acld)
@ -1261,6 +1282,7 @@
0.000000 MetaHookPre LoadFile(./consts) 0.000000 MetaHookPre LoadFile(./consts)
0.000000 MetaHookPre LoadFile(./consts.bro) 0.000000 MetaHookPre LoadFile(./consts.bro)
0.000000 MetaHookPre LoadFile(./contents) 0.000000 MetaHookPre LoadFile(./contents)
0.000000 MetaHookPre LoadFile(./ct-list)
0.000000 MetaHookPre LoadFile(./data.bif.bro) 0.000000 MetaHookPre LoadFile(./data.bif.bro)
0.000000 MetaHookPre LoadFile(./dcc-send) 0.000000 MetaHookPre LoadFile(./dcc-send)
0.000000 MetaHookPre LoadFile(./debug) 0.000000 MetaHookPre LoadFile(./debug)
@ -1588,7 +1610,16 @@
0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_XMPP, {5222<...>/tcp}) 0.000000 | HookCallFunction Analyzer::register_for_ports(Analyzer::ANALYZER_XMPP, {5222<...>/tcp})
0.000000 | HookCallFunction Cluster::is_enabled() 0.000000 | HookCallFunction Cluster::is_enabled()
0.000000 | HookCallFunction Files::register_analyzer_add_callback(Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$last_active, -, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)FileExtract::f$info$extracted_cutoff = Fmkdir(FileExtract::prefix)}) 0.000000 | HookCallFunction Files::register_analyzer_add_callback(Files::ANALYZER_EXTRACT, FileExtract::on_add{ if (!FileExtract::args?$extract_filename) FileExtract::args$extract_filename = cat(extract-, FileExtract::f$last_active, -, FileExtract::f$source, -, FileExtract::f$id)FileExtract::f$info$extracted = FileExtract::args$extract_filenameFileExtract::args$extract_filename = build_path_compressed(FileExtract::prefix, FileExtract::args$extract_filename)FileExtract::f$info$extracted_cutoff = Fmkdir(FileExtract::prefix)})
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_MD5, application/pkix-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_MD5, application/x-x509-ca-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_MD5, application/x-x509-user-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_PE, application/x-dosexec) 0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_PE, application/x-dosexec)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_SHA1, application/pkix-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_SHA1, application/x-x509-ca-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_SHA1, application/x-x509-user-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_X509, application/pkix-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_X509, application/x-x509-ca-cert)
0.000000 | HookCallFunction Files::register_for_mime_type(Files::ANALYZER_X509, application/x-x509-user-cert)
0.000000 | HookCallFunction Files::register_for_mime_types(Files::ANALYZER_PE, {application/x-dosexec}) 0.000000 | HookCallFunction Files::register_for_mime_types(Files::ANALYZER_PE, {application/x-dosexec})
0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_DTLS, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ <init> SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}]) 0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_DTLS, [get_file_handle=SSL::get_file_handle{ return ()}, describe=SSL::describe_file{ <init> SSL::cid{ if (SSL::f$source != SSL || !SSL::f?$info || !SSL::f$info?$x509 || !SSL::f$info$x509?$certificate) return ()for ([SSL::cid] in SSL::f$conns) { if (SSL::f$conns[SSL::cid]?$ssl) { SSL::c = SSL::f$conns[SSL::cid]return (cat(SSL::c$id$resp_h, :, SSL::c$id$resp_p))}}return (cat(Serial: , SSL::f$info$x509$certificate$serial, Subject: , SSL::f$info$x509$certificate$subject, Issuer: , SSL::f$info$x509$certificate$issuer))}}])
0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ <init> FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}]) 0.000000 | HookCallFunction Files::register_protocol(Analyzer::ANALYZER_FTP_DATA, [get_file_handle=FTP::get_file_handle{ if (!FTP::c$id$resp_h, FTP::c$id$resp_p in FTP::ftp_data_expected) return ()return (cat(Analyzer::ANALYZER_FTP_DATA, FTP::c$start_time, FTP::c$id, FTP::is_orig))}, describe=FTP::describe_file{ <init> FTP::cid{ if (FTP::f$source != FTP) return ()for ([FTP::cid] in FTP::f$conns) { if (FTP::f$conns[FTP::cid]?$ftp) return (FTP::describe(FTP::f$conns[FTP::cid]$ftp))}return ()}}])
@ -1684,7 +1715,7 @@
0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])
0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1498500921.18004, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG)
@ -1814,7 +1845,7 @@
0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])
0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1498500921.18004, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction NetControl::check_plugins() 0.000000 | HookCallFunction NetControl::check_plugins()
0.000000 | HookCallFunction NetControl::init() 0.000000 | HookCallFunction NetControl::init()
0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction Notice::want_pp()
@ -1856,7 +1887,7 @@
0.000000 | HookLoadFile base<...>/bif 0.000000 | HookLoadFile base<...>/bif
0.000000 | HookLoadFile base<...>/bro 0.000000 | HookLoadFile base<...>/bro
0.000000 | HookLogInit packet_filter 1/1 {ts (time), node (string), filter (string), init (bool), success (bool)} 0.000000 | HookLogInit packet_filter 1/1 {ts (time), node (string), filter (string), init (bool), success (bool)}
0.000000 | HookLogWrite packet_filter [ts=1493067689.952434, node=bro, filter=ip or not ip, init=T, success=T] 0.000000 | HookLogWrite packet_filter [ts=1498500921.180040, node=bro, filter=ip or not ip, init=T, success=T]
0.000000 | HookQueueEvent NetControl::init() 0.000000 | HookQueueEvent NetControl::init()
0.000000 | HookQueueEvent bro_init() 0.000000 | HookQueueEvent bro_init()
0.000000 | HookQueueEvent filter_change_tracking() 0.000000 | HookQueueEvent filter_change_tracking()
@ -2204,7 +2235,7 @@
1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CHhAvVGS1DHFjwGM9}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CHhAvVGS1DHFjwGM9}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) -> <no result>
1362692527.009775 MetaHookPost CallFunction(file_sniff, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(file_sniff, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], inferred=T])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])) -> <no result> 1362692527.009775 MetaHookPost CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])) -> <no result>
1362692527.009775 MetaHookPost CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) -> <no result>
1362692527.009775 MetaHookPost CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> <no result> 1362692527.009775 MetaHookPost CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> <no result>
@ -2217,7 +2248,7 @@
1362692527.009775 MetaHookPost LogInit(Log::WRITER_ASCII, default, true, true, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}) -> <void> 1362692527.009775 MetaHookPost LogInit(Log::WRITER_ASCII, default, true, true, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}) -> <void>
1362692527.009775 MetaHookPost LogWrite(Log::WRITER_ASCII, default, files(1362692527.009775,0.0,0.0), 25, {ts (time), fuid (string), tx_hosts (set[addr]), rx_hosts (set[addr]), conn_uids (set[string]), source (string), depth (count), analyzers (set[string]), mime_type (string), filename (string), duration (interval), local_orig (bool), is_orig (bool), seen_bytes (count), total_bytes (count), missing_bytes (count), overflow_bytes (count), timedout (bool), parent_fuid (string), md5 (string), sha1 (string), sha256 (string), extracted (string), extracted_cutoff (bool), extracted_size (count)}, <void ptr>) -> true 1362692527.009775 MetaHookPost LogWrite(Log::WRITER_ASCII, default, files(1362692527.009775,0.0,0.0), 25, {ts (time), fuid (string), tx_hosts (set[addr]), rx_hosts (set[addr]), conn_uids (set[string]), source (string), depth (count), analyzers (set[string]), mime_type (string), filename (string), duration (interval), local_orig (bool), is_orig (bool), seen_bytes (count), total_bytes (count), missing_bytes (count), overflow_bytes (count), timedout (bool), parent_fuid (string), md5 (string), sha1 (string), sha256 (string), extracted (string), extracted_cutoff (bool), extracted_size (count)}, <void ptr>) -> true
1362692527.009775 MetaHookPost LogWrite(Log::WRITER_ASCII, default, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}, <void ptr>) -> true 1362692527.009775 MetaHookPost LogWrite(Log::WRITER_ASCII, default, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}, <void ptr>) -> true
1362692527.009775 MetaHookPost QueueEvent(file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])) -> false 1362692527.009775 MetaHookPost QueueEvent(file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], inferred=T])) -> false
1362692527.009775 MetaHookPost QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])) -> false 1362692527.009775 MetaHookPost QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])) -> false
1362692527.009775 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false 1362692527.009775 MetaHookPost QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false
1362692527.009775 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false 1362692527.009775 MetaHookPost QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) -> false
@ -2233,7 +2264,7 @@
1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CHhAvVGS1DHFjwGM9}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>])) 1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CHhAvVGS1DHFjwGM9}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>]))
1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])) 1362692527.009775 MetaHookPre CallFunction(Log::write, <frame>, (HTTP::LOG, [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]))
1362692527.009775 MetaHookPre CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)) 1362692527.009775 MetaHookPre CallFunction(cat, <frame>, (Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80))
1362692527.009775 MetaHookPre CallFunction(file_sniff, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])) 1362692527.009775 MetaHookPre CallFunction(file_sniff, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], inferred=T]))
1362692527.009775 MetaHookPre CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])) 1362692527.009775 MetaHookPre CallFunction(file_state_remove, <null>, ([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>]))
1362692527.009775 MetaHookPre CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)) 1362692527.009775 MetaHookPre CallFunction(fmt, <frame>, (%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp))
1362692527.009775 MetaHookPre CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) 1362692527.009775 MetaHookPre CallFunction(get_file_handle, <null>, (Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F))
@ -2246,7 +2277,7 @@
1362692527.009775 MetaHookPre LogInit(Log::WRITER_ASCII, default, true, true, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}) 1362692527.009775 MetaHookPre LogInit(Log::WRITER_ASCII, default, true, true, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])})
1362692527.009775 MetaHookPre LogWrite(Log::WRITER_ASCII, default, files(1362692527.009775,0.0,0.0), 25, {ts (time), fuid (string), tx_hosts (set[addr]), rx_hosts (set[addr]), conn_uids (set[string]), source (string), depth (count), analyzers (set[string]), mime_type (string), filename (string), duration (interval), local_orig (bool), is_orig (bool), seen_bytes (count), total_bytes (count), missing_bytes (count), overflow_bytes (count), timedout (bool), parent_fuid (string), md5 (string), sha1 (string), sha256 (string), extracted (string), extracted_cutoff (bool), extracted_size (count)}, <void ptr>) 1362692527.009775 MetaHookPre LogWrite(Log::WRITER_ASCII, default, files(1362692527.009775,0.0,0.0), 25, {ts (time), fuid (string), tx_hosts (set[addr]), rx_hosts (set[addr]), conn_uids (set[string]), source (string), depth (count), analyzers (set[string]), mime_type (string), filename (string), duration (interval), local_orig (bool), is_orig (bool), seen_bytes (count), total_bytes (count), missing_bytes (count), overflow_bytes (count), timedout (bool), parent_fuid (string), md5 (string), sha1 (string), sha256 (string), extracted (string), extracted_cutoff (bool), extracted_size (count)}, <void ptr>)
1362692527.009775 MetaHookPre LogWrite(Log::WRITER_ASCII, default, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}, <void ptr>) 1362692527.009775 MetaHookPre LogWrite(Log::WRITER_ASCII, default, http(1362692527.009775,0.0,0.0), 29, {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}, <void ptr>)
1362692527.009775 MetaHookPre QueueEvent(file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]])) 1362692527.009775 MetaHookPre QueueEvent(file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], inferred=T]))
1362692527.009775 MetaHookPre QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])) 1362692527.009775 MetaHookPre QueueEvent(file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>]))
1362692527.009775 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) 1362692527.009775 MetaHookPre QueueEvent(get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F))
1362692527.009775 MetaHookPre QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)) 1362692527.009775 MetaHookPre QueueEvent(http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F))
@ -2263,7 +2294,7 @@
1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CHhAvVGS1DHFjwGM9}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>]) 1362692527.009775 | HookCallFunction Log::write(Files::LOG, [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts={192.150.187.43}, rx_hosts={141.142.228.5}, conn_uids={CHhAvVGS1DHFjwGM9}, source=HTTP, depth=0, analyzers={}, mime_type=text/plain, filename=<uninitialized>, duration=262.0 usecs, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, x509=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>])
1362692527.009775 | HookCallFunction Log::write(HTTP::LOG, [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]) 1362692527.009775 | HookCallFunction Log::write(HTTP::LOG, [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1])
1362692527.009775 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80) 1362692527.009775 | HookCallFunction cat(Analyzer::ANALYZER_HTTP, 1362692526.869344, F, 1, 1, 141.142.228.5:59856 > 192.150.187.43:80)
1362692527.009775 | HookCallFunction file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]]) 1362692527.009775 | HookCallFunction file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], inferred=T])
1362692527.009775 | HookCallFunction file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>]) 1362692527.009775 | HookCallFunction file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])
1362692527.009775 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp) 1362692527.009775 | HookCallFunction fmt(%s:%d > %s:%d, 141.142.228.5, 59856<...>/tcp)
1362692527.009775 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F) 1362692527.009775 | HookCallFunction get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=<uninitialized>, orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)
@ -2276,7 +2307,7 @@
1362692527.009775 | HookLogInit http 1/1 {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])} 1362692527.009775 | HookLogInit http 1/1 {ts (time), uid (string), id.orig_h (addr), id.orig_p (port), id.resp_h (addr), id.resp_p (port), trans_depth (count), method (string), host (string), uri (string), referrer (string), version (string), user_agent (string), request_body_len (count), response_body_len (count), status_code (count), status_msg (string), info_code (count), info_msg (string), tags (set[enum]), username (string), password (string), proxied (set[string]), orig_fuids (vector[string]), orig_filenames (vector[string]), orig_mime_types (vector[string]), resp_fuids (vector[string]), resp_filenames (vector[string]), resp_mime_types (vector[string])}
1362692527.009775 | HookLogWrite files [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts=192.150.187.43, rx_hosts=141.142.228.5, conn_uids=CHhAvVGS1DHFjwGM9, source=HTTP, depth=0, analyzers=, mime_type=text/plain, filename=<uninitialized>, duration=0.000263, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>] 1362692527.009775 | HookLogWrite files [ts=1362692527.009512, fuid=FakNcS1Jfe01uljb3, tx_hosts=192.150.187.43, rx_hosts=141.142.228.5, conn_uids=CHhAvVGS1DHFjwGM9, source=HTTP, depth=0, analyzers=, mime_type=text/plain, filename=<uninitialized>, duration=0.000263, local_orig=<uninitialized>, is_orig=F, seen_bytes=4705, total_bytes=4705, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=<uninitialized>, md5=<uninitialized>, sha1=<uninitialized>, sha256=<uninitialized>, extracted=<uninitialized>, extracted_cutoff=<uninitialized>, extracted_size=<uninitialized>]
1362692527.009775 | HookLogWrite http [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id.orig_h=141.142.228.5, id.orig_p=59856, id.resp_h=192.150.187.43, id.resp_p=80, trans_depth=1, method=GET, host=bro.org, uri=<...>/plain] 1362692527.009775 | HookLogWrite http [ts=1362692526.939527, uid=CHhAvVGS1DHFjwGM9, id.orig_h=141.142.228.5, id.orig_p=59856, id.resp_h=192.150.187.43, id.resp_p=80, trans_depth=1, method=GET, host=bro.org, uri=<...>/plain]
1362692527.009775 | HookQueueEvent file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]]]) 1362692527.009775 | HookQueueEvent file_sniff([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain]], inferred=T])
1362692527.009775 | HookQueueEvent file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>]) 1362692527.009775 | HookQueueEvent file_state_remove([id=FakNcS1Jfe01uljb3, parent_id=<uninitialized>, source=HTTP, is_orig=F, conns={[[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1], irc=<uninitialized>, pe=<uninitialized>, u2_events=<uninitialized>])
1362692527.009775 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F) 1362692527.009775 | HookQueueEvent get_file_handle(Analyzer::ANALYZER_HTTP, [id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)
1362692527.009775 | HookQueueEvent http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F) 1362692527.009775 | HookQueueEvent http_end_entity([id=[orig_h=141.142.228.5, orig_p=59856<...>/plain], current_entity=[filename=<uninitialized>], orig_mime_depth=1, resp_mime_depth=1]}, current_request=1, current_response=1, trans_depth=1], irc=<uninitialized>, krb=<uninitialized>, modbus=<uninitialized>, mysql=<uninitialized>, ntlm=<uninitialized>, radius=<uninitialized>, rdp=<uninitialized>, rfb=<uninitialized>, sip=<uninitialized>, sip_state=<uninitialized>, snmp=<uninitialized>, smtp=<uninitialized>, smtp_state=<uninitialized>, socks=<uninitialized>, ssh=<uninitialized>, syslog=<uninitialized>], F)

View file

@ -0,0 +1,12 @@
0, Symantec log, 1474927230.876, 4, 3
0, Google 'Rocketeer' log, 1474927232.863, 4, 3
0, Google 'Aviator' log, 1474927232.112, 4, 3
0, Google 'Pilot' log, 1474927232.304, 4, 3
Verify of, Symantec log, T
Bad verify of, Symantec log, F
Verify of, Google 'Rocketeer' log, T
Bad verify of, Google 'Rocketeer' log, F
Verify of, Google 'Aviator' log, T
Bad verify of, Google 'Aviator' log, F
Verify of, Google 'Pilot' log, T
Bad verify of, Google 'Pilot' log, F

View file

@ -0,0 +1,6 @@
0, Google 'Pilot' log, 1406997753.366, 4, 3
Verify of, Google 'Pilot' log, T
Bad verify of, Google 'Pilot' log, F
0, Google 'Aviator' log, 1407002457.456, 4, 3
Verify of, Google 'Aviator' log, T
Bad verify of, Google 'Aviator' log, F

View file

@ -60,10 +60,8 @@ FILE_OVER_NEW_CONNECTION
FILE_STATE_REMOVE FILE_STATE_REMOVE
file #4, 1406, 0 file #4, 1406, 0
[orig_h=192.168.133.100, orig_p=49655/tcp, resp_h=17.167.150.73, resp_p=443/tcp] [orig_h=192.168.133.100, orig_p=49655/tcp, resp_h=17.167.150.73, resp_p=443/tcp]
FILE_BOF_BUFFER
0\x82\x05z0\x82\x04b\xa0\x03\x02
MIME_TYPE MIME_TYPE
application/pkix-cert application/x-x509-user-cert
source: SSL source: SSL
MD5: 1bf9696d9f337805383427e88781d001 MD5: 1bf9696d9f337805383427e88781d001
SHA1: f5ccb1a724133607548b00d8eb402efca3076d58 SHA1: f5ccb1a724133607548b00d8eb402efca3076d58
@ -73,10 +71,8 @@ FILE_OVER_NEW_CONNECTION
FILE_STATE_REMOVE FILE_STATE_REMOVE
file #5, 1092, 0 file #5, 1092, 0
[orig_h=192.168.133.100, orig_p=49655/tcp, resp_h=17.167.150.73, resp_p=443/tcp] [orig_h=192.168.133.100, orig_p=49655/tcp, resp_h=17.167.150.73, resp_p=443/tcp]
FILE_BOF_BUFFER
0\x82\x04@0\x82\x03(\xa0\x03\x02
MIME_TYPE MIME_TYPE
application/pkix-cert application/x-x509-ca-cert
source: SSL source: SSL
MD5: 48f0e38385112eeca5fc9ffd402eaecd MD5: 48f0e38385112eeca5fc9ffd402eaecd
SHA1: 8e8321ca08b08e3726fe1d82996884eeb5f0d655 SHA1: 8e8321ca08b08e3726fe1d82996884eeb5f0d655

View file

@ -0,0 +1,3 @@
ocsp_response_status, successful
ocsp_response_certificate, sha1, F2E06AF9858A1D8D709B4919237AA9B51A287E64, 4ADD06161BBCF668B576F581B6BB621ABA5A812F, 4ADD06161BBCF668B576F581B6BB621ABA5A812F, good, 0.0, , 1436577056.0, 1437181856.0
ocsp_response_bytes, successful, 0, 4ADD06161BBCF668B576F581B6BB621ABA5A812F, 1436577056.0, sha1WithRSAEncryption

View file

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ocsp
#open 2017-02-10-23-35-49
#fields ts id hashAlgorithm issuerNameHash issuerKeyHash serialNumber certStatus revoketime revokereason thisUpdate nextUpdate
#types time string string string string string string time string time time
1436909712.329517 Ft368Gc1ce0Juvj0d sha1 F2E06AF9858A1D8D709B4919237AA9B51A287E64 4ADD06161BBCF668B576F581B6BB621ABA5A812F 4ADD06161BBCF668B576F581B6BB621ABA5A812F good - - 1436577056.000000 1437181856.000000
#close 2017-02-10-23-35-50

View file

@ -0,0 +1,2 @@
request, 0,
request cert, sha1, B6080D5F6C6B76EB13E438A5F8660BA85233344E, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE

View file

@ -0,0 +1,5 @@
request, 0,
request cert, sha1, B6080D5F6C6B76EB13E438A5F8660BA85233344E, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE
ocsp_response_status, successful
ocsp_response_certificate, sha1, B6080D5F6C6B76EB13E438A5F8660BA85233344E, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE, good, 0.0, , 1434665014.0, 1434794614.0
ocsp_response_bytes, successful, 0, C = US, ST = Arizona, L = Scottsdale, O = GoDaddy Inc., CN = Go Daddy Validation Authority - G2, 1434665014.0, sha1WithRSAEncryption

View file

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ocsp
#open 2017-02-11-00-00-41
#fields ts id hashAlgorithm issuerNameHash issuerKeyHash serialNumber certStatus revoketime revokereason thisUpdate nextUpdate
#types time string string string string string string time string time time
1434666864.070748 Fb215u2y5byABaV747 sha1 B6080D5F6C6B76EB13E438A5F8660BA85233344E 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE good - - 1434665014.000000 1434794614.000000
#close 2017-02-11-00-00-41

View file

@ -0,0 +1,3 @@
ocsp_response_status, successful
ocsp_response_certificate, sha1, B6080D5F6C6B76EB13E438A5F8660BA85233344E, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE, 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE, good, 0.0, , 1434665014.0, 1434794614.0
ocsp_response_bytes, successful, 0, C = US, ST = Arizona, L = Scottsdale, O = GoDaddy Inc., CN = Go Daddy Validation Authority - G2, 1434665014.0, sha1WithRSAEncryption

View file

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ocsp
#open 2017-02-11-00-00-52
#fields ts id hashAlgorithm issuerNameHash issuerKeyHash serialNumber certStatus revoketime revokereason thisUpdate nextUpdate
#types time string string string string string string time string time time
1434666864.070748 Fb215u2y5byABaV747 sha1 B6080D5F6C6B76EB13E438A5F8660BA85233344E 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE 40C2BD278ECC348330A233D7FB6CB3F0B42C80CE good - - 1434665014.000000 1434794614.000000
#close 2017-02-11-00-00-52

View file

@ -0,0 +1,20 @@
request, 0,
request cert, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A
ocsp_response_status, successful
ocsp_response_certificate, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, revoked, 1431615529.0, superseded, 1436286514.0, 1443489162.0
ocsp_response_bytes, successful, 0, F6215E926EB3EC41FE08FC25F09FB1B9A0344A10, 1436286514.0, sha1WithRSAEncryption
request, 0,
request cert, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A
ocsp_response_status, successful
ocsp_response_certificate, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, revoked, 1422391081.0, unspecified, 1436304214.0, 1443597239.0
ocsp_response_bytes, successful, 0, F6215E926EB3EC41FE08FC25F09FB1B9A0344A10, 1436304214.0, sha1WithRSAEncryption
request, 0,
request cert, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A
ocsp_response_status, successful
ocsp_response_certificate, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, revoked, 1432792428.0, (UNKNOWN), 1436238224.0, 1443473859.0
ocsp_response_bytes, successful, 0, F6215E926EB3EC41FE08FC25F09FB1B9A0344A10, 1436238224.0, sha1WithRSAEncryption
request, 0,
request cert, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A
ocsp_response_status, successful
ocsp_response_certificate, sha1, 74241467069FF5E0983F5E3E1A6BA0652A541575, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, 0159ABE7DD3A0B59A66463D6CF200757D591E76A, revoked, 1421494379.0, keyCompromise, 1436321024.0, 1443459307.0
ocsp_response_bytes, successful, 0, F6215E926EB3EC41FE08FC25F09FB1B9A0344A10, 1436321024.0, sha1WithRSAEncryption

View file

@ -0,0 +1,13 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ocsp
#open 2017-02-11-00-00-56
#fields ts id hashAlgorithm issuerNameHash issuerKeyHash serialNumber certStatus revoketime revokereason thisUpdate nextUpdate
#types time string string string string string string time string time time
1438374032.607476 Ftl4F41OsGtUDrOTWc sha1 74241467069FF5E0983F5E3E1A6BA0652A541575 0159ABE7DD3A0B59A66463D6CF200757D591E76A 0159ABE7DD3A0B59A66463D6CF200757D591E76A revoked 1431615529.000000 superseded 1436286514.000000 1443489162.000000
1438374032.731983 FXISxH2UuTiDn0qCa1 sha1 74241467069FF5E0983F5E3E1A6BA0652A541575 0159ABE7DD3A0B59A66463D6CF200757D591E76A 0159ABE7DD3A0B59A66463D6CF200757D591E76A revoked 1422391081.000000 unspecified 1436304214.000000 1443597239.000000
1438374032.848476 F3OYfx3A0JvMX787V3 sha1 74241467069FF5E0983F5E3E1A6BA0652A541575 0159ABE7DD3A0B59A66463D6CF200757D591E76A 0159ABE7DD3A0B59A66463D6CF200757D591E76A revoked 1432792428.000000 (UNKNOWN) 1436238224.000000 1443473859.000000
1438374033.033189 FVty9v3KTnCvbg0Xf2 sha1 74241467069FF5E0983F5E3E1A6BA0652A541575 0159ABE7DD3A0B59A66463D6CF200757D591E76A 0159ABE7DD3A0B59A66463D6CF200757D591E76A revoked 1421494379.000000 keyCompromise 1436321024.000000 1443459307.000000
#close 2017-02-11-00-00-56

View file

@ -0,0 +1,9 @@
0, Google 'Pilot' log, 1406997753.366, [HashAlgorithm=4, SignatureAlgorithm=3]
0, Google 'Aviator' log, 1407002457.456, [HashAlgorithm=4, SignatureAlgorithm=3]
0, Google 'Rocketeer' log, 1410299366.023, [HashAlgorithm=4, SignatureAlgorithm=3]
Verify of, Google 'Pilot' log, T
Bad verify of, Google 'Pilot' log, F
Verify of, Google 'Aviator' log, T
Bad verify of, Google 'Aviator' log, F
Verify of, Google 'Rocketeer' log, T
Bad verify of, Google 'Rocketeer' log, F

View file

@ -3,23 +3,23 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path intel #path intel
#open 2016-08-05-13-22-37 #open 2017-05-02-20-45-26
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p seen.indicator seen.indicator_type seen.where seen.node matched sources fuid file_mime_type file_desc #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p seen.indicator seen.indicator_type seen.where seen.node matched sources fuid file_mime_type file_desc
#types time string addr port addr port string enum enum string set[enum] set[string] string string string #types time string addr port addr port string enum enum string set[enum] set[string] string string string
1416942644.593119 CHhAvVGS1DHFjwGM9 192.168.4.149 49422 23.92.19.75 443 www.pantz.org Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 Fi6J8q3lDJpbQWAnvi application/pkix-cert 23.92.19.75:443/tcp 1416942644.593119 CHhAvVGS1DHFjwGM9 192.168.4.149 49422 23.92.19.75 443 www.pantz.org Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 Fi6J8q3lDJpbQWAnvi application/x-x509-user-cert 23.92.19.75:443/tcp
#close 2016-08-05-13-22-37 #close 2017-05-02-20-45-26
#separator \x09 #separator \x09
#set_separator , #set_separator ,
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path intel #path intel
#open 2016-08-05-13-22-37 #open 2017-05-02-20-45-27
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p seen.indicator seen.indicator_type seen.where seen.node matched sources fuid file_mime_type file_desc #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p seen.indicator seen.indicator_type seen.where seen.node matched sources fuid file_mime_type file_desc
#types time string addr port addr port string enum enum string set[enum] set[string] string string string #types time string addr port addr port string enum enum string set[enum] set[string] string string string
1170717505.735416 CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 2c322ae2b7fe91391345e070b63668978bb1c9da Intel::CERT_HASH X509::IN_CERT bro Intel::CERT_HASH source1 FeCwNK3rzqPnZ7eBQ5 application/pkix-cert 194.127.84.106:443/tcp 1170717505.735416 CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 2c322ae2b7fe91391345e070b63668978bb1c9da Intel::CERT_HASH X509::IN_CERT bro Intel::CERT_HASH source1 FeCwNK3rzqPnZ7eBQ5 application/x-x509-user-cert 194.127.84.106:443/tcp
1170717505.934612 CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 www.dresdner-privat.de Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 FeCwNK3rzqPnZ7eBQ5 - - 1170717505.934612 CHhAvVGS1DHFjwGM9 192.150.187.164 58868 194.127.84.106 443 www.dresdner-privat.de Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 FeCwNK3rzqPnZ7eBQ5 - -
1170717508.883051 ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 2c322ae2b7fe91391345e070b63668978bb1c9da Intel::CERT_HASH X509::IN_CERT bro Intel::CERT_HASH source1 FjkLnG4s34DVZlaBNc application/pkix-cert 194.127.84.106:443/tcp 1170717508.883051 ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 2c322ae2b7fe91391345e070b63668978bb1c9da Intel::CERT_HASH X509::IN_CERT bro Intel::CERT_HASH source1 FjkLnG4s34DVZlaBNc application/x-x509-user-cert 194.127.84.106:443/tcp
1170717509.082241 ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 www.dresdner-privat.de Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 FjkLnG4s34DVZlaBNc - - 1170717509.082241 ClEkJM2Vm5giqnMf4h 192.150.187.164 58869 194.127.84.106 443 www.dresdner-privat.de Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 FjkLnG4s34DVZlaBNc - -
1170717511.909717 C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 2c322ae2b7fe91391345e070b63668978bb1c9da Intel::CERT_HASH X509::IN_CERT bro Intel::CERT_HASH source1 FQXAWgI2FB5STbrff application/pkix-cert 194.127.84.106:443/tcp 1170717511.909717 C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 2c322ae2b7fe91391345e070b63668978bb1c9da Intel::CERT_HASH X509::IN_CERT bro Intel::CERT_HASH source1 FQXAWgI2FB5STbrff application/x-x509-user-cert 194.127.84.106:443/tcp
1170717512.108799 C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 www.dresdner-privat.de Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 FQXAWgI2FB5STbrff - - 1170717512.108799 C4J4Th3PJpwUYZZ6gc 192.150.187.164 58870 194.127.84.106 443 www.dresdner-privat.de Intel::DOMAIN X509::IN_CERT bro Intel::DOMAIN source1 FQXAWgI2FB5STbrff - -
#close 2016-08-05-13-22-38 #close 2017-05-02-20-45-27

View file

@ -173,6 +173,7 @@
1437831799.764576 file_new 1437831799.764576 file_new
1437831799.764576 file_over_new_connection 1437831799.764576 file_over_new_connection
1437831799.764576 file_sniff 1437831799.764576 file_sniff
1437831799.764576 file_hash
1437831799.764576 x509_certificate 1437831799.764576 x509_certificate
1437831799.764576 x509_extension 1437831799.764576 x509_extension
1437831799.764576 x509_extension 1437831799.764576 x509_extension
@ -190,6 +191,7 @@
1437831799.764576 file_new 1437831799.764576 file_new
1437831799.764576 file_over_new_connection 1437831799.764576 file_over_new_connection
1437831799.764576 file_sniff 1437831799.764576 file_sniff
1437831799.764576 file_hash
1437831799.764576 x509_certificate 1437831799.764576 x509_certificate
1437831799.764576 x509_extension 1437831799.764576 x509_extension
1437831799.764576 x509_extension 1437831799.764576 x509_extension

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,17 @@
[[version=0, logid=\xa4\xb9\x09\x90\xb4\x18X\x14\x87\xbb\x13\xa2\xccgp\x0a<5\x98\x04\xf9\x1b\xdf\xb8\xe3w\xcd\x0e\xc8\x0d\xdc\x10, timestamp=1406997753366, sig_alg=3, hash_alg=4, signature=0D\x02 \x1cK\x82]\x95ng[\xdb\x04\x95K\xf6\xce\xf42>\x86zz2\xab\x18`t\xde\x08\xda\x05\x91L/\x02 sT\x1bn\x7f\xa1\xb0}\x11\xbc\xe6\xf3\x85/\x97f\x1a\xf7\x8a\xe4\x10%\x8f\x12\xf4o9\x0f\xd2\x9e\x18\xf0, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=h\xf6\x98\xf8\x1fd\x82\xbe:\x8c\xee\xb9(\x1dL\xfcqQ]g\x93\xd4D\xd1\x0ag\xac\xbbOO\xfb\xc4, timestamp=1407002457456, sig_alg=3, hash_alg=4, signature=0E\x02 2!\x148\x06\xd8r.\x000d\x1a\xe2\xe8mNZ\xe1\xd9B\x1e\x82K\x96%\x89\xd5&\x13\xd3\x9c\xfa\x02!\x00\x8f\x12(dQOD\xd5\x8c\x18b#\xb2C\x933\x05\xf3CU\xa1\xd9\xee\xcd\xc5q5\x91\xddI\xd1\x0b, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\xeeK\xbd\xb7u\xce`\xba\xe1Bi\x1f\xab\xe1\x9ef\xa3\x0f~_\xb0r\xd8\x83\x00\xc4{\x89z\xa8\xfd\xcb, timestamp=1410299366023, sig_alg=3, hash_alg=4, signature=0E\x02 )\x89\xd6\xb0S\xd3\xd2\xe9\x91\xbc\xf1\xb5@\xbe\x1e.\xe7\\xb4t'\xed\x8f\x9b\x02\xe9\xfa\xc2L\xba\xa2\xbe\x02!\x00\xafCdRq\x15)X@\x91\xc7\x08\x16\x96\x03\xa8s\xa5e\xa0l\xb8HVZ\xb6)\x83dm*\x9d, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\xa4\xb9\x09\x90\xb4\x18X\x14\x87\xbb\x13\xa2\xccgp\x0a<5\x98\x04\xf9\x1b\xdf\xb8\xe3w\xcd\x0e\xc8\x0d\xdc\x10, timestamp=1406997753366, sig_alg=3, hash_alg=4, signature=0D\x02 \x1cK\x82]\x95ng[\xdb\x04\x95K\xf6\xce\xf42>\x86zz2\xab\x18`t\xde\x08\xda\x05\x91L/\x02 sT\x1bn\x7f\xa1\xb0}\x11\xbc\xe6\xf3\x85/\x97f\x1a\xf7\x8a\xe4\x10%\x8f\x12\xf4o9\x0f\xd2\x9e\x18\xf0, source=SSL::SCT_OCSP_EXT, valid=T], [version=0, logid=h\xf6\x98\xf8\x1fd\x82\xbe:\x8c\xee\xb9(\x1dL\xfcqQ]g\x93\xd4D\xd1\x0ag\xac\xbbOO\xfb\xc4, timestamp=1407002457456, sig_alg=3, hash_alg=4, signature=0E\x02 2!\x148\x06\xd8r.\x000d\x1a\xe2\xe8mNZ\xe1\xd9B\x1e\x82K\x96%\x89\xd5&\x13\xd3\x9c\xfa\x02!\x00\x8f\x12(dQOD\xd5\x8c\x18b#\xb2C\x933\x05\xf3CU\xa1\xd9\xee\xcd\xc5q5\x91\xddI\xd1\x0b, source=SSL::SCT_OCSP_EXT, valid=T]]
Google 'Pilot' log, T
Google 'Aviator' log, T
Google 'Rocketeer' log, T
Google 'Pilot' log, T
Google 'Aviator' log, T
[[version=0, logid=\xa4\xb9\x09\x90\xb4\x18X\x14\x87\xbb\x13\xa2\xccgp\x0a<5\x98\x04\xf9\x1b\xdf\xb8\xe3w\xcd\x0e\xc8\x0d\xdc\x10, timestamp=1487726002208, sig_alg=3, hash_alg=4, signature=0F\x02!\x00\x89\x82s\x17\xd9\xcbo\xcf\xc3\xba\x91{\xeb\xe8\xf1\xbe\xc8)\x97\x1e\xe8A\x99P\x00\xaa\xb4\x15\xd97\x93\xca\x02!\x00\xca\xcd\xec\x9e\x12\xeed/v\xf5\xc32\xba\x92S\xe0 }\x85k\xe7\xd4TRp\xe8\x8d~\xba\x9d\x12\x16, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\xac;\x9a\xed\x7f\xa9gGW\x15\x9em}WVr\xf9\xd9\x81\x00\x94\x1e\x9b\xde\xff\xec\xa11;ux-, timestamp=1487726003188, sig_alg=1, hash_alg=4, signature=\x04\xed\x08\xca\x8e\x1b\x8ba$\xe5\xe8{Y\x96'+\x06\x86\x87o\x1a=i5\x91\xc3\xfd\xf6\xbe\xeao;\xc8\x1c\x01j\xc0\x14\xea\x06\xd3\xe3#w,\x07\x06\xc3\xd0\xdc\xf2L:\xb0{\xfd.\x00\xdf\xc2\xb8w(\xaak\xfe^\xa0\x05\xe1\x84\xad\x1a!\xf2@/J\xcc\xcb8\xbb\xfa`;CF\<e\x17\xdafE/zX\xeb\xd0y\x15[\xd5\xe2\xee\xaf\xf8k\xeeX\x92\xa48\x0c\xab\x15v\xa6\xa4\x00\xc5Sjo\xe9\xbcL\xde\x11\x1d\x93\x7f\x9b\xbe\xb1\x13\xfb\xf1\xcb\xfb4\x85\xf2j\xc1t\xb0\x82g;*\x05i\x99*h\xe1\xcc\x07\xd2u\xc8L\xd3\x97\xb9\x81[-\xd1\xff\x1e\xc0\xa4\x80^vv\xb8+\xc5q\xec\xc0\xe7\x90\x00\x11{\xfdY\xb4fk'{\xa4T\xf4HO\xfd\x1d\xf6\xce\xbe=\x08G\x91\xd54\x0a\x90\xe7\xd5\xeda\x8c\xeb|"\xc1r!\xd9\xfb\xbd~\xf8\xc1\x01\xb5@9|\x9e\x0ej\xd1S\x97\xa3\x0a\xf9h\x15\xd7}\x05\x8a\x1b+j\x13\xf5, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\x03\x01\x9d\xf3\xfd\x85\xa6\x9a\x8e\xbd\x1f\xac\xc6\xda\x9b\xa7>F\x97t\xfew\xf5y\xfcZ\x08\xb82\x8c\x1dk, timestamp=1487726024253, sig_alg=3, hash_alg=4, signature=0F\x02!\x00\x99\x8c\xa5+u\xe1t\x08\x0a\xa9!\xed)\x9b\xb6\xccx\x8d0VN,RZ2\xd93\xdc\xa7 \xa5\xd3\x02!\x00\xc8\xde\x96\x8d\x02\xd6\xfcx\xdbM \x06\x1cq\xe5\x10\xe3 \x18B\\x1d1\x88\xb0\xeb\xf3\xf2\x9b\x99X\xb4, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=V\x14\x06\x9a/\xd7\xc2\xec\xd3\xf5\xe1\xbdD\xb2>\xc7Fv\xb9\xbc\x99\x11\\xc0\xef\x94\x98U\xd6\x89\xd0\xdd, timestamp=1487726001197, sig_alg=3, hash_alg=4, signature=0E\x02 F\xc2\xfb\x02\xfd\xa3RNy_\x16^\xb54-S\x90\xdbK\x97\x87\x00\x93\xa1\x0d'\xc0<\xbeu\xc4\xab\x02!\x00\xb4\x93\xbb\xe2\xee\x14X\xd4\xcf\xa4\xc1\xd8\xcf\xdaAoaD\xf0\xbbM7\xdb\xb0\xec\xca\x0f\x18\xcbe\x8d\xe9, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\xeeK\xbd\xb7u\xce`\xba\xe1Bi\x1f\xab\xe1\x9ef\xa3\x0f~_\xb0r\xd8\x83\x00\xc4{\x89z\xa8\xfd\xcb, timestamp=1487726002855, sig_alg=3, hash_alg=4, signature=0D\x02 I\x06\xb4\x84Zo\xf49\x85\xd2\xbb\xc8\x8bb\x9b\xac\xbd\x84\x00\xf2f\xd0\x14\x0cV\x15_\xc7\x09&\xc1\x9f\x02 M\x0c\x05\x01ab\xe5\x97\xf9\xf8'\x02\xf4\x198\x97\xd2>xa\xc2\xda\xc1saw\xd8]\xc8\x97\xd6], source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\xbb\xd9\xdf\xbc\x1f\x8aq\xb5\x93\x94#\x97\xaa\x92{G8W\x95\x0a\xabR\xe8\x1a\x90\x96d6\x8e\x1e\xd1\x85, timestamp=1487726000774, sig_alg=3, hash_alg=4, signature=0E\x02!\x00\xb1\x1atJ4\x80\xbd\xc5\x97\x7f(\xae^N\xe3WE-AO\x14X\x0aB\x1e\xc4\xb36\x00TVg\x02 o1hk\xec\x9fFG\xa4\xd2&\x97>E\x87\x7f\xcf\x1c\xc8\xdb>j\xc9\xde\xf5\x1e\x97\xf8\xc3e\xcc\x11, source=SSL::SCT_TLS_EXT, valid=T], [version=0, logid=\xa4\xb9\x09\x90\xb4\x18X\x14\x87\xbb\x13\xa2\xccgp\x0a<5\x98\x04\xf9\x1b\xdf\xb8\xe3w\xcd\x0e\xc8\x0d\xdc\x10, timestamp=1487725321667, sig_alg=3, hash_alg=4, signature=0E\x02 S\xc6N8\xf0\x84\xe5\xc8\xf5C\x87\xf6\xedU\x10\x0b}u2\xd2\x08+\x04\xbbS\xf6a\xc1\xb0\x94\x04\xc3\x02!\x00\xf4\xa2g\xa5!_\xee\x13\xd5\x0f\xd1\xb2\xe8o\x99\x10m\xa9\x0f\xd7W\xd5IH\xaa\x89\xdews\xe3=\x95, source=SSL::SCT_X509_EXT, valid=T], [version=0, logid=V\x14\x06\x9a/\xd7\xc2\xec\xd3\xf5\xe1\xbdD\xb2>\xc7Fv\xb9\xbc\x99\x11\\xc0\xef\x94\x98U\xd6\x89\xd0\xdd, timestamp=1487725322003, sig_alg=3, hash_alg=4, signature=0D\x02 \x04\x9d.\x13Q\xed\xed\xf1l\x9f\xa1\x94\x9dd\xfe\x9c0V|\xb6\xa8|9L5/\xaa\x19\xc7*\xed\xcf\x02 0\x0e+\xe3\xa4S\xfe\x85\xa6X\xcc\x06\xf2\x13\xe9\x0a\x87\xa0I\xdf\x8dr\x13xb\x12\x8c\xe6\xdd\x8f\xa8\xde, source=SSL::SCT_X509_EXT, valid=T], [version=0, logid=\xeeK\xbd\xb7u\xce`\xba\xe1Bi\x1f\xab\xe1\x9ef\xa3\x0f~_\xb0r\xd8\x83\x00\xc4{\x89z\xa8\xfd\xcb, timestamp=1487725322768, sig_alg=3, hash_alg=4, signature=0F\x02!\x00\xd37.:`\x98\x08\xb8\xf8\xc0\xad\xb1z\xe2]\x00\xb8\x08"\x97\xc8P\xeb1\x97\x16\x95!\xd0T\xb5\xd6\x02!\x00\xfe\xb8\xa3\xbf\x12\xb6%\x97\x9b\x0f\x0f\x9fc\xccP\xa0\x07\x0c\xe9\xf2\xda\xe9\\x0a\x8e\xeag\x8a\x131\x96?, source=SSL::SCT_X509_EXT, valid=T], [version=0, logid=\xbb\xd9\xdf\xbc\x1f\x8aq\xb5\x93\x94#\x97\xaa\x92{G8W\x95\x0a\xabR\xe8\x1a\x90\x96d6\x8e\x1e\xd1\x85, timestamp=1487725321891, sig_alg=3, hash_alg=4, signature=0F\x02!\x00\xe7\x14'\xc8\x03?\xfc\xf1\xc6\x86\xe4g\xb6s\x034<\xf0\x96\xf0\xe0\x1a\xb8\x953\xe0\xf8U\x1d\x1c\xbf\xe6\x02!\x00\xcag\xf24\xcc\x86\x1aYd\xfb{\x82N\xeb,\xa3\xecu\xf1i\x01\xbc\xd4b\x1a\x9e\xa8\xc4\xca\x8f\x01\x8b, source=SSL::SCT_X509_EXT, valid=T]]
Google 'Pilot' log, T
Venafi log, T
Venafi Gen2 CT log, T
DigiCert Log Server, T
Google 'Rocketeer' log, T
Google 'Skydiver' log, T
Google 'Pilot' log, T
DigiCert Log Server, T
Google 'Rocketeer' log, T
Google 'Skydiver' log, T

View file

@ -0,0 +1,20 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ssl
#open 2017-03-22-01-52-35
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer validation_status valid_ct_logs valid_ct_operators
#types time string addr port addr port string string string string bool string string bool vector[string] vector[string] string string string string string count count
1484228945.191472 CHhAvVGS1DHFjwGM9 192.168.178.73 60640 97.107.139.108 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 secp256r1 ritter.vg F - http/1.1 T FDWgotac24NQJKrRi,FUHPFD4bNbAmVvzf99,FL5BECVkzTuWWefyh (empty) CN=ritter.vg,OU=PositiveSSL,OU=Domain Control Validated CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - ok 3 1
#close 2017-03-22-01-52-35
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ssl
#open 2017-03-22-01-52-36
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer validation_status valid_ct_logs valid_ct_operators
#types time string addr port addr port string string string string bool string string bool vector[string] vector[string] string string string string string count count
1490146178.647622 CHhAvVGS1DHFjwGM9 192.168.17.58 51995 97.107.139.108 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 secp256r1 ritter.vg F - h2 T Fui6LM65IdSB9LD25,FIwxeCtbWPXg98zO1 (empty) CN=ritter.vg,O=Tom Ritter\\, LLC,L=Urbana,ST=Illinois,C=US,serialNumber=0600438893,jurisdictionST=New Jersey,jurisdictionC=US,businessCategory=Private Organization CN=DigiCert SHA2 Extended Validation Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US - - ok 6 3
#close 2017-03-22-01-52-36

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,62 @@
# @TEST-EXEC: bro -r $TRACES/tls/certificate-with-sct.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
@load protocols/ssl/validate-certs
redef SSL::ssl_store_valid_chain = T;
export {
type LogInfo: record {
version: count;
logid: string;
timestamp: count;
sig_alg: count;
hash_alg: count;
signature: string;
};
}
redef record SSL::Info += {
ct_proofs: vector of LogInfo &default=vector();
};
event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string)
{
print version, SSL::ct_logs[logid]$description, double_to_time(timestamp/1000.0), hash_algorithm, signature_algorithm;
if ( |f$conns| != 1 )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 )
return;
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = LogInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_algorithm, $hash_alg=hash_algorithm, $signature=signature);
}
event ssl_established(c: connection)
{
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 )
return;
if ( |c$ssl$valid_chain| < 2 )
return;
local cert = c$ssl$cert_chain[0]$x509$handle;
local issuer_key_hash = x509_spki_hash(c$ssl$valid_chain[1], 4);
for ( i in c$ssl$ct_proofs )
{
local log = c$ssl$ct_proofs[i];
print "Verify of", SSL::ct_logs[log$logid]$description, sct_verify(cert, log$logid, SSL::ct_logs[log$logid]$key, log$signature, log$timestamp, log$hash_alg, issuer_key_hash);
print "Bad verify of", SSL::ct_logs[log$logid]$description, sct_verify(cert, log$logid, SSL::ct_logs[log$logid]$key, log$signature, log$timestamp+1, log$hash_alg, issuer_key_hash);
}
}

View file

@ -0,0 +1,31 @@
# @TEST-EXEC: bro -r $TRACES/tls/signed_certificate_timestamp.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event x509_ocsp_ext_signed_certificate_timestamp(f: fa_file, version: count, logid: string, timestamp: count, hash_algorithm: count, signature_algorithm: count, signature: string)
{
print version, SSL::ct_logs[logid]$description, double_to_time(timestamp/1000.0), hash_algorithm, signature_algorithm;
if ( |f$conns| != 1 )
return;
for ( cid in f$conns )
{
if ( ! f$conns[cid]?$ssl )
return;
local c = f$conns[cid];
}
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 )
return;
local cert = c$ssl$cert_chain[0]$x509$handle;
print "Verify of", SSL::ct_logs[logid]$description, sct_verify(cert, logid, SSL::ct_logs[logid]$key, signature, timestamp, hash_algorithm);
print "Bad verify of", SSL::ct_logs[logid]$description, sct_verify(cert, logid, SSL::ct_logs[logid]$key, signature, timestamp+1, hash_algorithm);
}

View file

@ -0,0 +1,43 @@
# This tests a normal OCSP request sent through HTTP GET
# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-http-get.pcap %INPUT
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_extension(f: fa_file, ext: X509::Extension, global_resp: bool)
{
print "extension: ", ext, global_resp;
}
event ocsp_request(f: fa_file, version: count, requestorName: string)
{
print "request", version, requestorName;
}
event ocsp_request_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string)
{
print "request cert", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber;
}
event ocsp_response_status(f: fa_file, status: string)
{
print "ocsp_response_status", status;
}
event ocsp_response_bytes(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector)
{
print "ocsp_response_bytes", status, version, responderId, producedAt, signatureAlgorithm;
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
print "ocsp_response_certificate", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber, certStatus, revoketime, revokereason, thisUpdate, nextUpdate;
}

View file

@ -0,0 +1,42 @@
# This tests a OCSP request missing response
# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-request-only.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_extension(f: fa_file, ext: X509::Extension, global_resp: bool)
{
print "extension: ", ext, global_resp;
}
event ocsp_request(f: fa_file, version: count, requestorName: string)
{
print "request", version, requestorName;
}
event ocsp_request_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string)
{
print "request cert", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber;
}
event ocsp_response_status(f: fa_file, status: string)
{
print "ocsp_response_status", status;
}
event ocsp_response_bytes(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector)
{
print "ocsp_response_bytes", status, version, responderId, producedAt, signatureAlgorithm;
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
print "ocsp_response_certificate", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber, certStatus, revoketime, revokereason, thisUpdate, nextUpdate;
}

View file

@ -0,0 +1,43 @@
# This tests a pair of normal OCSP request and response
# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-request-response.pcap %INPUT
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_extension(f: fa_file, ext: X509::Extension, global_resp: bool)
{
print "extension: ", ext, global_resp;
}
event ocsp_request(f: fa_file, version: count, requestorName: string)
{
print "request", version, requestorName;
}
event ocsp_request_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string)
{
print "request cert", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber;
}
event ocsp_response_status(f: fa_file, status: string)
{
print "ocsp_response_status", status;
}
event ocsp_response_bytes(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector)
{
print "ocsp_response_bytes", status, version, responderId, producedAt, signatureAlgorithm;
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
print "ocsp_response_certificate", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber, certStatus, revoketime, revokereason, thisUpdate, nextUpdate;
}

View file

@ -0,0 +1,43 @@
# This tests a normal OCSP response missing request
# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-response-only.pcap %INPUT
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_extension(f: fa_file, ext: X509::Extension, global_resp: bool)
{
print "extension: ", ext, global_resp;
}
event ocsp_request(f: fa_file, version: count, requestorName: string)
{
print "request", version, requestorName;
}
event ocsp_request_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string)
{
print "request cert", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber;
}
event ocsp_response_status(f: fa_file, status: string)
{
print "ocsp_response_status", status;
}
event ocsp_response_bytes(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector)
{
print "ocsp_response_bytes", status, version, responderId, producedAt, signatureAlgorithm;
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
print "ocsp_response_certificate", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber, certStatus, revoketime, revokereason, thisUpdate, nextUpdate;
}

View file

@ -0,0 +1,43 @@
# This tests OCSP response with revocation
# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-revoked.pcap %INPUT
# @TEST-EXEC: btest-diff ocsp.log
# @TEST-EXEC: btest-diff .stdout
@load files/x509/log-ocsp
event bro_init()
{
Files::register_for_mime_type(Files::ANALYZER_OCSP_REQUEST, "application/ocsp-request");
Files::register_for_mime_type(Files::ANALYZER_OCSP_REPLY, "application/ocsp-response");
}
event ocsp_extension(f: fa_file, ext: X509::Extension, global_resp: bool)
{
print "extension: ", ext, global_resp;
}
event ocsp_request(f: fa_file, version: count, requestorName: string)
{
print "request", version, requestorName;
}
event ocsp_request_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string)
{
print "request cert", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber;
}
event ocsp_response_status(f: fa_file, status: string)
{
print "ocsp_response_status", status;
}
event ocsp_response_bytes(f: fa_file, resp_ref: opaque of ocsp_resp, status: string, version: count, responderId: string, producedAt: time, signatureAlgorithm: string, certs: x509_opaque_vector)
{
print "ocsp_response_bytes", status, version, responderId, producedAt, signatureAlgorithm;
}
event ocsp_response_certificate(f: fa_file, hashAlgorithm: string, issuerNameHash: string, issuerKeyHash: string, serialNumber: string, certStatus: string, revoketime: time, revokereason: string, thisUpdate: time, nextUpdate: time)
{
print "ocsp_response_certificate", hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber, certStatus, revoketime, revokereason, thisUpdate, nextUpdate;
}

View file

@ -0,0 +1,39 @@
# @TEST-EXEC: bro -r $TRACES/tls/signed_certificate_timestamp.pcap %INPUT
# @TEST-EXEC: btest-diff .stdout
export {
type LogInfo: record {
version: count;
logid: string;
timestamp: count;
sig_alg: count;
hash_alg: count;
signature: string;
};
}
redef record SSL::Info += {
ct_proofs: vector of LogInfo &default=vector();
};
event ssl_extension_signed_certificate_timestamp(c: connection, is_orig: bool, version: count, logid: string, timestamp: count, signature_and_hashalgorithm: SSL::SignatureAndHashAlgorithm, signature: string)
{
print version, SSL::ct_logs[logid]$description, double_to_time(timestamp/1000.0), signature_and_hashalgorithm;
c$ssl$ct_proofs[|c$ssl$ct_proofs|] = LogInfo($version=version, $logid=logid, $timestamp=timestamp, $sig_alg=signature_and_hashalgorithm$SignatureAlgorithm, $hash_alg=signature_and_hashalgorithm$HashAlgorithm, $signature=signature);
}
event ssl_established(c: connection)
{
if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || ! c$ssl$cert_chain[0]?$x509 )
return;
local cert = c$ssl$cert_chain[0]$x509$handle;
for ( i in c$ssl$ct_proofs )
{
local log = c$ssl$ct_proofs[i];
print "Verify of", SSL::ct_logs[log$logid]$description, sct_verify(cert, log$logid, SSL::ct_logs[log$logid]$key, log$signature, log$timestamp, log$hash_alg);
print "Bad verify of", SSL::ct_logs[log$logid]$description, sct_verify(cert, log$logid, SSL::ct_logs[log$logid]$key, log$signature, log$timestamp+1, log$hash_alg);
}
}

View file

@ -0,0 +1,21 @@
# @TEST-EXEC: bro -r $TRACES/tls/signed_certificate_timestamp.pcap $SCRIPTS/external-ca-list.bro %INPUT
# @TEST-EXEC: cat ssl.log > ssl-all.log
# @TEST-EXEC: bro -r $TRACES/tls/signed_certificate_timestamp-2.pcap $SCRIPTS/external-ca-list.bro %INPUT
# @TEST-EXEC: cat ssl.log >> ssl-all.log
# @TEST-EXEC: btest-diff .stdout
# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-x509-names | $SCRIPTS/diff-remove-timestamps" btest-diff ssl-all.log
@load protocols/ssl/validate-sct.bro
module SSL;
event ssl_established(c: connection)
{
print c$ssl$ct_proofs;
for ( i in c$ssl$ct_proofs )
{
local proof = c$ssl$ct_proofs[i];
local log = SSL::ct_logs[proof$logid];
print log$description, proof$valid;
}
}