SANS Digital Forensics and Incident Response Blog

2015 DFIR Monterey Network Forensic Challenge Results

2015-03-04 UPDATE: I've added some thought process/methodology to the answers inline below.


Thanks to everyone that submitted or just played along with the SANS DFIR Network Forensic Challenge! We had over 3,000 evidence downloads, and more than 500 submissions! Per the rules, the winner must have answered four of the six questions correctly. Then, by random selection among those submissions, the winner was selected.

We're excited to announce that Henry van Jaarsveld is the winner for this challenge! Congratulations, and we hope you enjoy your SANS OnDemand Course. Great work, Henry!

Thanks for all the submissions and interest in this challenge. If you enjoyed the questions - no matter how many questions you answered - you should check out FOR572: Advanced Network Forensics and Analysis. The class is available via OnDemand, as well as the following live and virtual SANS events:

More live and virtual/remote events are being added all the time, so keep checking the course page for additional offerings.

The challenge answers are listed below:

  1. At what time (UTC, including year) did the portscanning activity from IP address 123.150.207.231 start?

Answer: Aug 29 2013 13:58:55 UTC

Portscanning activity is typically characterized by connection attempts to a range of ports. This is often repaid and originates from the same IP address. Some scanning utilities may or may not use the same source port or a small cluster of source ports. In this case, the following command get you started:

$ grep SRC=123.150.207.231 messages

The first result is below:

Aug 29 09:58:55 gw kernel: FW reject_input: IN=eth0 OUT= MAC=08:00:27:53:38:ee:08:00:27:1c:21:2b:08:00 SRC=123.150.207.231 DST=98.252.16.36 LEN=44 TOS=0x00 PREC=0x00 TTL=41 ID=35517 PROTO=TCP SPT=38553 DPT=3306 WINDOW=1024 RES=0x00 SYN URGP=0

However, we've asked for the time in UTC, which is the only recommended time zone to use for forensic reporting. To find the offset, examine the same "messages" file further. This isn't often an explicitly logged value, so context is necessary. The following line shows the syslog time (system local time) and a corresponding UTC value. Therefore, it is reasonable to state that the system's time zone is UTC-4 during the time the file was created.

Aug 29 07:07:40 gw kernel: rtc_cmos rtc_cmos: setting system clock to 2013-08-29 11:07:08 UTC (1377774428)


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

Answer: 169.254.20.167, 169.254.90.183, 192.168.1.64

This is an exercise in using Wireshark/tshark display filters. The following tshark command will answer the question quickly:

$ tshark -n -r nitroba.pcap -T fields -e 'ip.src' -Y 'eth.src == 00:1f:f3:5a:77:9b and ip' | sort | uniq

-n: suppress DNS lookups
-r nitroba.pcap: file to read
-T fields: use "fields" output format
-e ip.src: output just the "ip.src" field, as defined by the Wireshark/tshark parsers
-Y 'eth.src == 00:1f:f3:5a:77:9b and ip': display filter to limit results to the MAC address of interest and IP traffic, which would be the only traffic to include IP addresses
| sort | uniq: bash shell utilities to narrow results to only unique values


  1. 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?

Answer: 149.20.20.135 and 192.168.75.29, 30472 and 51851

Again, the tshark utility is your friend. This is as a multiple-stage process. First, get the frame number containing the desired request. This command returns frame number 5846.

$ tshark -n -r ftp-example.pcap -Y 'ftp.request.arg == "scenery-backgrounds-6.0.0-1.el6.noarch.rpm"' -T fields -e frame.number

-n: suppress DNS lookups
-r ftp-example.pcap: file to read
-Y 'ftp.request.arg == "scenery-backgrounds-6.0.0-1.el6.noarch.rpm"': display filter to limit results to just FTP commands that included the argument of interest
-T fields: use "fields" output format
-e frame.number: Get the frame number containing the desired request

Next, find the immediately preceding "Passive Mode" response.

$ tshark -n -r ftp-example.pcap -Y 'ftp.response.code == 227 && frame.number < 5846' -T fields -e frame.number -e ftp.passive.ip -e ftp.passive.port | tail -n 1

