Shell Maze is a misc challenge that was part of the 2022 TUCTF. We had to solve a maze by sending the right commands to the server. After solving a maze, we got the next one that was a bit harder than the previous one.

## Solution

First maze:

``````XOOOOOOOOOOOOO######
#############O######
#############O######
###OOOOOOOOOOO######
#OOO################
#OOOOOOOOOOOOOOOOO##
#################O##
##########OOOOOOOO##
##########OO########
###########O########
#OOOOOOOOOOOOOOOOOOO
``````
Command Description
`>` Move right
`<` Move left
`V` Move down

### Game logic

The game logic is pretty simple. We have to move the `X` to the bottom right corner. The `X` can move only right, left and down. If the `X` moves to the right or left, it can move only if there is an `O` in the next column. If the `X` moves down, it can move only if there is an `O` in the next row.

``````if x_row == len(maze) - 1: # if we are in the last row -> move right
io.sendline(b'>')
else:
if maze[x_row + 1][x_col] == "O":
io.sendline(b"V")
else:
o_pos = find_o_in_row(x_row + 1)
if o_pos < x_col:
io.sendline(b"<")
else:
io.sendline(b">")
``````

### Final code

``````#!/usr/bin/env python
from pwn import remote

io = remote('chals.tuctf.com', 30204)
io.recvuntil(b'down.\n')

x_row, x_col = 0, 0
def get_pos_of_X():
global x_row, x_col
for row in range(len(maze)):
for col in range(len(maze[row])):
if maze[row][col] == 'X':
x_row, x_col = row, col
return

def find_o_in_row(row):
for col in range(len(maze[row])):
if maze[row][col] == 'O':
return col
return -1

run = 1
while True:
try:
maze = io.recvuntil(b'Move: ').decode().split("\nMove: ")[-2]
except:
print(io.recvall().decode())
break

print(maze)
print(f"maze {run}")

run += 1
for line in maze.splitlines():
if line and line[0] == 'X':
start_line = maze.splitlines().index(line)
maze = [list(line) for line in maze \
.splitlines()[start_line:]]
break
else:
maze = [list(line) for line in maze.splitlines()]

get_pos_of_X()

if x_row == len(maze) - 1:
io.sendline(b'>')
else:
if maze[x_row + 1][x_col] == "O":
io.sendline(b"V")
else:
o_pos = find_o_in_row(x_row + 1)
if o_pos < x_col:
io.sendline(b"<")
else:
io.sendline(b">")
``````

Output:

``````\$ ./solve-maze.py
[+] Opening connection to chals.tuctf.com on port 30204: Done
XOOOOOOOOOOOOO######
#############O######
#############O######
###OOOOOOOOOOO######
#OOO################
#OOOOOOOOOOOOOOOOO##
#################O##
##########OOOOOOOO##
##########OO########
###########O########
#OOOOOOOOOOOOOOOOOOO
maze 1
OXOOOOOOOOOOOO######
#############O######
#############O######
###OOOOOOOOOOO######
#OOO################
#OOOOOOOOOOOOOOOOO##
#################O##
##########OOOOOOOO##
##########OO########
###########O########
#OOOOOOOOOOOOOOOOOOO
maze 1
...
O###################
O###################
O###################
...
############O#######
############O#######
##OOOOOOOOOOOOOOOOXO
maze 50
[+] Receiving all data: Done (1.33KB)
[*] Closed connection to chals.tuctf.com port 30204

O###################
O###################
O###################
...
############O#######
############O#######
##OOOOOOOOOOOOOOOOOX