Additionally, paste this code immediately after the opening tag:

As part of the most recent ZeekWeek event the Zeek Project Training Subgroup and the Corelight Labs Team made a capture the flag (CTF) competition available for attendees to play. The competition included 19 challenges of varying difficulties which involved tasks surrounding Zeek, including scripting, history of the project, traffic analysis, and more. 76 participants registered to play the CTF. The top three scoring players were:

  1. amosesso, with 4081 points
  2. zee_kweek, with 3996 points
  3. rand0mf0rest, with 3633 points

Congratulations and bragging rights to the winners!

Last year, we awarded points for participant’s solution write-ups, which we then shared via a post-event blog. While we did not award points for solution write-ups this year, we recognize that publishing the CTF materials and solutions benefits the community. As such, this blog serves as a debrief of the competition and a location to review the answers to the proposed puzzles. Additionally, we have published the challenge and solution resources from this and last year’s CTF into the zeek-training repository

In addition to this blog, Benjaminxreid wrote up a great summary of the solutions to the puzzles.

Challenge Solutions


This challenge’s aim was to raise awareness of the name change of the Zeek project (previously called Bro). One solution, proposed by Corelight Labs’ Yacin Nadji, is to search Youtube for “zeek vern new name”.

Flags: t-shirt, shirt, tshirt


This challenge was inspired by a SuriCon 2019 puzzle originally created by Sake Blok. The objective was to analyze a pcap which included the exfiltration of a file over an encrypted channel and recover the file contents. The key to decrypting the exfiltrated PDF relied on a random password generated by a website visited over a TLS connection. How were participants to decrypt the TLS connection? The attacker used email to conduct the exfiltration of the password protected PDF. It, as well as a SSLKEYLOGFILE, were included as attachments. Once carved from the email, the SSLKEYLOGFILE could be used to decrypt the TLS connection to retrieve the password to the PDF, which contained the flag.

Flag: YouFoundThisFlag!_Congrats!


The premise of this puzzle is that an attacker, dubbed PIANO FINGERS, gained access to one of your SSH servers and you have to determine the length of the password used by the attacker to elevate their privileges. This challenge was a throwback to a similar challenge (sudo-su) from last year’s CTF. The twist was, this pcap included Syslog messages so participants knew the exact moment in time when PIANO FINGERS executed “sudo su”. By understanding that SSH sends individual keystrokes as individual packets, one can simply count the packets preceding the Syslog message to count the characters of the actor’s password.

Flag: 10


The goal of this puzzle was to force players to learn about scriptland hook types. Hooks are very useful but can appear a bit quirky at first glance. They exist somewhere between a function and an event. The way to solve this challenge was to not become bogged down by the number of hooks in the script and instead to focus on what they were all doing: slightly modifying a global value. By waiting until all hooks were finished executing and then printing that value, the flag could be identified.

I enjoyed writing this challenge because I used a Python script to write the Zeek script for me. Code which writes code is always neat to think about and implement.

Flag: haak+bfnnmgqzvcvspqbzmmmppkcdwrsvjrzrhkvxrmmxbxspfvlkdmrdhljmyczclbnjtvsmbvsdtwgxlxqvkfnthytrnmzwrtpzdsltbtwfdgywzhwvlggctqqxdvndfkfrfyynxpmkbnlwrhgqcclptpknkbsjjnbddbsyztcmsqnycztjkrzmbwwzshpntfblyjqycykdhk


The motivation behind this puzzle was to demonstrate the utility of It also exposes script writers to the concept of namespacing (with the module declaration) and troubleshooting script bugs. I really like it and I think it achieves its goals without being overly complicated. The solution is to alter the script such that it correctly prints the concatenation of the x and y variables to reveal the flag.

Flag: try_and_try_again!