-n: suppress DNS lookups
-r ftp-example.pcap: file to read
-Y 'ftp.response.code == 227 && frame.number < 5846': Display filter to limit results to just FTP response codes of "227" (Entering Passive Mode) and prior to the frame number containing the request of interest
-T fields: use "fields" output format
-e frame.number -e ftp.passive.ip -e ftp.passive.port: Get the values from the fields of interest
| tail -n 1: Just return the last result from the list

Finally, get IPs and ports from both ends of the data transfer.

$ tshark -n -r ftp-example.pcap -Y 'ip.addr == 149.20.20.135 && tcp.port == 30472' -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport | sort | uniq

-n: suppress DNS lookups
-r ftp-example.pcap: file to read
-Y 'ip.addr == 149.20.20.135 && tcp.port == 30472': Display filter to isolate TCP connection according to IP and port determined above
-T fields: use "fields" output format
-e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport: Get the values from the fields of interest
| sort | uniq: Only display unique lines


  1. How many IP addresses attempted to connect to destination IP address 63.141.241.10 on the default SSH port?

Answer: 49

A connection attempt may or may not be successful, so we can simply limit our search to the high-level filtering provided by nfdump. You could use grep against the text file as well.
There are 55 total connections:

$ nfdump -q -O tstart -r nfcapd.201405230000 -o 'fmt:%sa' 'dst ip 63.141.241.10 and dst port 22' | wc -l

-q: "quiet" output, which suppresses summary header/footer information
-O tstart: order output by "start time" of each record
-r nfcapd.201405230000: input file to read
-o 'fmt:%sa': only display the source IP address for each record
'dst ip 63.141.241.10 and dst port 22': limit flows to those from the IP address of interest, to the default SSH port. You might also limit by TCP protocol by adding "and proto tcp"
| wc -l: count the results

There were 49 unique IPs in this data set:

$ nfdump -q -O tstart -r nfcapd.201405230000 -o 'fmt:%sa' 'dst ip 63.141.241.10 and dst port 22' | sort | uniq | wc -l

This is the identical command to that above, but uses the following shell command chain

| sort | uniq | wc -l: Count only unique lines from the nfdump command's output


  1. What is the byte size for the file named "Researched Sub-Atomic Particles.xlsx"?

Answer: 13,625 bytes

To find the portion(s) of the input pcap that involve the filename of interest, use the "smb.file" field to find the TCP streams of interest.

$ tshark -n -r stark-20120403-full-smb_smb2.pcap -Y 'smb.file == "Researched Sub-Atomic Particles.xlsx"' -T fields -e tcp.stream
2104
2207

This is a large input pcap, so loading it directly to Wireshark is not advisable. Instead, isolate the TCP streams identified above to a new file:

$ tshark -n -r stark-20120403-full-smb_smb2.pcap -Y 'tcp.stream == 2104 or tcp.stream == 2207' -w tcpstreams_2104_2207.pcap
$ md5sum tcpstreams_2104_2207.pcap
fe9c5a388d0d70f74bb96913f120fc7a tcpstreams_2104_2207.pcap

This file is very feasible to open in Wireshark, as it's a mere 18MB.

After opening the file, you must explore the SMB session - which is not at all a simple process. In the input file generated above, the message we're interested in is the Trans2 Response message containing Standard File Info for the file of interest. This occurs in frame 749 (frame.time = Apr 5, 2012 14:21:50.574112000). By spelunking the available fields, you'll find the "End of File" value, which is 13,625. This represents the number of bytes in the file. Note that the Wireshark status bar tells us that Wireshark knows this field by the name "smb.end_of_file", which could be used to scale this process out via the tshark utility.


  1. 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.

Answer: ULQENP2 at offset 4 (bytes 5-11 of the TCP data segment, zero-based)

There are a number of ways to approach this. The goal is to identify commonalities among the individual sessions, even though we are not (yet) sure what the bytes mean.
This evidence file is small enough to load into Wireshark, then visually explore the content - despite Wireshark not knowing the content is anything other than generic "Data".
After visually inspecting these fields in the traffic the IDS logged, you should see that bytes 4-10 (zero-based, of course) seem consistent. This can be confirmed with the following display filter:

