Chapter 4 Question Quests

The story setup for these exercises is that we are analysts working for a security service provider and have been tasked with analyzing a packet capture for a customer’s employee whose network activity has been monitored for a while. The company suspects this individual is a possible insider threat.

4.1 11 Quests

The set of questions appears to be randomized on the CyberDefenders site (likely to prevent blind copy/pasting from solution sets like this). We’re going to tackle them in the following order to create a more logical flow.

  1. How many UDP packets were sent from 192.168.1.26 to 24.39.217.246?
  2. What is the MAC address of the system being monitored?
  3. What domain is the user looking up in packet 15174?
  4. What domain was the user connected to in packet 27300?
  5. What is the IPv6 address of the DNS server used by 192.168.1.26?
  6. What is the FTP password?
  7. What is the first TLS 1.3 client random that was used to establish a connection with protonmail.com?
  8. What is the server certificate public key that was used in TLS session: da4a0000342e4b73459d7360b4bea971cc303ac18d29b99067e46d16cc07f4ff?
  9. What time was a non-standard folder created on the FTP server on the 20th of April?
  10. What country is the MAC address of the FTP server registered in?
  11. What was the camera model name used to take picture 20210429_152157.jpg?

4.2 Target User Activity

The challenge setup does not state this overtly, but the target of our network analysis is the user activity associated with the IP address 192.168.1.26.

Let’s get an overview of this user’s activity.

Note that we are now in the main project folder and not in the maze directory. The remaining chapters will make the assumption that we are working in the same RStudio session and that any variables created in each chapter are in-memory for the duration of the book.

To start, we’ll read in the packet information file we generated with tshark:

library(tidyverse)

packet_cols <- c("packet_num", "ts", "src", "discard", "dst", "proto", "length", "info")

read_tsv(
  file = "maze/maze.txt",
  col_names = packet_cols,
  col_types = "ddccccdc"
) %>% 
  select(-discard) %>% 
  glimpse() -> packets
## Rows: 45,024
## Columns: 7
## $ packet_num <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
## $ ts         <dbl> 0.000000000, 0.004073155, 0.004680329, 0.068286008, 0.06832…
## $ src        <chr> "192.168.1.26", "173.223.18.66", "192.168.1.26", "192.168.1…
## $ dst        <chr> "13.107.21.200", "192.168.1.26", "173.223.18.66", "13.107.2…
## $ proto      <chr> "TCP", "TCP", "TCP", "TLSv1.2", "TLSv1.2", "TLSv1.2", "TCP"…
## $ length     <dbl> 74, 66, 66, 525, 624, 104, 74, 66, 191, 66, 66, 66, 66, 66,…
## $ info       <chr> "33066 → 443 [SYN] Seq=0 Win=65330 Len=0 MSS=1390 SACK_PERM…
packets
## # A tibble: 45,024 x 7
##    packet_num      ts src      dst      proto length info                       
##         <dbl>   <dbl> <chr>    <chr>    <chr>  <dbl> <chr>                      
##  1          1 0       192.168… 13.107.… TCP       74 33066 → 443 [SYN] Seq=0 Wi…
##  2          2 0.00407 173.223… 192.168… TCP       66 80 → 51754 [FIN, ACK] Seq=…
##  3          3 0.00468 192.168… 173.223… TCP       66 51754 → 80 [FIN, ACK] Seq=…
##  4          4 0.0683  192.168… 13.107.… TLSv…    525 Application Data           
##  5          5 0.0683  192.168… 13.107.… TLSv…    624 Application Data           
##  6          6 0.141   192.168… 13.107.… TLSv…    104 Application Data           
##  7          7 0.144   13.107.… 192.168… TCP       74 443 → 33066 [SYN, ACK] Seq…
##  8          8 0.144   192.168… 13.107.… TCP       66 33066 → 443 [ACK] Seq=1 Ac…
##  9          9 0.145   192.168… 13.107.… TLSv1    191 Client Hello               
## 10         10 0.149   173.223… 192.168… TCP       66 80 → 51754 [ACK] Seq=2 Ack…
## # … with 45,014 more rows

Now we’ll get an overview of the activity by looking at the number of packets originating from the target we’re investigating to each distinct host by protocol:

packets %>% 
  filter(src == "192.168.1.26") %>% 
  count(src, dst, proto, sort=TRUE) %>% 
  print(n=20) # limiting to 20 rows of output for brevity; IRL you'd likely want to see them all
## # A tibble: 146 x 4
##    src          dst             proto        n
##    <chr>        <chr>           <chr>    <int>
##  1 192.168.1.26 172.67.162.206  TCP      17942
##  2 192.168.1.26 192.168.1.20    FTP-DATA  8568
##  3 192.168.1.26 185.70.41.130   TCP       2307
##  4 192.168.1.26 23.51.191.35    TCP       1185
##  5 192.168.1.26 185.70.41.35    TCP        687
##  6 192.168.1.26 159.65.89.65    TCP        394
##  7 192.168.1.26 142.250.190.132 QUIC       361
##  8 192.168.1.26 23.51.191.35    TLSv1.2    332
##  9 192.168.1.26 35.186.220.63   TCP        161
## 10 192.168.1.26 13.107.21.200   TCP        133
## 11 192.168.1.26 24.35.154.189   UDP        113
## 12 192.168.1.26 192.168.1.20    TCP         85
## 13 192.168.1.26 52.137.103.130  TCP         83
## 14 192.168.1.26 185.70.41.130   TLSv1.3     67
## 15 192.168.1.26 104.21.89.171   QUIC        65
## 16 192.168.1.26 192.168.0.44    UDP         60
## 17 192.168.1.26 204.79.197.200  TCP         47
## 18 192.168.1.26 52.137.103.130  TLSv1.2     43
## 19 192.168.1.26 13.107.246.254  TCP         39
## 20 192.168.1.26 192.168.1.20    FTP         38
## # … with 126 more rows

as well as the overall protocol use distribution:

packets %>% 
  count(proto, sort=TRUE) %>% 
  print(n=nrow(.))
## # A tibble: 20 x 2
##    proto        n
##    <chr>    <int>
##  1 TCP      28933
##  2 FTP-DATA  8573
##  3 TLSv1.3   3269
##  4 TLSv1.2   1772
##  5 QUIC      1557
##  6 UDP        234
##  7 DNS        163
##  8 ICMPv6     152
##  9 IPv6       109
## 10 FTP         88
## 11 ARP         72
## 12 TLSv1       31
## 13 NBNS        21
## 14 SSLv2       18
## 15 HTTP        17
## 16 ICMP         7
## 17 IGMPv2       4
## 18 EAPOL        2
## 19 OCSP         1
## 20 SSL          1

We can further count the total number of network hosts contacted:

packets %>% 
  filter(
    src == "192.168.1.26",
    dst != "192.168.1.26"
  ) %>% 
  distinct(dst) %>% 
  count()
## # A tibble: 1 x 1
##       n
##   <int>
## 1    70

You are encouraged to poke around this data frame with some of the concepts you may have seen in R4DS before jumping into the first quest.