Saturday, November 10, 2018

Visualizing your Zeek (Bro) data with Splunk - x509.log (x509 Certificate logs)

Looking at x509 certificate information can be a good sign of the type of secure communication occuring in your environment. On most days you should expect to see some of the more popular Certification Authorities (CA) within your environment. Seeing a "strange" name maybe enough to trigger you to investigate that communication.

Let's first see the available fields as we have have always done before.

root@securitynik-host:/opt/bro/logs/current# bro-cut -C < x509.log | head --lines=10 --verbose
#fields ts      id      certificate.version     certificate.serial      certificate.subject     certificate.issuer      certificate.not_valid_before    certificate.not_valid_after   certificate.key_alg     certificate.sig_alg     certificate.key_type    certificate.key_length  certificate.exponent    certificate.curve     san.dns san.uri san.email       san.ip  basic_constraints.ca    basic_constraints.path_len
#types  time    string  count   string  string  string  time    time    string  string  string  count   string  string  vector[string]  vector[string]  vector[string]        vector[addr]    bool    count
1541376003.219940       FxRAX42VHMcyayZAi8      3       070FD92417F460AC        CN=*.google.com,O=Google LLC,L=Mountain View,ST=California,C=US CN=Google Internet Authority G3,O=Google Trust Services,C=US  1539704220.000000       1546965420.000000       id-ecPublicKey  sha256WithRSAEncryption ecdsa   256     -    prime256v1       *.google.com,*.android.com,*.appengine.google.com,*.cloud.google.com,*.g.co,*.gcp.gvt2.com,*.ggpht.cn,*.google-analytics.com,*.google.ca,*.google.cl,*.google.co.in,*.google.co.jp,*.google.co.uk,*.google.com.ar,*.google.com.au,*.google.com.br,*.google.com.co,*.google.com.mx,*.google.com.tr,*.google.com.vn,*.google.de,*.google.es,*.google.fr,*.google.hu,*.google.it,*.google.nl,*.google.pl,*.google.pt,*.googleadapis.com,*.googleapis.cn,*.googlecommerce.com,*.googlevideo.com,*.gstatic.cn,*.gstatic.com,*.gstaticcnapps.cn,*.gvt1.com,*.gvt2.com,*.metric.gstatic.com,*.urchin.com,*.url.google.com,*.youtube-nocookie.com,*.youtube.com,*.youtubeeducation.com,*.youtubekids.com,*.yt.be,*.ytimg.com,android.clients.google.com,android.com,developer.android.google.cn,developers.android.google.cn,g.co,ggpht.cn,goo.gl,google-analytics.com,google.com,googlecommerce.com,source.android.google.cn,urchin.com,www.goo.gl,youtu.be,youtube.com,youtubeeducation.com,youtubekids.com,yt.be -       -       -       F       -
1541376005.435851       FjKF7e2fCp33DNHup1      3       2D0000CDC4C84DD1293BFC9BB400000000CDC4  CN=*.msedge.net CN=Microsoft IT TLS CA 5,OU=Microsoft IT,O=Microsoft Corporation,L=Redmond,ST=Washington,C=US 1507851234.000000       1570923234.000000       rsaEncryption   sha256WithRSAEncryption rsa     2048    65537-*.msedge.net,*.a-msedge.net,a-msedge.net,b-msedge.net,*.b-msedge.net,c-msedge.net,*.c-msedge.net,dc-msedge.net,*.dc-msedge.net,*.lbas.msedge.net,*.test.msedge.net,*.azp.footprintdns.com,*.footprintdns.com,*.clo.footprintdns.com,*.any.footprintdns.com,*.nrb.footprintdns.com,*.perf.msedge.net   -       -       -    --

Now that the fields are identified, this Splunk search will help us to extract these fields.

index=_* OR index=* sourcetype=Bro-Security-Monitoring source="/opt/bro/logs/current/x509.log" NOT "#fields" 
|  rex field=_raw "(?<ts>.*?\t)(?<id>.*?\t)(?<certificate_version>.*?\t)(?<certificate_serial>.*?\t)(?<certificate_subject>.*?\t)(?<certificate_issuer>.*?\t)(?<certificate_not_valid_before>.*?\t)(?<certificate_not_valid_after>.*?\t)(?<certificate_key_alg>.*?\t)(?<certificate_sig_alg>.*?\t)(?<certificate_key_type>.*?\t)(?<certificate_key_length>.*?\t)(?<certificate_exponent>.*?\t)(?<certificate_curve>.*?\t)(?<san_dns>.*?\t)(?<san_uri>.*?\t)(?<san_email>.*?\t)(?<san_ip>.*?\t)(?<basic_constraints_ca>.*?\t)" 
|  stats count by ts,id,certificate_version,certificate_serial,certificate_subject,certificate_issuer,certificate_not_valid_before,certificate_not_valid_after,certificate_key_alg,certificate_sig_alg,certificate_key_type,certificate_key_length,certificate_exponent,certificate_curve,san_dns,san_uri,san_email,san_ip,basic_constraints_ca



