> For the complete documentation index, see [llms.txt](https://notes-95.gitbook.io/documents/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://notes-95.gitbook.io/documents/home/ctf-lab-write-ups/tryhackme/web-exploitation/fools-mate.md).

# Fools Mate

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

### **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.

<details>

<summary><strong>Summary</strong></summary>

Fool's Mate is an easy, chess-themed web challenge built around a client-side validation flaw. An online chessboard application refuses to let you play an objectively legal checkmating move, but that refusal only exists in the browser because the server never independently verifies whether a move is actually legal before accepting it. The challenge is proving that gap: catching the request the browser sends for a move, and sending a different one directly to the server instead.

</details>

***

### **Recon**

I first navigated to the target website:

```
http://10.64.144.245
```

Which brought me to the Endgame Trainer webpage. The webpage is an online chessboard where I am assuming users visit to practice their chess skills!

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

While exploring the webpage a little bit, I found that if I moved the rook from the a1 square to the a8 square to put the opponent in checkmate, a pop-up window appears with a threatening message!

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

***

### **Enumeration**

I viewed the webpages source page with DevTools by pressing F12 on my machine's keyboard. Once in DevTools, I navigated to the Debugger tab. I viewed the HTML content under app.js and I found something very interesting.

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

When the user attempts to checkmate, the premovecheck() function and the probe.move results in a checkmate, then the message, "I'll shut down your PC if you play that." Which tells me that this prevention is happening on the client side.

<details>

<summary><strong>Why this matters?</strong></summary>

If the check only runs client side, it isn't a real rule, its only advisory. The server would still need to be tested directly though!

</details>

***

### **Exploitation**

**DevTools**

The first thing I need to do is capture a POST request from the Network tab. After moving the rook from a1 to a2, I received a POST /api/move/ request. I right-clicked the request and clicked on "Edit and Resend." In the new request, I scrolled down to the body section and inputted:

```
{"from":"a2","to":"a8"}
```

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

From there, I hit send and confirmed my new request sent: "200". I viewed the Response tab on the right and right there, I found the flag!

***

### **Burp Suite**

An alternative way I found to get the flag is by using Burp Suite instead of DevTools. In this section I will show you how I got the flag by using Burp Suite.&#x20;

First, I opened Burp Suite, and opened the browser through Burp Suite in the Proxy Tab and to the right I clicked on "Open Browser." Once the browser loaded I navigated to the target website, <http://10.64.144.245>, and then turned my Proxy Intercept on.

From there, I moved the rook from a1 to a2 like before and captured the POST request:

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

Once I captured the /api/move/ POST request, I sent the request to Repeater. While in Repeater, I changed the request body from "a1" to "a2" to from "a2" to "a8" and sent the request. After sending the new POST request, I received a 200-OK response and when I looked towards the bottom, the flag was printed.

&#x20;

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

***

### **curl**

I have successfully shown how I have achieved in finding the flag by capturing the POST /api/move/ request in DevTools and in Burp Suite.

In this section, I will demonstrate how I recreated the steps from above by just using the curl command.

```
curl -X POST "http://10.64.144.245/api/move" -H "Content-Type: application/json" -d '{"from":"a1","to":"a8"}'
```

This curl command sends a POST request to the /api/move/ endpoint on the target's server by submitting a payload that describes a move from square a1 to square a8.

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

After running the curl command, I received the flag!

<details>

<summary><strong>Why this matters?</strong></summary>

All three methods hit the same gap, /api/move/, and never rechecked whether the move was legal. Once the request format is known, curl is the fastest way to produce it.

</details>

***

### **Key Takeaways**

* premovecheck() only runs client-side, it never touches the server.
* /api/move/ accepts any from/to pair without validating legality
* DevTools "Edit and Resend" and Burp's Repeater accomplish the same thing; curl reproduces it without a browser at all.
