Chapter 12 What is the server certificate public key that was used in TLS session: da4a0000342e4b73459d7360b4bea971cc303ac18d29b99067e46d16cc07f4ff?

12.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)
  • conn — Zeek conn.log data (Chapter 5)
  • hoststshark host/IP file (Chapter 8)
  • ftp — Zeek ftp.log data (Chapter 10)

Packages:

  • {jsonlite}
  • {stringi}
  • {glue}
  • {tidyverse}

12.2 Question Setup

We learned in the previous chapter that knowledge of TLS sessions can be pretty handy when poking at PCAPs and this chapter expands upon that knowledge by asking us to reveal the server certificate public key that was used in TLS session: da4a0000342e4b73459d7360b4bea971cc303ac18d29b99067e46d16cc07f4ff? Being able to extract and compare TLS session elements is another handy skill, and this example will let us explore another set of tshark display filter and output fields that can come in usful in future IRL scenarios.

12.3 Solving the quest with tshark custom filters (and a wee bit of R)

That’s right, we’re not going to make you generate giant JSON files and sift through horribly nested R lists. We are going to need some help from R since the question gave us a session byte string without colons, which tshark requires in their filters, so we’ll use R to generate that before passing the info to the command line.

We’ll use regular expression-based find/replace via the {stringi} package. In the regex below, the (?!$) hieroglyphics means “but not at the end of the string” and the (.{2}) hieroglyphics means “match every two characters and take them as a group.” Once we have a valid value, we can use the {glue} package to add that to the tshark command line call via string interpolation.

Speaking of tshark filters, we’re searching on tls.handshake.session_id for the provided session, and if we re-visit the online display filter reference we can see that the “public key” (or Pubkey) is tls.handshake.server_point, so we can focus on just extracting that.

library(stringi)
library(glue)

(stri_replace_all_regex(
  str = "da4a0000342e4b73459d7360b4bea971cc303ac18d29b99067e46d16cc07f4ff",
  pattern = "(.{2})(?!$)",
  replacement = "$1:"
) -> session_to_find)
## [1] "da:4a:00:00:34:2e:4b:73:45:9d:73:60:b4:be:a9:71:cc:30:3a:c1:8d:29:b9:90:67:e4:6d:16:cc:07:f4:ff"
system(
  glue(
    "tshark -e tls.handshake.server_point -Tfields -r maze/maze.pcapng tls.handshake.session_id == '{session_to_find}'"
  ), intern=TRUE
)
## [1] "04edcc123af7b13e90ce101a31c2f996f471a7c8f48a1b81d765085f548059a550f3f4f62ca1f0e8f74d727053074a37bceb2cbdc7ce2a8994dcd76dd6834eefc5438c3b6da929321f3a1366bd14c877cc83e5d0731b7f80a6b80916efd4a23a4d"