Exercise 1:
Description: There is a high volume of activity between 192.168.11.162 and 192.168.11.101 using UDP port 53. Can you explain what this is? Is the attack successful?

The first packet is a DNS query for the A record (or IPv4 address) of the domain www.evilname.com.
This query is followed by several DNS responses which is very suspicious as normally one query is followed by one dns response packet. The response should match the query ID so that the client can match it to their request.
We see that the transaction ID for our DNS query is 0x2870

The DNS response matching this ID is packet 118:

The question is: what are these other 100 DNS response packets? DNS response packet number 118 was sent from the same MAC address that was listed as the receiver in the original DNS query. In contrast, the other 100 response packets came from a different MAC address. This looks like a potential DNS cache poisoning attack as multiple spoofed DNS responses begin arriving from 192.168.11.101 with a different mac address: 5a:92:eb:81:00:00. These packets also appear to respond to the www.evilname.com query, but their transaction ids do not match the original query. They start at 0x0001 and increase incrementally.
This behavior indicates that the attacker was attempting to guess the correct transaction id before the legitimate dns response arrived. This type of brute-force guessing is typical in dns cache poisoning attacks. In this case, the attack failed because the real server responded with the correct transaction id before the spoofed responses could match it.
Exercise 2:
Investigate dns packet behavior by identifying anomalies or unexpected response codes in the packet capture file dns.pcap
.
Filter 1: identify dns queries that contain more than one question, which is considered abnormal. Craft a filter to detect packets with multiple dns queries in a single request.
I used tcpdump with berkeley packet filters to inspect specific fields in the dns header, particularly those found at udp offsets 10 and 11, where dns flags and return codes are located. I created a filter that looks for udp traffic on port 53 (dns), verifies the packet is a query (not a response), and checks that the number of questions is greater than one:

We find one packet with two questions contained in a DNS query.
Filter 2: detect dns responses with non-zero return codes by using both tcpdump and tshark. a non-zero return code in a dns response can indicate issues like a name resolution failure (e.g., nxdomain) or other errors, and is often worth investigating.

Exercise 3
Write a custom snort rule to detect dns queries targeting the domain “amazon.com”. The goal is to identify these queries by using both the content keyword to match the domain name and the byte_test operator to check for a valid query structure.
To get started with this custom rule, we know that Snort 3 has a dns service header already defined. Therefore, we can start with something like “alert dns ()”
Now, we can think on how to properly add a content option to detect dns queries for the domain “amazon.com”. Instead of searching for the plain-text domain name, i had to account for how dns encodes names—using length markers and sometimes compression techniques to make the query as small as possible. I began with a simple content match and gradually refined it to target the specific portion of the dns payload. I also used the pipe symbols to include raw byte values, ensuring my content match aligned with the encoded format of the dns query.

Let’s test this rule:

The rules triggers but we see that some of these packets are dns responses that need to be filtered out. In order to do this, I used the byte_test keyword in snort to determine whether a dns packet is a query or a response. The query/response (qr) flag is found in byte offset 2 of the dns header. Specifically, the qr bit is the highest bit in that byte. To detect this bit, i needed to use byte_test in combination with a bitmask (0x80) to evaluate whether the qr bit was set.

Let’s test it to make sure that this updated alert filters out the DNS responses when triggered:

It did. The custom rule is now complete.