Blog

  • DNS

    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.









  • HTTP

    Overview

    In this lab, I explored the intricacies of the HTTP protocol while gaining practical experience with network traffic analysis and intrusion detection systems (IDS), specifically Snort. The goal was to extract and analyze HTTP traffic captured from a live network segment, then prepare the data for further inspection using IDS tools.

    Objectives

    The lab focused on:

    • Deepening understanding of the HTTP protocol and how it manifests in raw packet data.
    • Practicing the use of IDS rule sets related to HTTP activity.
    • Preparing packet captures for detection and analysis using Snort.

    1) Using the analyze tool on the course VM, extract all HTTP traffic observed by the dmz sensor on TCP port 80 during the time range from 05/02/19 09:00:00 to 05/02/19 11:00:00. Save the extracted data to a file named http_extract.pcap.

    Place this file in the directory /sec503/Exercises/Day3
    This will ensure it is accessible for use with Snort or Suricata in the upcoming exercises.

    2) Review the extracted packets using Wireshark and answer the following questions about the capture:

    – Reassemble the session between host 192.168.61.20 and host 134.170.104.154. What version of HTTP is in use? What kind of request is sent? How does the server respond? What kind of server does it appear to be?

    We see that HTTP version 1.1 is in use. The client is sending an HTTP POST request to the server meaning it is sending data to the server, likely for uploading. The body of the request contains 1324 bytes of data. The target host for this request is ssw.live.com.

    The server HTTP response is a successful 200 ok response. The server acknowledged and successfully processed the request but did not return any content. This is typical for many upload or form submission responses that only need to confirm success without sending data back. The webserver is a Microsoft-IIS/7.5.

    3) Create a Snort Rule that can detect a possible indicator of data exfiltration using one or more Snort Http rule options.

    – What in the URL might indicate a potential exfiltration attempt ?

    The URL in question is /UploadData.aspx. Even though it’s not definitive proof, seeing the word “Upload” in the URL is a strong clue that the client may be sending data to the server—something often associated with exfiltration.

    -why is it better to scan for this term in the url instead of the full request or response body?

    Urls are generally short and follow predictable patterns, making them much easier and faster to scan for keywords like “upload”. searching the full session payload for this term could be very inefficient, especially since we wouldn’t know where to start looking.

    – create a snort or rule in your local.rules file under /sec503/exercises/day3 that looks for the word “upload” in a url. confirm that your rule successfully detects the activity.

    Let’s verify if this alert works properly:

    Bingo

  • Snort Writing Rules 2

    Exercise 1
    Task: Develop a new version of the detection rule created in the first lab that identifies the exploit within the payload by applying keyword options such as offset, within, depth, and distance.

    Instructions:
    Begin by duplicating the rule you previously created in the last exercise. Paste it into a new file to work with a clean version. Make sure to update the sid to a new, unique value and reset the rev (revision number) to 1. Although it’s not mandatory, updating the msg field is encouraged to help distinguish this alert from the earlier version visually. This isn’t strictly required because the sid is already unique and is displayed in any alert output.

    1) I analyzed raw packet data to determine the precise starting point of a specific payload pattern: the serie of Xs located in the payload . This task focused on calculating the payload offset using hexadecimal interpretation of both IP and TCP headers.

    The packet began with the hex value 4500, indicating a 20-byte IP header. Further inspection of the header—specifically the value 4500 00d8 bcb2 4000 4006—confirmed the use of TCP, as represented by the protocol number 6. Examining the TCP header at offset 0x0020, I found the value 8018, where 0x80 corresponds to a TCP header length of 8 (multiplied by 4), resulting in 32 bytes.

    By adding the 20-byte IP header to the 32-byte TCP header, I determined the payload begins at byte offset 52, or 0x34 in hexadecimal. Using the tcpdump output, I identified the line starting at offset 0x0030 and noted that the first byte at 0x00340x58—was the beginning of the payload.

    We can use this information to write a more accurate and efficient alert now that we know where our Serie of Xs begins. We can add the option offset 0 right after our content:

    Let’s try and run this alert to make sure it functions as intended.

    Both Alerts successfully Triggered.

    2) I can continue improving my detection rule by optimizing not just where the signature search begins in the payload, but also how far the inspection should go. This optimization involves defining the maximum distance into the payload that the string matching engine will search for the targeted content.

    To implement this, I added one or more rule options to constrain the search window. This ensures the matching engine stops looking after a defined number of bytes, which helps minimize unnecessary processing and improves rule efficiency.

    To do this, I am going to use the Depth option which refers to the size or length of a specified content.

    We added a depth of 13 to our Xs content because we used a string of 13 Xs in our alert content and therefore the minimum amount we can use for our depth option is also 13.

    3) The next step in improving the accuracy of my detection rule is taken by targeting specific binary content found within the payload of the exploit. My goal was to define a content match that would identify a sequence of binary data located between two known strings—XXXXXX and /sh.

    To begin, I used Snort’s support for binary content matching by enclosing hexadecimal byte sequences within pipe symbols (|). For example, a match string like |89 90 1a 2b| would correspond to a precise set of bytes in the payload. This level of specificity helps reduce false positives and ensures that my rule only triggers on highly characteristic patterns of the exploit.

    The bytes of interest—e8 ed ff bf b8—were identified within the packet at a specific payload offset. This additional match was added immediately after the initial XXXXXX... content match:

    Let’s now use the distance and within modifiers to control how closely Snort looks for a second match relative to the first one. This approach is especially useful when trying to match content that consistently appears a specific number of bytes after another known pattern.

    By analysing the hex output of the packet, I identified the relative location of these two key elements in the payload: the string represented by XXXXXX... and the binary sequence (e8 ed ff bf b8). Although these bytes appeared to be directly after the X’s in the data, I had to account for the fact that the initial content match was set with an offset of 0 and a length of 13 characters. This required adjusting the distance value accordingly to avoid skipping the binary data or misaligning the match.

    Additionally, I calculated the exact length of the binary pattern to determine an appropriate within value, ensuring that Snort stops scanning shortly after the desired match.

    4) Simplify the logic by combining both content elements into a single content match. This approach reduces the number of operations Snort needs to perform, improving performance and clarity.

    Initially, my instinct was to match strings at their starting point. However, I discovered that it’s equally valid—and often more effective—to match the trailing portion of a string instead.

    This realization helped me streamline my rule logic. Since the payload in this case happened to start at offset zero, it was tempting to match from the beginning. But had the payload been preceded by other data, that approach would have failed. By refactoring the rule to focus on the ending portion of the string, I improved its reliability and flexibility in different network conditions.

    5) Add offset, within, distance and depth options to try and make this revised rule as efficient as possible

    It was about figuring out how to place each piece of the rule so Snort could accurately spot our target pattern in the payload.

    Here’s what I figured out:

    • We already knew there were 132 X characters in the string, and we’d used 13 of them in a previous rule. That gave us a starting offset of 119 for our match.
    • Those 13 characters were followed by 5 bytes of binary data. So, I set the depth to 18 to capture all of that (13 + 5).
    • Since the /2/sh string comes right after the Xs and binary bytes, it needed to be searched immediately after the first content match, which justified using offset 119.
    • Instead of matching /2/sh right away as the next content, I added it with a distance: 0 from the previous match—basically telling Snort to look for it right after.
    • I also had to make sure Pb/bin, the final part of the payload, was found within 4 bytes after /2/sh. It turns out it starts 3 bytes later and is 6 bytes long, so I used distance: 3 and within: 6.

    Once I put all these details together, I ended up with a rule that’s a lot more efficient and accurate than the one I started with. Here’s what the refined rule looks like now:

    6) In this exercise, I simulated a real-world scenario where my Snort rule—developed through the previous lab steps—had been deployed in a production environment for a while. Unfortunately, despite that setup, someone still managed to exploit the LamanServer, and no alerts were generated. That was a red flag.

    To figure out what went wrong, I pulled packet captures of the suspected exploit and used them to test my detection rule inside my Snort lab setup. Specifically, I ran the rule against the 02_exploit.pcap file.

    The goal here was to determine why the IDS didn’t pick up the attack. I used all the rules I had built in the previous exercises and evaluated them against the new pcap file to see if they triggered as expected—or if the attacker had changed something just enough to evade detection.

  • Snort Writing Rules 1

    Objectives
    This lab is the first in a series aimed at guiding you through writing effective rules for IDS/IPS tools such as Snort and Suricata.

    Details
    You’ll be using the packet capture file located at /sec503/Exercises/Day3/01_exploit.pcap. The goal is to write a signature that correctly detects the exploit within the capture, which simulates a system compromise using a fictional CVE. Treat the capture as an example of traffic generated by a proof-of-concept exploit targeting a LamanServer service on a local network.

    CVE-2026-0503
    Description
    This CVE relates to a buffer overflow in the Novak Enterprises LamanServer application. The vulnerability allows remote code execution and is triggered through traffic to TCP port 50503. Although a proof-of-concept exploit exists, there are no known instances of real-world exploitation.

    The vulnerability occurs in the command parser, which only becomes accessible after the server receives a HELO command.

    Exercise 1

    Description: Write a rule that successfully detects the exploit in the file named 01_exploit.pcap by using one or more content options.

    1) When developing rules for Snort (or similar IDS/IPS tools), it is best practice to use a custom copy of the configuration file. While it might seem easier to work with a minimal configuration specific to your testing environment, doing so may cause you to miss critical updates or necessary settings for a rule to function properly in a production environment.

    First, we are going to validate the configuration file located in the etc directory:

    2) Write a basic alert rule that includes only a rule header and leaves the rule options section empty. Test this rule using the 01_exploit.pcap file. Make sure the rule displays alerts in the console and saves any logs to the /sec503/Exercises/Day3/logs directory. The rule should trigger an alert for every packet in the capture file.

    Let’s first open the local.rules file:

    There’s already a rule in place from the previous lab. Using an editor, I am going to comment out this rule by adding a # at the beginning of the line It’s a good idea to keep the rule commented for reference.

    To create a new rule header, I have to start by choosing the action the rule should perform. Possible actions include:

    • alert: generate an alert
    • pass: allow traffic through without further inspection
    • log: log packets but don’t raise an alert
    • sdrop: silently drop the packet (IPS only)
    • drop: drop and log the packet (IPS only)
    • reject: block the packet, log it, and send a TCP RST to reset the connection
    • activate: enable a related dynamic rule if this rule matches
    • dynamic: define a rule that can only be triggered by an activate rule

    Next, the rule header must include the protocol, source IP, source port, direction, destination IP, and destination port. Supported protocols are:

    • ip
    • tcp
    • udp
    • icmp

    Following the header, the rule must include the options section. This goes right after the destination port and must be enclosed in parentheses. In this case no options are needed, therefore I can use empty parentheses. I am going a very simple rule that generates an alert everytime a packet travelling over IP is encountered in the file:

    Let’s now see the results generated by this alert:

    3) Incorporating Metadata in Custom Snort Rules

    When creating a custom Snort rule, it’s important to include metadata to ensure clarity, traceability, and effective alerting. For this rule, I assigned a signature ID (SID) of 1000000 and set the revision number to 1. I also defined a custom alert message to be displayed when the rule is triggered.

    Metadata should reflect key contextual information. According to best practices:

    The reference field links the rule to external documentation, such as CVEs or BugTraq entries. When supported, these references can be automatically converted into URLs for easier follow-up.

    The rev field indicates the rule’s revision number. Each time a rule is updated, this number should be incremented. This helps avoid confusion caused by stale or outdated rules and streamlines troubleshooting.

    The sid (signature ID) is a mandatory unique identifier for each rule. IDs under 1,000,000 are typically reserved, so custom rules should use higher values to prevent conflicts.

    The msg field contains the message that will be displayed when the rule is triggered. This should clearly describe the nature of the alert.

    4) Analyzing Packet Content for Reliable Signature Matching

    As part of the analysis of 01_exploit.pcap, the objective is to identify specific content within the packets that could serve as a reliable signature for rule creation. The ideal content should be distinct enough that it won’t appear in regular network traffic, helping to minimize false positives.

    Effective matching content is typically a string that is at least four bytes long—longer is better to improve match reliability. If shorter strings must be used, they should be supplemented by longer, more unique strings to ensure accurate detection.

    Snort prioritizes locating the longest matching string, particularly one found at a known offset or near the beginning of the packet payload. Understanding how Snort evaluates packet data in this way is key to crafting precise and effective intrusion detection rules.

    I am going to use tcpdump to look at the first 10 packets payload in this file:

    I am going to use the payload in the 9th packet as a signature for my Alert. We have 3 strings that can be used as content for this signature: a series of Xs followed by PH/bin and 2/sh. Using this payload in the options’ content section, we write the below alert:

    Let’s make sure that the alert wroks as intended:

  • Running Snort

    Purpose
    This lab is an introduction to Snort and its output. It focuses on helping a new user get comfortable with the tool.

    Exercise 1

    1)Start by exploring Snort’s available command-line options. Run the following command to view help information and understand what parameters are available:

      2)Which command-line option should you use to specify a particular configuration file when running Snort?

      Going through the above list of available parameters, we find the below option

      Exercise 2

      1)Which Snort command-line option can be used to check the current configuration and generate a report?

          2)Launch Snort using the correct option to validate the configuration and generate a report, pointing to the snort.lua configuration file located in /sec503/Exercises/Day3/snort/.

          Using the 2 questions above, we can easily answer this question:

          3) After running Snort, you’ll see a stream of initialization messages. Does the snort.lua configuration file pass validation?

          4) How many rules did Snort confirm it loaded?

          5) Run Snort again with the -T option to test the configuration, but this time use snort-broken.lua as the config file. Add the -q option to reduce clutter by hiding the usual startup messages—this will make the error message easier to spot.

          6) In which file is the error located? What is the specific error message?

          The error is located in file called local.rules. Two variables are undefined in this file.

          7) Use the diff command to compare the contents of snort.lua and snort-broken.lua. What differences do you observe?

          The main difference is that snort.lua defines two variables that are commented out in snort-broken.lua. Specifically, HOME_NET is set to the 10.121.0.0/16 network, while EXTERNAL_NET is defined as any network not included in HOME_NET (using the exclamation mark ! for negation). These variables help Snort distinguish between IP addresses inside the monitored network and those outside of it. In snort-broken.lua, these variable definitions are disabled using comment markers (--), so they aren’t loaded. Snort 3 requires that both HOME_NET and EXTERNAL_NET be properly set.

          Exercise 3

          This task is about running Snort in IDS mode. You’ll be using a configuration file and analyzing traffic from a packet capture file instead of live network data. For this, use the file named sample.pcap, located in the /sec503/Exercises/Day3 folder.

          1) The goal is to run Snort using the snort.lua configuration file and see alerts on your console. To make this work, you’ll need to use a few options that haven’t been covered yet.

          To accomplish this task, I ran snort with the below options:

          2) Looking at the alert output, you’ll notice that after the GID, SID, and revision number, there’s a message, followed by a priority level. After that, it shows the protocol, the source IP address and port, and then the destination IP address and port (shown with the arrow symbol “->”). What are the values for the protocol, source IP and port, and destination IP and port?

          The protocol is TCP. The source IP address is 10.121.70.151. The source port is 21 (FTP). The destination IP address is 10.234.125.254 and the destination port is 2217.

          Exercise 4
          Task: Run Snort in IDS mode and make sure logging is enabled.

          1) In the previous exercise, you saw that Snort does not show alerts by default unless it’s specifically told to. Figure out how to configure Snort so it logs fast alerts to a file. The alerts should be saved in the logs directory, located in the current folder or at /sec503/Exercises/Day3/snort/logs.

          Wed can use the -l option to log a given file to a desired directory:

            The file was correctly saved in the chosen directory:

            2) Look at the content of this file

            This is the same content as what we saw in the console output above.

            3) Review the available logger plugins again and identify one that supports both event and packet logging.

            The --help-plugins option provides detailed information about the different plugins that are available. Looking at the list, the unified2 plugin appears to be a good choice. This plugin can be run with the -A option:

              After the unified2 log file has been created, it can be read using tools such as u2spewfoo and u2boat. Running u2spewfoo on the file will display the alert and a packet dump showing what triggered it.

            1. Wireshark part III

              Exercise 1

              Description: Extract the web object image from wireshark3.pcap and view it. According to the extracted image, what did Snort save?

              Exercise 2

              Description: Carve and decode the base64-encoded message from the SMTP exchange between 10.10.10.10 and 10.10.10.25. What does it say?

              First, we apply a filter to capture all the packets involved in this exchange:

              Then, we can right-click on any of these packets so that we can follow the TCP stream for this conversation:

              We can then save this stream as ‘raw’:

              Using notepad, I can now edit the file I just saved.

              I have to delete all lines above and below the single base64-encoded line and delete all blank lines.

              I can now decode the resulting base64-encoded carved file. There are many online base64 decoders available. I can also use built-in tools on most operating systems.

              For Windows, I am going to use the built-in certutil command-line tool. The certutil command with the –decode option takes in a base64 file and outputs the decoded file. The format is:

              The encoded message says: You rock big time!

            2. UDP-ICMP

              This lab focused on analyzing packet behavior related to UDP and ICMP. It was designed to help understand how certain traffic patterns can trigger ICMP error messages and under what conditions those messages should or shouldn’t appear.

              Exercise 1 – Investigating ICMP Echo Requests

              Task:
              The first six records in the capture are grouped in pairs. Each pair includes one packet that would normally trigger an ICMP error, followed by a response or lack of one. According to RFC 1122 and the ICMP protocol, the goal is to determine whether these ICMP errors should be generated, and if not, why.

              Records 1 and 2:

              We see an echo request sent to the address 255.255.255.255 (the broadcast address) and a destination unreachable (Host unreachable) response sent from 192.168.11.1. An echo request sent to the broadcast address should not generate an ICMP error message and it would be an open door for DDOS attacks or broadcast storm to happen.

              Records 3 and 4:

              Record 3 has a More Fragment flag set and a fragment offset of 32 in its IP header which means it is part of fragment train. We are missing the fragment with offset 0 (which would be the first fragment for this given train) and the rest of the fragments located before and after offset 32. Without these missing fragments, the receiving host would not be able to reassemble these records. The ICMP message received in record 4, “TTL exceeded”, should only be sent if the fragment with offset 0 was received which is not the case here. In normal traffic condition, this message would not be generated.

              Records 5 and 6:

              in Record 5 we see 192.168.11.65 sending an ICMP message Type 3 code 1: Destination Unreachable (Host Unreachable) to 192.168.11.1. Normally, this type of message is sent as a response to packet sent to a host that cannot be reached but in this case it is not a response. Record 6 is also an ICMP error message for Host Unreachable. An ICMP error message should never be sent as a response to another ICMP error message otherwise this would generate an endless loop.

              Exercise 2 – ICMP Echo Request Activity (Packets 12–35)


              Analyze packets 12 through 35 in the capture file to determine the nature of the observed activity and identify the likely operating system generating the ICMP echo requests.

              We see sets of 3 Echo Requests being sent from 192.168.11.48 to 68.85.138.249. The first set of 3 has a TTL of 1 and then this TTL gets incremented by 1 every set. These records get an ICMP error message TTL exceeded up until record 31 where the response is an echo reply. This tells us that the host is located 4 hops away from the sender and we can map all the routers passed along the way. The behavior observed corresponds to a Windows tracert using ICMP to identify all the routers along the path from 192.168.11.46 to 68.85.138.249. The tracert command on non-Windows systems typically uses UDP packets instead of ICMP.

              What are the intermediate routers that appear along the path?

              We can easily find this data by looking at the IP addresses sending these ICMP error messages:

              • 192.168.11.1 (records 13, 15 , 17)
              • 192.168.1.1 (records 19, 21, 23)
              • 69.250.56.1 (records 25, 27, 29)

              Exercise 3 – Find the packet number that caused an ICMP error.

              a) Identify the packet that triggered the ICMP error message “time to live exceeded (fragment reassembly timeout)” in record 11.

              Looking at the ICMP portion of record 11, we can find an embedded IP packet that represents part of the original offending packet. Filtering on a unique field in this embedded IP packet like the checksum, we can find the related packet:

              Record 7 is the offending packet:

              b) Identify the packet number that triggered the ICMP error message “port unreachable” in record 36.

              We apply the same type of filtering that was used in the previous question to record 36:

              Record 8 is the packet that generated the ICMP error message in record 36.

              Exercise 4ICMP echo requests and replies found in records 37–46 are all related. What is this activity?

              Each reply receives several echo requests from what appears to be the same IP address. Why is there an imbalance. One echo request should only be answered by one echo reply. We also see a lot of data being carried in both these echo requests and replies packets:

              This mismatch between echo requests and replies and the amount/type of data caried by these ICMP packets are one of the telltale signs of an ICMP tunnel. This is an example of ptunnel that uses ICMP as a tunnel for other protocols, in this case SSH.

            3. TCP

              Lab 2.3 – TCP Packet Analysis

              This lab focused on deepening my understanding of core TCP concepts through packet inspection.

              Exercise 1 – Verifying TCP Protocol Checksum

              Task: Examine the embedded TCP checksum in the packet with:

              • Destination IP: 192.168.2.109
              • Source Port: 2056

              The checksum is equal to 0x0000 which is not a valid checksum:

              Wireshark also flagged this field as incorrect and highlighted the discrepancy in red. This malformed TCP checksum indicates a corrupted or deliberately crafted packet. It will be dropped by any compliant receiving host, as TCP checksums are used to verify the integrity of the header and data.

              Exercise 2 – Suspicious Use of TCP Sequence Numbers

              Objective:
              Investigate two TCP packets with a source port of 4545 and identify what’s unusual about their sequence numbers and behavior.

              We see that both packets have the same sequence number (76148922):

              Both of these packets have the same source and destination address. These packets are trying to establish a connection with a web server (the SYN flag is set). We also notice that both packets have a TCP payload of 12 bytes which is very unusual and suspicious for a TCP packet with a SYN flag set.

              This pattern strongly suggests evasive or malicious behavior, possibly an attempt to:

              • Bypass intrusion detection systems (IDS) by fragmenting or duplicating payload delivery
              • Confuse TCP reassembly logic on different hosts
              • Test how different stacks handle duplicate sequence numbers

              Additionally, the TCP flag settings are unusual for carrying payloads, potentially indicating deliberate manipulation of protocol norms.

              Exercise 3 – Comparing SYN Retries vs. Different Connection Attempts

              Objective:
              Analyze two sets of TCP traffic to determine which is a case of SYN retries (retransmissions) and which represents multiple separate connection attempts.

              Details:

              The activity involves:

              • 10.254.1.8 → port 21
              • 10.114.187.126 → port 143

              To examine the traffic, I used the following tcpdump filter:

              For this first set of activity, we notice that the source port and the sequence number stay the same for all the packets. For the second set of activity, we see that a different source port is used for each retransmission and a different sequence number is generated for each retransmission:

              This first set of connections clearly represents SYN retries:

              • The source port (3655) and TCP sequence number (1216633961) remained the same across all packets, which is a strong indicator of retransmissions rather than new connection attempts.
              • The timing pattern between packets followed a doubling back-off pattern (e.g., 3s, 6s, 12s), which is typical of TCP’s retransmission algorithm when no SYN-ACK is received.

              In contrast, the second set of packets:

              • Had varying source ports and different initial sequence numbers
              • Showed non-uniform timestamps, more consistent with multiple, unique connection attempts

              Conclusion:

              • Set 1 is clearly retries to a non-responsive host
              • Set 2 is a sequence of independent SYN connections, possibly part of a port scan or host enumeration

              Exercise 4 – Detecting Crafted TCP Fields

              Objective:
              Analyze a TCP connection from source 192.0.2.1 to destination 10.10.10.1 and identify at least three anomalies or indicators of packet crafting.

              Analysis & Findings:

              1. The source and Destination port are 0. These are not used in normal traffic.
              2. The FIN, RST, SYN, PSH, ACK and URG flags are all set which abnormal.
              3. One of the TCP options in the packet declared an Maximum Segment Size of 0, which is invalid. The MSS value indicates the maximum amount of TCP payload a sender is willing to receive, and setting it to zero would effectively prevent any data transfer.

              Exercise 5 – Detecting Spoofed SYN/ACK Traffic

              Scenario:
              We observed a large number of SYN/ACK packets coming from source IP 68.178.232.100 and supposedly going to 10.10.10.x hosts. However, our outbound monitoring sensor shows no evidence that the 10.10.10.x hosts ever sent SYNs—which is a red flag.

              A SYN/ACK is sent in response to a SYN packet. If we have no evidence of 10.10.10.x hosts sending SYNs then these addresses might have been spoofed by an attacker.

              Further investigation reveals that the attacker likely crafted the SYN packets with some very clear anomalies.

              1. DoS via spoofed connections:
                It appears the attacker was attempting a denial-of-service (DoS) attack against 68.178.232.100 by flooding port 80 with fake TCP connection attempts. By using spoofed source IP addresses (such as those in the 10.10.10.x range), the attacker tries to mask their identity and avoid detection or filtering.
              2. Identical source ports (port 1024):
                All of the supposed client packets used source port 1024. In legitimate TCP traffic, source ports are typically randomized. The repeated use of the same source port across multiple packets targeting the same destination is highly suspicious and suggests intentional packet crafting.
              3. Identical initial sequence numbers:
                Each spoofed SYN packet used the same initial sequence number: 462297438. Real TCP connections use randomized sequence numbers to ensure connection uniqueness and prevent certain types of attacks. The use of the same sequence number repeatedly is another sign of fabricated traffic.

              Exercise 6 – Investigating an Unusual Packet in a TCP Session

              Objective:
              Analyze the full TCP session between 192.168.1.105 (source port 18655) and 192.168.1.103. The task was to identify what’s strange about the fourth packet, as well as why the connection continues afterward.

              I noticed that the packet was indeed a reset (RST), but it had an invalid TCP checksum. This is important because receiving hosts are designed to silently discard packets with bad checksums.

              If a device like an intrusion detection or prevention system (IDS/IPS) doesn’t validate TCP checksums, it might mistakenly interpret the packet as a legitimate RST. It would then stop tracking the session, assuming the connection is closed. This means it would miss any traffic that follows.

              However, the receiving host in this case ignores the bad RST due to the invalid checksum and continues the session. It goes on to receive and acknowledge two additional segments, which contain a suspicious payload. When reassembled, that payload includes:

              GET /EVILSTUFF HTTP/1.1\r\n\r\n

              This is clearly crafted content with malicious intent. The goal here seems to be evasion—bypassing systems that don’t check checksums properly. The attacker uses a fake RST to throw off monitoring tools, while the target system ignores the bad packet and accepts the real payload.

            4. Writing tcpdump filters

              This lab focused on building familiarity with tcpdump filters, particularly for identifying specific traffic based on TCP flags. The lab also introduced the use of TCP flags, which play a key role in identifying different types of TCP traffic (e.g., SYN, ACK, FIN).

              Exercise 1 – Identifying TCP Connection Attempts with tcpdump

              Objective:
              Use tcpdump to examine records from the file int-server.pcap and identify initial TCP connection attempts from clients to servers. The goal is to isolate packets where only the SYN bit is set—this indicates the start of a TCP handshake.

              Steps Taken:

              1. Command Setup:
                To simplify the output, I used the -n (no DNS resolution) and -t (no timestamp) flags
              2. Filtering on TCP Flags:
              3. TCP control flags are located at byte offset 13 in the TCP header (tcp[13]). For SYN-only packets (i.e., no ACK or other bits set), we need to match exactly the binary value 00000010, which is 0x02 in hex.
              4. tcpdump Filter Expression:
              5. The appropriate filter to match only SYN packets is:

              We see attempted connections from the clients to ports 25(SMTP), 445(SMB), 4444(default port used by Metasploit), 999, 80(HTTP) and 53(DNS).

              Exercise 2 – Filtering for TCP SYN-ACK Responses

              Objective:
              Use tcpdump to identify packets from the int-server.pcap file where a server responds to a connection request—i.e., where both the SYN and ACK flags are set. This indicates the server is listening and willing to establish a connection.

              Understanding TCP Flags:

              • The TCP flags byte is at offset 13 (tcp[13])
              • ACK = 0x10
              • SYN = 0x02
              • Therefore, SYN-ACK = 0x12 (00010010 in binary)

              tcpdump Filter Used:

              The server ports that responded are 25, 445 and 4444.

              Exercise 3 – Filtering for TCP Session Termination (RST or FIN)

              Objective:
              Use tcpdump to identify packets from the int-server.pcap file that contain termination flags, specifically the RST or FIN flags. These flags signal that a TCP session is being closed—either gracefully (FIN) or abruptly (RST).

              Flag Values:

              • FIN = 0x01
              • RST = 0x04

              Unlike previous filters that matched exact values, this task required detecting whether either of the two termination flags is present, regardless of other flags that might also be set.

              Using a Mask Byte:

              The correct approach is to apply a mask byte that preserves only the FIN and RST bits:

              • Binary: 00000101
              • Hex: 0x05

              The filter will check if either of these bits is present using a bitwise AND mask.

              tcpdump Filter Used:

              We see 7 records with either or both the FIN and RESET flags set.

              Exercise 4 – Filtering for TCP Packets with Both PSH and ACK Flags on Port 143 (IMAP)

              Objective:
              Use tcpdump to extract the first five packets from int-server.pcap that meet all the following criteria:

              • Destination port is TCP 143 (IMAP)
              • Both the PUSH and ACK flags are set
              • Other flags may be present as well

              TCP Flags Reference:

              • ACK = 0x10 (bit 4)
              • PSH = 0x08 (bit 3)
                Combined, they yield a value of 0x18 (00011000 in binary)

              To isolate packets where both these bits are set (regardless of other flags), I used a bitmask to mask all other bits:

              • Mask: 0x18
              • Value: 0x18

              tcpdump Filter Used:

            5. Wireshark Display Filters

              Wireshark Display Filters Lab – Overview and Setup

              This lab focused on becoming more familiar with using Wireshark display filters to isolate specific types of traffic.

              Exercise 1 – Filtering DNS Queries for a Specific Domain

              Task: Find the packet record number(s) where a DNS query name contains the string glenhighland.

              There are many ways to solve this. One way is to filter the packets in Wireshark for DNS query name using the filter ‘dns.qry.name’ and then looking for the glenhighland string in the filtered packets using the Edit/Find Packet menu. Packets 101 and 102 contains this string.

              Exercise 2 – Finding ARP Request Records

              Task: Find all ARP request records. How many are there, and what filter did you use?

              To complete this task, I used a Wireshark display filter that isolates ARP request packets specifically. First, I reviewed the structure of an ARP packet by looking at one in the packet list which Wireshark identified as a request under the Address Resolution Protocol section.

              I then right clicked on the Opcode line and applied this same filter to the packet list.

              The arp.opcode==1 gets applied, and 16 packets get displayed (it is shown at the bottom right corner of the wireshark screen).

              Exercise 3 – Identifying ICMP Echo Replies with Undersized IP Payloads

              Task: Find the record numbers of any ICMP echo reply (type 0) frames that required zero-padding due to being smaller than the minimum acceptable Ethernet II length.

              To solve this, I first recalled that the minimum Ethernet II frame size is 64 bytes, and that the Ethernet header (14 bytes) plus trailer (4 bytes) leave at least 46 bytes required for the IP payload. Therefore, any IP datagram smaller than 46 bytes would be too short and must be padded to meet Ethernet’s minimum.

              I used the Wireshark Display Filter Expression dialog to build a compound filter that would identify:

              • ICMP echo replies (type 0)
              • IP datagrams with a Total Length < 46

              To do this:

              1. I opened Analyze > Display Filter Expression
              2. Selected the field ip.len
              3. Chose the less than (<) relation
              4. Entered the value 46
              5. Added icmp.type == 0 to narrow it to echo replies

              We identified 3 packets using these combined filters.

              Exercise 4 – Isolating and Exporting DNS over UDP Traffic

              Task: Find all records where the UDP protocol is carrying DNS traffic. How many are there? Save those packets to a new file named dns.pcapng.

              To complete this, I used this display filter in Wireshark:

              This filter shows all packets where DNS communication is occurring over UDP (14 packets are displayed).

              Once filtered, I saved the displayed packets to a new capture file:

              1. Went to File > Export Specified Packets.
              2. Entered the filename: dns.pcapng.
              3. Selected All packets and Displayed (to export only the filtered results).
              4. Clicked Save.