Background
I wrote this challenge with a coworker of mine Richard Rohrkemper, for a “mini-ctf” that my company was hosting at CactusCon 2019. The mini-ctf challenges are meant to be beginner-friendly and direct, and for them we frequently use html5up’s templates, as they are easy to use and allow us to make nice looking challenges without having to work on site design.
Goal of the challenge / Challenge Design
We wanted this challenge to be a single-page application with the primary vulnerability being a lack of strong server-side validation. The site is a page to play tic-tac-toe, but where a user cannot win without interfering with the HTTP request (This is where Rich got the name for the challenge). Each turn the server will always place anO
in the first two spots it can, and the user can choose where to place theirX
.
If you remove any pieces, you’ll get an error and the following response:
And while this is true, in the source, you can see that the function to check how many X’s and O’s, does not do a length check on the given string.
|
|
This means that even though the game checks for win conditions on the board, pieces can be placed off of the board (Solution 1) without an error, which should be pretty easy to find while manipulating the request.
Solution
Solution 1:
Response: X--------OO
_X_|___|___
___|___|___
| |
OO
Response: XX-------OOOO
_X_|_X_|___
___|___|___
| |
OOOO
Response: XXX------OOOOOO
_X_|_X_|_X_
___|___|___
| |
OOOOOO
Solution 2:
While we did not plan on this solution, we agreed that by restricting the win condition to the first solution, we were making the win a little too abstract for our audience.
Response: XOO------
_X_|_O_|_O_
___|___|___
| |
Response: XOOOXO---
_X_|_O_|_O_
_O_|_X_|_O_
| |
Response: XOOOXOOOX
_X_|_O_|_O_
_O_|_X_|_O_
O | O | X