Now that we have those fields extracted, like always, let pick on one of the fields. In this example, let's look at the certificate subject.

index=_* OR index=* sourcetype=Bro-Security-Monitoring source="/opt/bro/logs/current/x509.log" NOT "#fields" 
|  rex field=_raw "(?<ts>.*?\t)(?<id>.*?\t)(?<certificate_version>.*?\t)(?<certificate_serial>.*?\t)(?<certificate_subject>.*?\t)(?<certificate_issuer>.*?\t)(?<certificate_not_valid_before>.*?\t)(?<certificate_not_valid_after>.*?\t)(?<certificate_key_alg>.*?\t)(?<certificate_sig_alg>.*?\t)(?<certificate_key_type>.*?\t)(?<certificate_key_length>.*?\t)(?<certificate_exponent>.*?\t)(?<certificate_curve>.*?\t)(?<san_dns>.*?\t)(?<san_uri>.*?\t)(?<san_email>.*?\t)(?<san_ip>.*?\t)(?<basic_constraints_ca>.*?\t)" 
|  stats count by certificate_subject 
|  sort - count


























As always, we take a look at those least seen issuers.

index=_* OR index=* sourcetype=Bro-Security-Monitoring source="/opt/bro/logs/current/x509.log" NOT "#fields" 
|  rex field=_raw "(?<ts>.*?\t)(?<id>.*?\t)(?<certificate_version>.*?\t)(?<certificate_serial>.*?\t)(?<certificate_subject>.*?\t)(?<certificate_issuer>.*?\t)(?<certificate_not_valid_before>.*?\t)(?<certificate_not_valid_after>.*?\t)(?<certificate_key_alg>.*?\t)(?<certificate_sig_alg>.*?\t)(?<certificate_key_type>.*?\t)(?<certificate_key_length>.*?\t)(?<certificate_exponent>.*?\t)(?<certificate_curve>.*?\t)(?<san_dns>.*?\t)(?<san_uri>.*?\t)(?<san_email>.*?\t)(?<san_ip>.*?\t)(?<basic_constraints_ca>.*?\t)" 
|  stats count by certificate_issuer
|  sort - count 
| rare limit=50 certificate_issuer
























Let's wrap this up by looking at the DNS information within these certificates.

This filter allows us to extract that dns information. As you can see in the search filter, I have whitelisted out some domains.

<!-- HTML generated using hilite.me --><div style="background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #ffffff">index=_* OR index=* sourcetype=Bro-Security-Monitoring source=&quot;/opt/bro/logs/current/x509.log&quot; NOT(&quot;#fields&quot; OR &quot;.comodo.com&quot; OR &quot;.google.com&quot; OR &quot;.microsoft.com&quot; OR &quot;.windows.com&quot;) </span>
<span style="color: #ffffff">|  rex field=_raw &quot;(?&lt;ts&gt;.*?\t)(?&lt;id&gt;.*?\t)(?&lt;certificate_version&gt;.*?\t)(?&lt;certificate_serial&gt;.*?\t)(?&lt;certificate_subject&gt;.*?\t)(?&lt;certificate_issuer&gt;.*?\t)(?&lt;certificate_not_valid_before&gt;.*?\t)(?&lt;certificate_not_valid_after&gt;.*?\t)(?&lt;certificate_key_alg&gt;.*?\t)(?&lt;certificate_sig_alg&gt;.*?\t)(?&lt;certificate_key_type&gt;.*?\t)(?&lt;certificate_key_length&gt;.*?\t)(?&lt;certificate_exponent&gt;.*?\t)(?&lt;certificate_curve&gt;.*?\t)(?&lt;san_dns&gt;.*?\t)(?&lt;san_uri&gt;.*?\t)(?&lt;san_email&gt;.*?\t)(?&lt;san_ip&gt;.*?\t)(?&lt;basic_constraints_ca&gt;.*?\t)&quot; </span>
<span style="color: #ffffff">|  stats count by san_dns</span>
<span style="color: #ffffff">|  sort -count</span>
</pre></div>




















Ok then. That's it for this series. If you are reading this and would like me to extract other logs, feel free to drop me a line.

The next set of posts on Zeek (Bro) will more than likely be around signatures and scripts.

Hope you enjoyed this series.

Posts in this series:
Visualizing your Zeek (Bro) data with Splunk - The Setup
Visualizing your Zeek (Bro) data with Splunk - conn.log (connection logs)
Visualizing your Zeek (Bro) data with Splunk - http.log (http logs)
Visualizing your Zeek (Bro) data with Splunk - dns.log (connection logs)
Visualizing your Zeek (Bro) data with Splunk - x509.log (connection logs)

No comments:

Post a Comment