LACTF 2026
tic-tac-no
Description
Tic-tac-toe is a draw when played perfectly. Can you be more perfect than my perfect bot?
ncchall.lac.tf30001
Solution
Goal of this challenge is to win tic-tac-toe board game to get the flag. In main function there is a check that will print content of flag.txt if we win the game.
int main() {
...
printBoard();
if (winner == player) {
printf("How's this possible? Well, I guess I'll have to give you the flag now.\n");
FILE* flag = fopen("flag.txt", "r");
char buf[256];
fgets(buf, 256, flag);
buf[strcspn(buf, "\n")] = '\0';
puts(buf);
}
...
}
The mark that use by computer and player are declared as global variable.
char board[9];
char player = 'X';
char computer = 'O';
The vulnerability is in function playerMove.
void playerMove() {
int x, y;
do{
printf("Enter row #(1-3): ");
scanf("%d", &x);
printf("Enter column #(1-3): ");
scanf("%d", &y);
int index = (x-1)*3+(y-1);
if(index >= 0 && index < 9 && board[index] != ' '){ // Check only pass when 3 condition must satisfied
printf("Invalid move.\n");
} else {
board[index] = player; // Should be safe, given that the user cannot overwrite tiles on the board
break;
}
} while(1);
}
The check logic:
-
Only blocks valid indexes that are already occupied
-
Allows:
-
index < 0 -
index >= 9
-
Which mean we can arbitrary write in memory based on calculated index.
Simple way to win the tic-tac-toe is to overwrite global variable computer = 'O' with 'X' . So, whereever computer movement will placed 'X' mark in board that make us eazy towin.
After debugging using gdb index for computer is located at index -23 .
Based on the index calculation formula in program we can input 1 and -22 then random valid movement to win.

Flag: lactf{th3_0nly_w1nn1ng_m0ve_1s_t0_p1ay}
tcdemy
Description
I'm telling you, tcache poisoning doesn't just happen due to double-frees!
ncchall.lac.tf31144