# solution to Maze of HITCON 2014 CTF
from telnetlib import Telnet
import terminal
from time import sleep
from IPython.html import widgets # Widget definitions
from IPython.display import display # Used to display widgets in the notebook
if "map_mem" not in globals():
map_mem=dict()
w=widgets.HTMLWidget()
w2=widgets.HTMLWidget()
def show_maze2():
html ="<table>"
for i in range(-44,45):
html+="<tr>"
for j in range(-44,45):
mx,my = j, i
bg = {'@': '#000', '.': '#fff', '':'#0f7' }[map_mem.get((mx,my), '')]
html+='<td style="background-color: %s; width: 6px; height: 6px;">%c</td>'%(bg, ' ')
html+="</tr>"
html+="</table>"
w2.value = html
def show_maze(d):
html ="<table>"
for i in range(9):
html+="<tr>"
for j in range(9):
try:
mx,my = cx+j-4,cy+i-4
bg = {'@': '#000', '.': '#fff', 'o':'#777' }[d[i][j]]
if (mx,my) in dead:
bg="#f00"
elif (mx,my) in old:
bg="#0f0"
except:
bg = "#00f"
t = d[i][j]
if t=='o': t='.'
if t in "@.":
if (mx,my) in map_mem:
if map_mem[mx,my] != t:
raise xxxxxx
else:
map_mem[mx,my] = t
html+='<td style="background-color: %s;width: 18px; height: 18px;">%c</td>'%(bg, d[i][j])
html+="</tr>"
html+="</table>"
w.value = html
import sys
progress = widgets.IntProgressWidget(value=0, max=1000)
progress.set_css("background", "black")
progress.set_css("width", "800px")
term = terminal.Terminal(24, 80)
X = Telnet("210.71.253.213", 8473)
r = X.read_until("..........")
term.write(r)
term.dump()
sleep(1)
def new_pos(cx,cy, d):
if d ==0:
return cx, cy-1
if d ==1:
return cx+1, cy
if d == 2:
return cx, cy+1
if d ==3:
return cx-1, cy
from collections import defaultdict
junction = set()
mem =defaultdict(int)
display(w)
display(progress)
display(w2)
direction = -1
ds = "ACBD"
rds = "BDAC"
stack =[]
old =set()
if 'dead' not in globals():
dead=set()
cx, cy = 0,0
IDLE = 0.05
LOOPS = int(500/IDLE)
UPDATE = int(25/IDLE)
for cnt in range(LOOPS):
sleep(IDLE)
r = X.read_very_eager()
term.write(r)
d = term.dump()
if cnt%3==0:
show_maze(d)
progress.value=int(cnt*1000./LOOPS)
nbhd = [d[3][4], d[4][5], d[5][4], d[4][3]]
while 1:
direction +=1
if direction >=4:
break
if nbhd[direction]=='.':
nx,ny = new_pos(cx,cy,direction)
if (nx,ny) not in old and (nx,ny) not in dead:
break
if direction == 4:
old.add((cx,cy))
dead.add((cx,cy))
if len(stack)==0:
show_maze2()
break
cx, cy, direction = stack.pop()
X.write("\x1b[%c"%rds[direction])
else:
stack.append((cx,cy,direction))
X.write("\x1b[%c"%ds[direction])
old.add((cx,cy))
cx,cy,direction=nx,ny,-1
if cnt%UPDATE==0:
show_maze2()
print "done"
done