Challenge Overview
Can you win in a convincing manner against this chess bot? He won't go easy on you!
You can find the challenge here.
Solution
The challenge mentions to win in chess against the bot to get the flag but I checked the source code first regardless. So when first opening the page and looking at the html source of the index file you can see two script sections. Here is the first one:
<script>
var ws_address = "ws://" + location.hostname + ":" + location.port + "/ws/";
const ws = new WebSocket(ws_address);
ws.onmessage = (event) => {
const message = event.data;
updateChat(message);
};
function sendMessage(message) {
ws.send(message);
}
function updateChat(message) {
const chatText = $("#chatText");
chatText.text(message);
}
</script>
One key thing you can see here is that they use a sendMessage function that will be used in the next script section. The next part is pretty long so I just included the important part to note of the second section near the end of the script tag:
...
else if (event.data.startsWith(`info depth ${DEPTH}`)) {
var splitString = event.data.split(" ");
if (event.data.includes("mate")) {
message = "mate " + parseInt(splitString[9]);
} else {
message = "eval " + parseInt(splitString[9]);
}
sendMessage(message);
}
You can see it uses both mate and eval for the message and if it has mate then it means checkmate. You can use Burp Suite, but since this problem is fairly simple you can just use the console in dev tools. By using the function sendMessage they created which is just ws.send(message) you can test out different values. Let's say you try to use the value one with "mate " as a part ofthe message like this:
sendMessage("mate 1")
After sending this in the console it says "drown in 1 moves" and if you increase the value it can just go on 2, 3, 4, and so on. Putting in 0 makes the message say "eventually checkmate me" and when putting in negative values like -1 nothing changes even when you increase the negative values. So just by using the basic eval you get better results with negative values:
sendMessage("eval -1000000000")
That gives the flag. You can try many different values if you'd like to see how the system reacts to it and better understand. For instance 50,000 is the threshold between "you're quite the chess shark" and giving the flag. So this is the largest number you can send to get the flag:
sendMessage("eval -50001")
Flag: picoCTF{c1i3nt_s1d3_w3b_s0ck3t5_e5e7...}