DFIR MONTEREY 2015 Network Forensics Challenge

DFIR MONTEREY 2015 Network Forensics Challenge

This article aims at solving the PCAP related questions from the DFIR MONTEREY 2015 Network Forensics Challenge using Squey.
Of course the idea here is not to really solve the challenge as it has been solved numerous times since then, but to see how easier it is to solve it using Squey.

The dataset 2014-11+DFIR+Network+Forensics+Challenge.zip was taken from the Netresec PCAP page.

Note: questions 1 and 4 were not solved because they didn’t involve any PCAP data.

2. What IP addresses were used by the system claiming the MAC Address 00:1f:f3:5a:77:9b?

Click on the PCAP button of the start page, select the provided HTTP profile, browse the nitroba.pcap file and then click Process.

You should now see the selected fields of the PCAP represented as Parallel Coordinates:

On the listing view located on the bottom of the window, right-click on any value of the eth.src column, select Search for..., paste the MAC address 00:1f:f3:5a:77:9b in the Expressions text field, select Case sensitivity: Does not match case and click Apply.

This will instantly filter the packets to display only eth.src == 00:1f:f3:5a:77:9b :

You can then right-click on the src.ip column header and select Distinct values to display the distinct values with their associated count/frequency:

Answer:, and

3. What IP (source and destination) and TCP ports (source and destination) are used to transfer the “scenery-backgrounds-6.0.0-1.el6.noarch.rpm” file?

Before loading this PCAP file, you will need to create a PCAP profile to select which fields to import in the application. On the PCAP dialog, select Manage profiles, click on New profile, enter something meaningful like FTP, browse the ftp-example.pcap file to analyse the protocols it contains and select all the fields you are interested in like :


Save the profile and open the ftp-example.pcap file with the FTP profile selected.

Right-click on the ftp.request.arg column header, select Distinct values and click on the scenery-backgrounds-6.0.0-1.el6.noarch.rpm file.

This will display the only packet containing scenery-backgrounds-6.0.0-1.el6.noarch.rpm as its ftp.request.arg field.
Right-click on the row index and select Copy line index to clipboard.

Press the g key and paste the value 34956 corresponding to our packet.

Scroll-back a few rows until you see on the ftp.response.code column the value 227 which corresponds to “Entering Passive Mode”.
We can then observe that the destination IP and port are

Right-click on the ip.src value of the packet containing the file and select Search for this value, this will only keep packets with this IP as source.

Then right-click on the tcp.dstport value 30472 and select Search for the value to add another level of filtering which will keep only packets having our previously selected IP as source and 30472 as TCP destination port.

We can observe that the source IP and port are

Answer: and

5. What is the byte size for the file named “Researched Sub-Atomic Particles.xlsx”?

Create a SMB PCAP profile containing the following fields:


Then import the stark-20120403-full-smb_smb2.pcap file using the newly created SMB profile.

Filter the packets containing the text Researched Sub-Atomic Particles.xlsx in their smb.file field:

Then display the Distinct values of the column smb.end_of_file

Answer: 13,625 bytes

6. The traffic in this Snort IDS pcap log contains traffic that is suspected to be a malware beaconing. Identify the substring and offset for a common substring that would support a unique Indicator Of Compromise for this activity.

Create a custom PCAP profile containing the following fields:


Then import the snort.log.1340504390.pcap file using the newly created profile.

Displaying the Distinct values of the data.data column and scrolling through the values seems to indicate that some of the data remains constant.

But scrolling the 14,228 distinct values to check if this patterns applies to all of them would make our eyes bleed for sure.
Wouldn’t it be nice if we could instead visualize the integrality of the data content and prove it ?

Alright, let’s do that by splitting the data.data field into the smallest addressable memory units: bytes.
A few lines of Python code will be plenty enough to do that:

1source = squey.source("snort.log.1340504390.pcap")
2data = source.column("data.data")
3for i in range(int(len(data[0])/2)):
4    b=data.view('<U2').reshape(data.shape + (-1,))[:, i]
5    source.insert_column(b.copy(), f"data_byte_{i}")

Now, it is crystal clear that along all the packets of the dataset, bytes 4 to 10 of the data.data field are always contant:

Answer: bytes 4 to 10 (zero based), which represent the string “ULQENP2” in ASCII.

7. BONUS! Identify the meaning of the bytes that precede the substring above.

There are 4 bytes preceding the static “ULQENP2” string: let’s extract these as a new uint32 integer column using the following Python code:

1import numpy as np
2source = squey.source("snort.log.1340504390.pcap")
3data = source.column("data.data")
4b=data.view('<U8').reshape(data.shape + (-1,))[:, 0]
5b_int=np.vectorize(lambda t: int(t, 16) if t else 0)(b)
6source.insert_column(b_int.copy(), "data_first_4_bytes_as_uint32")

Now, let’s check if we can observe an evolution of this data through time by using a scatter plot.

Wait, it is not evolving through time, it is time.

Answer: A UNIX timesteamp.