← Back to Writeups
CUSTOMMediumpwn

Maze

XESXOR9/2/20262 min read
#pwn#custom#medium#negative_array_index#out_of_bounds_memory_access#game_logic_exploitation

Maze

Platform: spbctf | Category: pwn | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-03-11 | Status: Solved Techniques: negative_array_index, out_of_bounds_memory_access, game_logic_exploitation

Summary

Server: nc 109.233.56.90 11574 Binary: task — ELF 64-bit x86-64, PIE, not stripped, with debug_info Points: 10

Maze — SPB CTF Pwn Season

Description

"Пройдите лабиринт и соберите 10 сокровищ"
(Navigate the maze and collect 10 treasures)

Server: nc 109.233.56.90 11574
Binary: task — ELF 64-bit x86-64, PIE, not stripped, with debug_info
Points: 10

Analysis

Missing bounds check in try_move function — no check for x < 0! This allows accessing memory before the maze array.

Memory Layout:

  • name[8]: 0x40a0
  • maze[1550]: 0x40c0
  • score: 0x470c

The program checks x < width and y >= 0 and y < height, but forgets to check x >= 0. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Exploitation Strategy:

  1. Set name to "XXXXXXX" (X = 0x58 = treasure character)
  2. Collect 4 real treasures in the maze (score = 4)
  3. Navigate to position (0, 0)
  4. Move left into negative x territory (no bounds check!)
  5. Step on 'X' characters in name buffer at y=0, x=-32 to x=-25
  6. Each 'X' increments score → score reaches 10
  7. system("cat /flag") is called
python
from pwn import *

io = remote('109.233.56.90', 11574)

# Set name to treasure characters
io.sendlineafter(b'name: ', b'XXXXXXX')
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Navigate maze, collect 4 treasures, reach (0,0)
# Then move left repeatedly to access name buffer
moves = "... collect treasures ... reach (0,0) ... " + "a" * 32  # 'a' = left

for move in moves:
    io.sendline(move.encode())

io.interactive()

Key insight: The name buffer is located BEFORE the maze array in memory. By moving left (negative x), we access the name buffer where we placed 'X' (treasure) characters. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