18th January 2022
Write-up Advent of CTF challenge 20

Write-Up Advent of CTF 20

The NOVI University Of Applied Sciences is offering an Advent CTF challenge for December 2020. The CTF is created by our community member of the Hackdewereld.nl and Chief Lecturer for Cyber Security at the NOVI University, Arjen Wiersma. If you want to participate in these CTF challenges, you can create an account on the website https://www.adventofctf.com/.

Challenge 20

  • Description: To pass the time until Christmas the elves challenge Santa to a game of tic-tac-toe. Santa plays X, can you make him win?
  • 2000 Points

It seems that we have to play a tic-tac-toe game with Santa. Can we win the game? Let’s find out! We visit the challenge URL https://20.adventofctf.com, and we are ending up on this web page with a tic-tac-toe game, not surprising huh?

Advent of CTF Challenge 20 tic-tac-toe game
Advent of CTF Challenge 20 tic-tac-toe game

The game was already started. It’s our turn, I can place the O the right top box or on the left bottom. In both scenarios, we will win the game. Because then we have three in a row. How the game tic-tac-toe works. Let’s try.

Advent of CTF Challenge 20 tic-tac-toe game win
Yup we won

Yup, we won the game. Ok, that was easy. But, we have to do something with it, there is no way that Santa will win this game unless we adjust the game a little bit. Let’s switch to Burp Suite and check the requests and the cookies.

At the start of the game, this is our cookie.


After decoding this base64 cookie, we got this as the cookie value:

..}q.(X….boardq.]q.(]q.(X….Oq.h.Ne]q.(h.X….Xq.h.e]q.(h.h.h.eeX….turnq.h.X….finishedq    .X….winnerq

After we have won the game, our cookie is changed to this:


It seems, that we have to do something with this cookie. Let’s take the cookie information to Google and let’s see what we can find. We can see that the cookie is ending with a dot (“.“). I’ve used this information to search, and I found this website: https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html.

It has something to do with serialized data. According to the information on that website, we can manipulate this data. For that, we can use Pickle. There is a Python Library for Pickle. Also, that webpage is giving is the information that this module can be used for serializing and de-serializing data in a Python object. Pickling is a process where a Python object is converted into a byte stream and unpickling is the inverse operation, whereby a byte stream (from a binary file or bytes-like object) is converted back into an object hierarchy.

So, the uncoded Base64 cookie shows us the pickling value (or serialized value). We need to do a de-serialization of this data so that we can modify the cookie and serialize this data back with the use of the Pickle Python Library.

I’ve written a Python script for de-serialize the data. The cookie is now human readable.

import pickle
import base64

def cookie(cookie):
    cookie = base64.b64decode(cookie)
    cookie = pickle.loads(cookie)


The output from the first cookie.

{'board': [['O', 'O', None], ['O', 'X', 'X'], [None, 'X', 'X']], 'turn': 'O', 'finished': False, 'winner': '', 'sane': True}

We see now, that this cookie has information about the game. And, it also determines the starting position of the game. The de-serialization of the winning cookie has this information:

{'board': [['O', 'O', None], ['O', 'X', 'X'], ['O', 'X', 'X']], 'turn': 'X', 'finished': True, 'winner': 'O', 'sane': True}

We can make this easy, by only modifying the winning cookie and we can grab the flag. After trying multiple times to modify the cookie, I’m only receiving an Internal Server Error, after applying the new cookie on the website. It turns out, that the winner is calculated based on the state of the board. So, there is no need to modify the 'turn': 'X', 'finished': True, 'winner': 'O', 'sane': True} part. Only the board needs to be modified. After some time scripting, I came with this script as the solution to this challenge.

import pickle
import base64

def NewCookie(cookie):
    payload = base64.b64decode(cookie)
    payload = pickle.loads(payload)
    payload["board"] = [['O', 'O', 'X'], ['O', 'None', 'X'], ['None', 'X', 'X']]
    payload = pickle.dumps(payload)
    newcookie = base64.b64encode(payload)


After running this script, we get this new cookie:


After replacing the current cookie, with the new cookie, the winner is calculated to X. The flag is now visible: NOVI{p1ckle_r1ck}.

Advent of CTF Challenge 20 Flag
Advent Of CTF Challenge 20 flag

Thanks for reading!


I'm a cybersecurity enthusiast! I'm working as an IT Security Engineer for a company in The Netherlands. I love writing scripts and doing research and pentesting. As a big fan of Hack The Box, I share my write-ups on this blog. I'm blogging because I like to summarize my thoughts and share them with you.

View all posts by T13nn3s →

Leave a Reply

Your email address will not be published. Required fields are marked *