Description

Are you the fastest cowboy here? http://breathtaking-roulette.ctfz.zone/

TLDR

Race Condition on WebSockets

Intro

When entering the application, we can see the game that looks like it is presented in Figure 1:

Figure 1: The basic game status

Figure 1: The basic game status

Here, we play VS computer opponent and our goal is to kill him faster, than he will kill us. According to the concept of “Russian Roulette”, we have a 1/6 chance to shoot, the same is true about the opponent. But after some tries we can notice that when the opponent shoots he instantly kills the player, but when the player shoots, the opponent keeps being alive and shoots back to player (which is killing us instantly too). This is shown in Figure 2:

Figure 2: Player succeeded to shoot case

Figure 2: Player succeeded to shoot case

From here, we can understand that our goal is to somehow kill the opponent.

Original Solution

We can use Burp to inspect the game logic. So, if we look at the Websockets section we will see the client-server interactions, which is shown in Figure 3:

Figure 3: Websocket interactions

Figure 3: Websocket interactions

Application follows the sequence:

Also, we can notice that there are little delays between the shots we can make while we will be playing in the UI. That means that we can try to bypass it and make several shots before the game ends.

So then we should restart the game and send as much shot messages to server as we can putting the initial shot message to the Burp repeater and fast-clicking the sending button. After some tries we will catch the state when the opponent lives are below 0, which is shown in Figure 4: