2 minutes
cherryNo.7
TUCTF 2022 - Shell Maze
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}")
if "Loading next level..." in maze:
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
Loading next level...
Congrats! Here's your flag: TUCTF{1_4m_4_7ru3_n37_7r4v3l3r_357269}
Flag
The flag is “TUCTF{1_4m_4_7ru3_n37_7r4v3l3r_357269}”.