Rating:

We are given an IP and port to connect via netcat.
It greets me with a description of the challenge and an example maze.

After starting the challenge by entering `Y`, I get a huge maze that I will have to solve in only a few seconds.
I will have to write a tool for it!

## Parsing the Maze

The most important step in solving the maze automatically is parsing it into a matrix of some sort. To better read it and automate everything I used `pwntools` to solve it.

```python
import pwn as p

conn = p.remote("192.168.125.100",9003)

conn.recvuntil(b'Ready? (Y/N)')
conn.sendline("Y")

# Getting and parsing the labyrinth by removing spaces & splitting into a matrix
lab = list(map(lambda x: list(x),conn.recvuntil("\n\n").decode().strip().replace(" ","").split("\n")))
```

## Actually solving the maze

To make it easier, I searched for a good pathfinding algorithm on the internet and found this one: [pathfinding](https://pypi.org/project/pathfinding/)
I needed to convert it to a matrix of weights first so that the tool can understand it.
Lets just replace the `#`'s with 0 and everything else with 1.

```python
# A very complex way of replacing everything in the matrix
lab = list(map(lambda x: list(map(lambda y: int(y.replace("#", "0").replace("O", "1").replace("L", "1").replace("H", "1")), x)),lab))
```
And then solving it with the pathfinding package:

```python
from pathfinding.core.diagonal_movement import DiagonalMovement
from pathfinding.core.grid import Grid
from pathfinding.finder.a_star import AStarFinder

grid = Grid(matrix=lab)

start = grid.node(0, 0) # Where L was
end = grid.node(len(lab) - 1, len(lab[len(lab) - 1]) - 1) # Where H was
finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
path, runs = finder.find_path(start, end, grid)
```

The path variable holds all of the moves it did to solve the maze as tuples `(0,1), (0,2), (1,2)...` but the challenge expects us to send the directions...

## Converting the moves to directions and sending the solution

```python
last = path[0]
directions = {(0, 1): "D", (0, -1): "U", (1, 0): "R", (-1, 0): "L"} # A dict that replaces multiple if statements
log = ""
for i in path:
if last == i: # Ignoring the first run
continue

log += directions[tuple(map(lambda a, b: a - b, i, last))] # Subtracting two tuples
last = i

conn.sendline(log) # Sending the directions
print(conn.recvall().decode()) # Prints the flag and the rest of the response
```

Done!

Original writeup (https://github.com/xXLeoXxOne/writeups/blob/main/Imperial%20CTF%202022/escapemaster.md).