Terminal - Strace Ltrace Retrace


Tinsel Upatree is hanging out in Santa’s kitchen, and seems nervous about Frost Fest:


Hiya hiya, I’m Tinsel Upatree!

Say, do you know what’s going on next door?

I’m a bit worried about the whole FrostFest event.

It feels a bit… ill-conceived, somehow. Nasty even.

Well, regardless – and more to the point, what do you know about tracing processes in Linux?

We rebuilt this here Cranberry Pi that runs the cotton candy machine, but we seem to be missing a file.

Do you think you can use strace or ltrace to help us rebuild the missing config?

We’d like to help some of our favorite children enjoy the sweet spun goodness again!

And, if you help me with this, I’ll give you some hints about using Wireshark filters to look for unusual options that might help you achieve Objectives here at the North Pole.

The terminal says I need to figure out what the cotton candy software is looking for:


There’s a single binary in the current directory:

kotton_kandy_co@44387eee33dc:~$ ls


Running the binary say it can’t open the configuration file:

kotton_kandy_co@fe9c13a44834:~$ ./make_the_candy 
Unable to open configuration file.

ltrace shows it’s trying to open registration.json:

kotton_kandy_co@fe9c13a44834:~$ ltrace ./make_the_candy
fopen("registration.json", "r")                           = 0
puts("Unable to open configuration fil"...Unable to open configuration file.
)               = 35
+++ exited (status 1) +++

I’ll create it:

kotton_kandy_co@fe9c13a44834:~$ echo "0xdf was here" > registration.json
kotton_kandy_co@fe9c13a44834:~$ ltrace ./make_the_candy
fopen("registration.json", "r")                           = 0x5576b3228260
getline(0x7fff5426ab00, 0x7fff5426ab08, 0x5576b3228260, 0x7fff5426ab08) = 14
strstr("0xdf was here\n", "Registration")                 = nil
getline(0x7fff5426ab00, 0x7fff5426ab08, 0x5576b3228260, 0x7fff5426ab08) = -1
puts("Unregistered - Exiting."Unregistered - Exiting.
)                           = 24
+++ exited (status 1) +++

strstr is looking for the offset of one string in another. So now it’s exiting after looking for the string “Registration” in the configuration file. I’ll set that as the contents of the file, and re-run:

kotton_kandy_co@fe9c13a44834:~$ echo "Registration" > registration.json
kotton_kandy_co@fe9c13a44834:~$ ltrace ./make_the_candy
fopen("registration.json", "r")                           = 0x55bd01813260
getline(0x7ffd5d2c3370, 0x7ffd5d2c3378, 0x55bd01813260, 0x7ffd5d2c3378) = 13
strstr("Registration\n", "Registration")                  = "Registration\n"
strchr("Registration\n", ':')                             = nil
getline(0x7ffd5d2c3370, 0x7ffd5d2c3378, 0x55bd01813260, 0x7ffd5d2c3378) = -1
puts("Unregistered - Exiting."Unregistered - Exiting.
)                           = 24
+++ exited (status 1) +++

strchr is looking for the “:” in the file. I’ll add that:

kotton_kandy_co@fe9c13a44834:~$ echo "Registration:" > registration.json
kotton_kandy_co@fe9c13a44834:~$ ltrace ./make_the_candy
fopen("registration.json", "r")                           = 0x56476ccc9260
getline(0x7ffc1c38ff20, 0x7ffc1c38ff28, 0x56476ccc9260, 0x7ffc1c38ff28) = 14
strstr("Registration:\n", "Registration")                 = "Registration:\n"
strchr("Registration:\n", ':')                            = ":\n"
strstr(":\n", "True")                                     = nil
getline(0x7ffc1c38ff20, 0x7ffc1c38ff28, 0x56476ccc9260, 0x7ffc1c38ff28) = -1
puts("Unregistered - Exiting."Unregistered - Exiting.
)                           = 24
+++ exited (status 1) +++

Now it’s looking for “True”. Adding that solves the challenge:

kotton_kandy_co@fe9c13a44834:~$ echo "Registration:True" > registration.json
kotton_kandy_co@fe9c13a44834:~$ ./make_the_candy


     *                              *
      *                            *
       *                          *
        *                        *

Customer Complaint Analysis


Tinsel appreciates my help, and has some tips to offer:

Great! Thanks so much for your help!

I’m sure I can put those skills I just learned from you to good use.

Are you familiar with RFC3514?

Wireshark uses a different name for the Evil Bit: ip.flags.rb.

HTTP responses are often gzip compressed. Fortunately, Wireshark decompresses them for us automatically.

You can search for strings in Wireshark fields using display filters with the contains keyword.

In the badge, two hints unlock:

  • RFC3514 defines the usage of the “Evil Bit” in IPv4 headers.
  • Different from BPF capture filters, Wireshark’s display filters can find text with the contains keyword - and evil bits with ip.flags.rb.


The prompt in the badge provides a downloadable file, jackfrosttower-network.zip, which contains a single file, jackfrosttower-network.pcap.


This video shows the complete analysis:

Looking at the PCAP, there are 32 TCP streams, 16 of which request a complain web page, and the next 16 POST a complain to the page.

One of the complaints doesn’t have the “evil bit” on, and it’s from a human, Muffy VonDuchess Sebastian in room 1024:


Using the WireShark filter ip.flags.rb==1 and http.request.method == POST, I can get the 15 other packets with the POST request data from the Trolls. Then, with the WireShark search (Ctrl-f), I can look for 1024, finding exactly three Trolls complaining about the woman in 1024.

image-20220107203153340 image-20220107203213606 image-20220107203232372

Putting their names in alphabetical order generates the flag.

Flag: Flud Hagg Yaqh