Skip to content

Instantly share code, notes, and snippets.

@PsHegger
Created September 19, 2021 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PsHegger/1c122885e81d84bafcd3641fe82d6fb7 to your computer and use it in GitHub Desktop.
Save PsHegger/1c122885e81d84bafcd3641fe82d6fb7 to your computer and use it in GitHub Desktop.
Script for solving the Words Church challenge in the 2021 h@cktivitycon CTF
#!/usr/bin/env python3
import socket, time
directions = [(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)]
def parse_grid(txt):
return [l[l.find('|')+1:].strip().replace(' ', '') for l in txt.split('\n')[2:]]
def calculate_coords(grid, start, direction, i):
x, y = start[0] + i * direction[0], start[1] + i * direction[1]
if y < 0:
y += len(grid)
if y >= len(grid):
y -= len(grid)
if x < 0:
x += len(grid[y])
if x >= len(grid[y]):
x -= len(grid[y])
return (x, y)
def is_word_present(grid, start, word, direction):
for i in range(len(word)):
x, y = calculate_coords(grid, start, direction, i)
if grid[y][x] != word[i]:
return False
return True
def find_word(grid, word):
start = None
direction = None
for y in range(len(grid)):
for x in range(len(grid[y])):
s = (x, y)
for d in directions:
if is_word_present(grid, s, word, d):
start = s
direction = d
break
if start is not None:
break
if start is not None:
break
coords = []
for i in range(len(word)):
coords.append((start[0] + i * direction[0], start[1] + i * direction[1]))
return coords
def send(s, txt):
print(txt)
s.sendall(bytes(txt, 'utf-8'))
time.sleep(.5)
resp = ""
while True:
try:
resp += s.recv(4096).decode('utf-8')
except:
break
for l in resp.split('\n'):
if "flag{" in l:
return resp
if ': >' in resp.split('\n')[-1]:
break
return resp
def _main():
grid = None
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.connect(("challenge.ctf.games", 30838))
time.sleep(2)
print(s.recv(4096).decode("utf-8"), end = " ")
resp = send(s, "play")
print(resp, end=" ")
while True:
lines = resp.split('\n')
new_grid_start = -1
for i in range(len(lines)):
if lines[i].startswith('Wordsearch #'):
new_grid_start = i
break
if new_grid_start >= 0:
new_grid_lines = lines[new_grid_start + 1:new_grid_start+19]
grid = parse_grid('\n'.join(new_grid_lines))
word = None
if ": >" in lines[-1]:
word = lines[-1][:lines[-1].find(':')]
if word is None:
break
coords = find_word(grid, word)
resp = send(s, str(coords))
print(resp, end="")
s.close()
if __name__ == "__main__":
_main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment