Similarly to the previous posts, we need to understand the structure of the DNS logs before we begin to parse it. Let's do that.
root@securitynik-host:/opt/bro/logs/current# bro-cut -C < dns.log | head --lines=10 --verbose #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id rtt query qclass qclass_name qtypeqtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected #types time string addr port addr port enum count interval string count string count string count string bool bool bool bool count vector[string] vector[interval] bool 1541376001.059940 CvWBmNcrGUcDWf60g 192.168.0.26 52542 208.67.222.222 53 udp 43942 0.047960 ssl.gstatic.com 1 C_INTERNET 28 AAAA 0 NOERROR F F T T 0 2607:f8b0:400b:80e::2003 300.000000 F 1541376003.063949 C2xxe74mFxdHKzMfHj 192.168.0.26 50157 208.67.222.222 53 udp 1261 0.039924 play.google.com 1 C_INTERNET 1 A 0 NOERROR F F T T 0 172.217.0.110 300.000000 F
Let's now identify the Splunk query that will extract these fields.
index=_* OR index=* sourcetype=Bro-Security-Monitoring source="/opt/bro/logs/current/dns.log" NOT "#fields" NOT "\\x00\\x00\\x00\\x00" NOT "ip6.arpa" | rex field=_raw "(?<ts>.*?\t)(?<uid>.*?\t)(?<orig_h>.*?\t)(?<orig_p>.*?\t)(?<resp_h>.*?\t)(?<resp_p>.*?\t)(?<proto>.*?\t)(?<trans_id>.*?\t)(?<rtt>.*?\t)(?<query>.*?\t)(?<qclass>.*?\t)(?<qclass_name>.*?\t)(?<qtype>.*?\t)(?<qtype_name>.*?\t)(?<rcode>.*?\t)(?<rcode_name>.*?\t)(?<aa>.*?\t)(?<tc>.*?\t)(?<rd>.*?\t)(?<ra>.*?\t)(?<z>.*?\t)(?<answers>.*?\t)(?<ttls>.*?\t)" | stats count by ts,uid,orig_h,orig_p,resp_h,resp_p,proto,trans_id,rtt,query,qclass,qclass_name,qtype,qtype_name,rcode,rcode_name,aa,tc,rd,ra,z,answers,ttls
Now that we have all the fields extracted, as we were able to do previously, we can now obtain statistics on specific fields. Let's first take a look at the top 50 domains seen in our "dns.log" file.
index=_* OR index=* sourcetype=Bro-Security-Monitoring source="/opt/bro/logs/current/dns.log" NOT "#fields" NOT "\\x00\\x00\\x00\\x00" NOT ".arpa" | rex field=_raw "(?<ts>.*?\t)(?<uid>.*?\t)(?<orig_h>.*?\t)(?<orig_p>.*?\t)(?<resp_h>.*?\t)(?<resp_p>.*?\t)(?<proto>.*?\t)(?<trans_id>.*?\t)(?<rtt>.*?\t)(?<query>.*?\t)(?<qclass>.*?\t)(?<qclass_name>.*?\t)(?<qtype>.*?\t)(?<qtype_name>.*?\t)(?<rcode>.*?\t)(?<rcode_name>.*?\t)(?<aa>.*?\t)(?<tc>.*?\t)(?<rd>.*?\t)(?<ra>.*?\t)(?<z>.*?\t)(?<answers>.*?\t)(?<ttls>.*?\t)" | stats count by query | sort -count limit=50
As always, similar to how you pay attention to the top domains seen, it is also important to look at the least seen. Let's use the following query to get that information. Remember, unique values can stand out in such a way that makes you wonder why it is there.
index=_* OR index=* sourcetype=Bro-Security-Monitoring source="/opt/bro/logs/current/dns.log" NOT "#fields" NOT "\\x00\\x00\\x00\\x00" NOT ".arpa" | rex field=_raw "(?<ts>.*?\t)(?<uid>.*?\t)(?<orig_h>.*?\t)(?<orig_p>.*?\t)(?<resp_h>.*?\t)(?<resp_p>.*?\t)(?<proto>.*?\t)(?<trans_id>.*?\t)(?<rtt>.*?\t)(?<query>.*?\t)(?<qclass>.*?\t)(?<qclass_name>.*?\t)(?<qtype>.*?\t)(?<qtype_name>.*?\t)(?<rcode>.*?\t)(?<rcode_name>.*?\t)(?<aa>.*?\t)(?<tc>.*?\t)(?<rd>.*?\t)(?<ra>.*?\t)(?<z>.*?\t)(?<answers>.*?\t)(?<ttls>.*?\t)" | rare limit=50 query
Now that's it for visualizing Zeek (Bro) DNS data. See you in the next post where we look at x509 logs.
References:
https://www.opendns.com/about/innovations/dnscrypt/
https://www.cloudflare.com/learning/dns/what-is-1.1.1.1/
https://www.rfc-editor.org/rfc/rfc7858.txt
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