Chapter 5 How many UDP packets were sent from 192.168.1.26
to 24.39.217.246
?
5.1 Objects in memory/packages loaded from preceding chapters
Objects available:
read_zeek_log()
— helper function to read Zeek log files (Chapter 3)packets
— data frame of PCAP packet data (Chapter 4)
Packages:
{tidyverse}
5.2 Question Setup
We’ve been asked to determine how many UDP packets were sent from 192.168.1.26
to 24.39.217.246
. You use UDP every day (well, your browsers/devices do) when you lookup website addresses (i.e. make traditional DNS queries) and even visit some websites since super fancy ones use HTTP/3 or QUIC protocols to speedup web sessions. This makes knowing how to find UDP information in packet captures a “must have” skill.
5.3 Solving the quest with tshark
The truth is that we don’t really need R to answer this question since tshark
has a rich query filter language which lets us subset what we’re looking for by wide array of fields.
In this case we’re looking for an IP source address (ip.src
) of 192.168.1.26
talking to an IP destination address (ip.dst
) of 24.39.217.246
speaking the UDP (udp
) network protocol:
system("tshark -r maze/maze.pcapng '(ip.src == 192.168.1.26) and (ip.dst == 24.39.217.246) and udp'", intern = TRUE)
## [1] "15806 128.281136434 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [2] "15808 128.283606894 192.168.1.26 → 24.39.217.246 UDP 94 51601 → 54150 Len=52"
## [3] "15825 130.239091258 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [4] "15851 132.241685345 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [5] "15865 135.324998370 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [6] "15942 137.223543961 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [7] "16095 139.223629695 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [8] "16695 143.331929739 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [9] "16810 145.217958711 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
## [10] "16955 147.222253195 192.168.1.26 → 24.39.217.246 UDP 94 53638 → 54150 Len=52"
If you’re on a system with wc
(word/char/line count utility — Windows folks can use WSL 2) you can pipe that output to said utility and end up with the value 10
.
5.4 Solving the quest with R
5.4.1 Using the tshark
packets
data
We already have packets
in memory and can use a {dplyr}
chain with essentially the same query we used in tshark
:
%>%
packets filter(
== "192.168.1.26",
src == "24.39.217.246",
dst == "UDP"
proto %>%
) count()
## # A tibble: 1 x 1
## n
## <int>
## 1 10
We can also use “classic R” idioms (along with the new, built-in/native pipe symbol |>
) if we’re in a retro-ish mood:
|>
packets subset(
== "192.168.1.26") &
(src == "24.39.217.246") &
(dst == "UDP")
(proto |>
) nrow()
## [1] 10
5.4.2 Using Zeek conn.log
data
We can arrive at the same answer by examining the Zeek conn.log
data using a similar technique. The Zeek src
/dst
equivalents are id.orig_h
/id.resp_h
(proto
is the same but the contents are lowercase), and Zeek’s conn.log
has an orig_pkts
field for each record which is the number of packets that the originator sent, which means we just need to sum those up to get our answer.
# read in the Zeek conn.log — this will now be in memory for future reference
<- read_zeek_log("maze/conn.log")) (conn
## # A tibble: 12,443 x 23
## ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr> <chr> <chr>
## 1 1.62e9 C27ow… 192.168.… 51754 173.223.… 80 tcp - 0.000607
## 2 1.62e9 Ct11V… 192.168.… 36116 192.168.… 53 udp dns 0.191884
## 3 1.62e9 ClVxP… 192.168.… 33066 13.107.2… 443 tcp ssl 10.3804…
## 4 1.62e9 CZF8x… 192.168.… 52064 192.168.… 53 udp dns 0.068408
## 5 1.62e9 CGOtA… 192.168.… 58432 192.168.… 53 udp dns 0.081218
## 6 1.62e9 CiHtO… 192.168.… 45191 192.168.… 53 udp dns 0.133955
## 7 1.62e9 CMY0w… 192.168.… 59660 192.168.… 53 udp dns 0.097726
## 8 1.62e9 CBQkN… 192.168.… 33078 13.107.2… 443 tcp - 0.138868
## 9 1.62e9 CHMrA… 192.168.… 54444 192.168.… 53 udp dns -
## 10 1.62e9 CO7KH… 192.168.… 54764 173.223.… 443 tcp - 0.151084
## # … with 12,433 more rows, and 14 more variables: orig_bytes <chr>,
## # resp_bytes <chr>, conn_state <chr>, local_orig <chr>, local_resp <chr>,
## # missed_bytes <dbl>, history <chr>, orig_pkts <dbl>, orig_ip_bytes <dbl>,
## # resp_pkts <dbl>, resp_ip_bytes <dbl>, tunnel_parents <chr>,
## # orig_l2_addr <chr>, resp_l2_addr <chr>
%>%
conn filter(
== "192.168.1.26"),
(id.orig_h == "24.39.217.246"),
(id.resp_h == "udp")
(proto %>%
) count(
wt = orig_pkts
)
## # A tibble: 1 x 1
## n
## <dbl>
## 1 10