# 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 ="" for i in range(-44,45): html+="" for j in range(-44,45): mx,my = j, i bg = {'@': '#000', '.': '#fff', '':'#0f7' }[map_mem.get((mx,my), '')] html+=''%(bg, ' ') html+="" html+="
%c
" w2.value = html def show_maze(d): html ="" for i in range(9): html+="" 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+=''%(bg, d[i][j]) html+="" html+="
%c
" 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"