====== Wireshark ====== Show all DNS queries from local IP that are for a specific FQDN. **NOTE**: This will obviously not show the return queries as we are only showing outbound requests. dns and ip.src==192.168.1.10 and dns.qry.name == "example.com" dns.qry.name == "test.com" or dns.qry.name == "example.com" Show HTTPS sites visited tls.handshake.type == 1 Filter by specific HTTPS site tls.handshake.extensions_server_name == "microsoft.com" List A record queries/responses dns.qry-type == 1 Other types: * AAAA = 28 * TXT = 16 * NS = 2 * PTR = 12 * CNAME = 5 * HTTPS = 65 * MX = 15 Full list [[https://en.wikipedia.org/wiki/List_of_DNS_record_types|here]]. To get just queries (and not responses) add the following && (dns.count.answers == 0) To get just responses(and not queries) add the following && (dns.count.answers > 0) ===== General Filters ===== Search Wireshark for packets that contain an IP address that are results of a DNS query. ip.addr == 1.2.3.4 ip.src == 1.2.3.4 ip.dst == 1.2.3.4 tcp.port eq 25 or icmp udp.port eq 53 ip.src==192.168.0.0/16 and ip.dst==192.168.0.0/16 udp.stream eq ${udp.stream} tcp.stream eq ${tcp.stream} ===== DHCP ===== Filter queries based on the client MAC in the "client" field in the DHCP request. dhcp.hw.mac_addr ===== DNS Filtering ===== Filter just DNS queries dns Filter DNS from IP and to IP dns and (ip.src==10.42.0.174 and ip.dst==10.43.0.10) Filter both directions of flow from client to server. dns and (ip.src==10.42.0.174 and ip.dst==10.43.0.10) or (ip.dst==10.42.0.174 and ip.src==10.43.0.10) Filter based on IP response to A record request dns.a == 1.2.3.4 Filter by specific query dns.qry.name == "sinkhole.paloaltonetworks.com" Filter by query that contains string dns.qry.name contains "paloaltonetworks.com" Filter for DNS queries only dns.flags.response == 0 Filter for DNS responses only dns.flags.response == 1 Filter by DNS transaction ID (where XX is the transaction ID) dns.id eq XX Filter for Zone Transfers dns.qry.type in {251 252} or dns.flags.opcode eq 4 Filter by DNS Option Codes standard queries: dns.flags.opcode == 0 inverse queries: dns.flags.opcode == 1 server status requests: dns.flags.opcode == 2 zone change notifications: dns.flags.opcode == 4 dynamic updates: dns.flags.opcode == 5 Filter by recursive query: dns.flags.recdesired == 1 Filter by non-recursive query: dns.flags.recdesired == 0 ===== Filtering ===== Capture all DNS queries (non-responses) directed to the DNS servers: ((ip.dst == 10.10.10.10 || ip.dst == 10.10.11.11 ) && (dns.flags.response == 0)) && (dns.flags.opcode == 0) The filtered data was exported to a plain text file for further processing. Total DNS Queries Captured: wc -l queries.txt Top 30 Queried Domains: less queries.txt | awk '{split($8,a,".");b=length(a);print a[b-3]"."a[b-2]"."a[b-1]"."a[b]}'| sort | uniq -c | sort -nr | head -30 Top 30 Querying Clients: less queries.txt | awk '{print $4}'|sort | uniq -c | sort -nr | head -30 Top FQDNs Queried by the Top 5 Clients: grep '10.10.10.10\|10.10.10.2\|10.10.10.3\|10.10.10.4\|10.10.10.5' queries.txt | awk '{print $8}'|sort | uniq -c | sort -nr | head -30 Top Domains Queried by the Top 5 Clients: grep '10.10.10.10\|10.10.10.2\|10.10.10.3\|10.10.10.4\|10.10.10.5' queries.txt | awk '{split($8,a,".");b=length(a);print a[b-3]"."a[b-2]"."a[b-1]"."a[b]}'| sort | uniq -c | sort -nr | head -30