data.data[4-10] == 55:4c:51:45:4e:50:32

After applying this filter, you can quickly see that 100% of the packets in the IDS log file match. Expanding the filter one byte before or after this substring range results in a <100% match. Barring any additional knowledge of the custom protocol used for these communications, this substring and offset would be a good indicator of compromise.


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

Answer: UNIX Timestamp

There is a no magic solution here - just trial and error combined with experience. The UNIX timestamp (number of seconds after Jan 1, 1970 at 00:00:00 UTC) fits into four bytes. Those with a keen eye for timestamps will see that after converting any given four byte sequence to a big-endian integer, then converting that to a timestamp, the Wireshark/tshark "frame.time" field value corresponds almost perfectly in every case. For example:

0x4fe6c278 == 1340523128
$ date -u -d @1340523128
Sun Jun 24 07:32:08 UTC 2012
Corresponding frame.time: Jun 24, 2012 07:32:08.273277000

10 Comments

Posted February 13, 2015 at 10:18 PM | Permalink | Reply

Ronnie

First many thanks for the challenge :)
This question is not well formulated i in my opinion wrong or wrong answer:
How many IP addresses attempted to connect to destination IP address 63.141.241.10 on the default SSH port?
45 IP addresses, because some of them are the same ones trying to connect again.
The right question for the answer you guys wanted is:
How many times was there connection attempts to connect to destination IP address 63.141.241.10 on the default SSH port?
49 Thats with duplicates of IP addresses.
Can you see my point ?

Posted March 5, 2015 at 3:16 AM | Permalink | Reply

Phil Hagen

Hi, Ron ''" this comment just popped up on the blog side. I believe I got the breakdown of the answer to you via twitter, but just in case:
There were 55 total connection attempts from 49 unique IPs. Commands for this question are here: http://pastebin.com/pMdA785W and I've added background to the cross-post, here: http://lewestech.com/2015/02/2015-network-challenge-results/
(Working to get these posted on this blog in parallel.)

Posted February 16, 2015 at 11:26 AM | Permalink | Reply

Mary

I wanted to win.. but congratulations to the winner!!!

Posted February 20, 2015 at 12:28 PM | Permalink | Reply

Niall

Hi Phil,
Thanks for taking the time to do this, painful to see how difficult I was making things for myself on one or two of the questions!
Hope to see more Network Forensics stuff from you soon.
Niall

Posted February 26, 2015 at 5:21 PM | Permalink | Reply

Jeremy

Are you going to leave the pcap/data files around to be available to we can use it as a training tool?

Posted March 5, 2015 at 3:16 AM | Permalink | Reply

Phil Hagen

Yes, the evidence files are back online.

Posted March 19, 2015 at 11:14 AM | Permalink | Reply

Josh Lemon

The example command given in answer 3 doesn't produce the correct answer.
The Tshark command you've given shows the initial request for the file (over TCP 21), but not the ports used for the actual data transfer (192.168.75.29:51851 ''"

Posted March 20, 2015 at 2:37 AM | Permalink | Reply

Phil Hagen

Good catch, Josh ''" thanks for the heads up. An old version of this writeup made it to publication. I've updated the answer to reflect the complete process. Thanks and sorry about that!

Posted March 27, 2015 at 1:50 AM | Permalink | Reply

Josh

Great challenge! A couple of questions though:
Question 1's answer references a tshark command within the first couple of sentences, however it's not present.
Question 3's final tshark command displays the following error: "** process:PID#: WARNING **: ''tcp.dstaddr' isn't a valid field!" Reviewing via Wireshark's Filter Expression, it seems there's no tcp.dstaddr nor tcp.srcaddr.

Posted March 31, 2015 at 8:25 PM | Permalink | Reply

Phil Hagen

Hi, Josh ''" good catch on the erroneous sentence on #1. That was an editing artifact and I've removed it.
For #3, the "dstaddr" was also an error ''" it should have been "dstport". Earlier versions of tshark (we used 1.10.7 at the time) did not error out when using a nonexistent field. Sounds like you've got a newer version that does the job better! I've updated the command to reflect the change, though ''" thanks again!