> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/tryhackme/2026/fools-mate.md).

# Fools Mate

{% embed url="<https://tryhackme.com/room/foolsmate>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Scenario

It's mate in one. You know it, the engine knows it, my grandma knows it. The board says checkmate is one click away. The engine says no. Settle the argument.

You can access the web app from your AttackBox's browser via: `http://MACHINE_IP`

## Summary

<details>

<summary>Summary</summary>

In Fools Mate, - a chess game sceanarion -the client attempts to prevent checkmate moves using JavaScript running in the browser. But this check exists only on the client side, with no matching validation on the server. By bypassing JavaScript execution (via Burp Suite or a direct `curl` request to `/api/move`), we submit a checkmate move (`a1` → `a8`) straight to the backend. The server accepts it without question, revealing the flag.

</details>

## Exploitation

We'll start right away by visiting the page as specified in the scenario. Here we have a chess game infront of us. We are able to reset postions and make our moves.

```
http://10.112.138.159/
```

<figure><img src="/files/9gJX4nnQnKGd2Llx52qh" alt=""><figcaption></figcaption></figure>

But when we try to checkmate the opponent, we'll get an error message and the move is prevented.

<figure><img src="/files/Ur1lnUFKQX2L0YE54C5x" alt=""><figcaption></figcaption></figure>

We take a look into the source code of the app and see a client side check that prevents checkmate moves.

```
view-source:http://10.112.138.159/js/app.js
```

<figure><img src="/files/peVpJAnX1f7xpvuJuPbb" alt=""><figcaption></figcaption></figure>

We can easily bypass this client-side check by sending the requests without JavaScript enabled. To do this, we can either disable JavaScript in the browser, intercept and modify a benign request in BurpSuite, or send the request directly using curl. This way, the client-side check doesn't even take place.

First we follow the approach in BurpSuite and catch a benign request and redirect it to the repeater module.

<figure><img src="/files/cssie6k0TI5Uo0vieSVc" alt=""><figcaption></figcaption></figure>

We then adapt the post body so that we do a checkmate move and send the request. We retrieve the flag.

<figure><img src="/files/CP9J3gfuGecE2QmAz19u" alt=""><figcaption></figcaption></figure>

We recreate the steps taken in BurpSuite using cURL.

We send the checkmate move (`a1` to `a8`) to `/api/move` using curl bypassing any client side check. Our move gets evaluated and we retrieve the flag.

{% code overflow="wrap" %}

```
target=10.112.138.159
```

{% endcode %}

{% code overflow="wrap" %}

```
curl -s -c cookies.txt -b cookies.txt -X POST http://$target/api/move -H "Content-Type: application/json" -d '{"from":"a1","to":"a8"}'
```

{% endcode %}

<figure><img src="/files/fVRfSfGxRq3Zkvk49iFI" alt=""><figcaption></figcaption></figure>