This puzzle introduced players to the ECS DNS extension. By default, Zeek’s DNS logging does not include information about DNS extensions. Zeek’s protocol parsing and scripting language does, however, provide mechanisms for inspecting DNS packet extensions (which could be used to enhance Zeek’s default logging). Since the pcap is rather small, one solution to this challenge could be to open the pcap with Wireshark and visually inspect all of the available fields Wireshark provides.



The intent of this challenge was to get participants thinking about anonymous, sometimes called lambda, functions and how they exist in Zeek scripts. How can script authors and debuggers observe or manipulate functions without a function name to reference? With the body of the function! The intended solution to this puzzle is to iterate through all available functions at Zeek’s initialization and hash their bodys’ contents to isolate the one which matches the hash provided in the challenge description.

Flag: failure_code-5


Surprisingly few developers have made surprisingly huge contributions to the Zeek project. A summary of a sliver of those contributions can be found in Zeek’s CHANGES file. This puzzle asked players to comb through that file and tally up mentions of developer names. Grep, awk, sed, cut, and other command-line text manipulation tools were the intended means of solving this puzzle.

Flag: Jon Siwek


This challenge was a silly one. The name was meant to distract players into trying to decode the contents of the script as morse code. The references to compressed paths in the challenge description was meant to guide players towards the compress_path() bif. By wrapping each string in this function before printing it, the strings reveal the flag in ASCII art.

Flag: ThisIsAFlag


Upon opening the pcap in Wireshark, a series of ICMP echo and echo-reply messages can be viewed. Participants could have compared what typical bodies of ping packets often include (perhaps by recording packets generated by the ping utility) with the bodies of the ping packets in the provided pcap. As the description of the challenge stated, the flag included the string “FLAG{{“. Players could have searched the contents of the pcap for this string. One way to do so could have been by applying the Wireshark display filter, ‘frame contains FLAG{{‘. Participants could then see where the flag begins and reassemble the entire flag.

Flag: FLAG{{ICMPCanBeUsedToExfiltrateData}}


Those who have worked IT or support roles often hate printers because of their cryptic errors, like “PC LOAD LETTER”. Those in the security industry may overlook printing services as attack vectors but recent vulnerabilities, such as PrintNightmare, show that printers are just as susceptible to attacks as Domain Controllers. This challenge offered a pcap to participants which included an IPP connection. Participants had to carve a file from the connection to isolate the flag. File extraction could be achieved with a manual tool, or some combination of existing tools like Wireshark and xxd.

Flag: printprintprintprint_Flag123!

samuel-likes-zeek part1 

By running the provided pcap through Zeek and observing the logs Zeek writes, participants could see that not much is in the pcap besides some SSH connections. Viewing the SSH log, the dots and dashes stand out. By reading a bit about the SSH protocol players may begin to understand that these dots and dashes are not “normal” for SSH sessions. Additionally, seasoned CTF players often have developed an eye for spotting common encoding schemes. Decoding the dots and dashes as morse code reveals the flag.


samuel-likes-zeek part2

This challenge is quite straightforward. Simply run the pcap through Zeek and observe the host_key field of the SSH log. 

Flag: 9d:c6:66:9d:65:53:a4:81:5b:d9:b7:61:5a:97:0f:a6

samuel-likes-zeek part3 

This challenge introduces participants to the idea of Zeek packages – scripts or plugins which extend Zeek’s default functionality. JA3 and HASSH are 2 such packages developed and shared by Zeek community members. The solution to this challenge is to install the HASSH package, developed by Corelight Labs’ Ben Reardon, and then run the pcap through Zeek. The HASSH fingerprint of the SSH sessions will then be present in Zeek’s SSH log.

Flag: 3ccd1778a76049721c71ad7d2bf62bbc


To solve this challenge players must first understand the properties of Bloom filters. A Python script and a Zeek script are used in conjunction, through the magic of Broker, to populate a Bloom filter object in Zeek. The Bloom filter represents 456,977 strings, each of length 4. Due to the configured false-positive rate of the Bloom filter object, we can calculate that there should be an inconsequential probability of the Bloom filter producing false-positive matches. This means all participants need to do is query the Bloom filter for all possible strings and see which 1 string it contains.
The second portion of this challenge involves loading the serialized Bloom filter, provided as part of the puzzle description, back into a Zeek script. This, again, relies on Broker. Within the Broker namespace is a function named data() which can be used to serialize/deserialize any Zeek object. This is a pretty powerful function and this challenge is likely an abuse of it. By deserializing the Bloom filter and bruteforce guessing against it, the flag can be obtained.

An interesting thought emerged from the design of this challenge: sharing probabilistic objects, like Bloom filters, instead of sharing raw indicators. An organization with sensitive intelligence could load a Bloom filter with the IOCs they’d like to share with the FP rate they are comfortable with, serialize the Bloom filter as a string, and then distribute that string to other organizations they’d like to share with (without exposing the original sensitive indicators). Neat!

Flag: aqsx


Today, the majority of conversations take place in Zeek’s Slack group. In the past, community communications took place on a public mailing list. This challenge’s goal was to guide players towards exploring the archive of that list. The solution to this puzzle could be found by using a search engine.

Flag: testing, testing, testing


To identify the flag in this puzzle, participants had to manually carve the tarball transferred in the pcap. This could be achieved with some combination of Python scripts, tshark, or xxd.



This challenge was a bit complicated. The basic idea is that there is a complex Zeek script, representing a lock, which players need to understand. Then, players had to extend the script to find the correct combination which “picked” the lock. 

The Lock consisted of 4 Tumblers and each Tumbler consisted of 1 to 4 Pins. Pins are essentially circle arcs of varying degrees, Tumblers are essentially circles with non-overlapping arcs, and Locks are essentially a set of concentric circles. Tumblers, and all of their Pins, spin at their own separate speeds. The object of the challenge is to identify when a set of Pins, one from each Tumbler, align such that a straight line can be drawn from the outer Tumbler to the inner Tumbler. 

Thanks goes to Justin Azoff for publishing his solution to this challenge.

Flag: 154-0002


The solution to this puzzle involved observing an SCTP connection. Many people have heard of UDP, TCP, and ICMP. However, some may not know that additional transport protocols exist. By using a manual file carving technique, players could extract a tarball containing a Unix user’s home folder. By investigating the tarball, participants who located the user’s .bashrc (hidden) file would find a password which decompresses the flag file.

Flag: SCTP_is_a_troll_protocol_8837??

Wrapping Up

Overall, this was another successful ZeekWeek CTF. Thank you to all those who participated in the event. Without players, there’d be no CTF. Thank you to all those who volunteered their time to create and vet puzzles. Without puzzle creators and content reviewers, there’d be no CTF. Thank you to all those who facilitated the event. Without your support, there’d be no CTF.

Special shout-outs to the following individuals for their help with this event:

  • Fatema Bannat Wala
  • Chandan Chowdhury
  • Amber Graner
  • Geoff Kasten
  • Anthony Kasza
  • Yacin Nadji
  • Kristopher Newsome
  • Dubem Nwoji
  • Vern Paxson
  • Ben Reardon

If you would like to know more about this CTF, Zeek, or getting involved in the Zeek Community please check out

About the Zeek Project Training Subgroup: The Zeek training subgroup that will focus on formulating some preliminary goals for Zeek approved training and tackle broader topics in the area of Zeek training. Frequently, we are asked about where people can find Zeek-related training and whether there is a central place to find Zeek-related training content. Hence to address the needs of the community and in general have some training programs that are approved by the Zeek project, we are creating this subgroup to focus on these goals.

About Corelight Labs: From detecting attacks to profiling behavior, Corelight Labs creates new ways to deepen network insight and strengthen enterprise security. We work in close partnership with other innovators at Corelight, and we take pride in the robust, deeply technical capabilities we create.



%d bloggers like this: