Connecting via netcat gives us
Hi there! Stupid CAPTCHA: enter your name, user40319
Entering the username gives us a bunch of mazes in this format…
layer (1, y, z): = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
This repeats from layer 0 to 49 or so, and then we are asked to find a path from any coordinate in this maze to another coordinate. This looks like a typical Association for Computing Machinery contest question, so I quickly ran over to programming team member Antony Stabile, Progrmaming Diety for the solution. Here’s the main logic from it, it’s a BFS algorithm that finds the shortest path:
Scanner in = new Scanner(new FileReader(new File("map.txt"))); PrintWriter out = new PrintWriter(new FileWriter(new File("map.out"))); ArrayListinput = new ArrayList (); while(in.hasNext()) input.add(in.nextLine()); ySize = 1; while(input.get(ySize).charAt(0)=='=') ySize++; ySize--; xSize = (input.size()-1)/(ySize+1); zSize = (input.get(1).length())/2; boolean[][][] g = new boolean[xSize][ySize][zSize]; // true if blocked for(int i=0; i coords = new ArrayList (); String cur = ""; for(char c : input.get(input.size()-1).toCharArray()) { if(Character.isDigit(c)) cur = cur+c; else if(cur.length() > 0) { coords.add(Integer.parseInt(cur)); cur = ""; } } in.close(); int sx = coords.get(0), sy = coords.get(1), sz = coords.get(2); int ex = coords.get(3), ey = coords.get(4), ez = coords.get(5); int[] dx = {1,-1,0,0,0,0}, dy = {0,0,1,-1,0,0}, dz = {0,0,0,0,1,-1}; int[][][] dist = new int[xSize][ySize][zSize]; int oo = 987654321; for(int[][] x : dist) for(int[] y : x) Arrays.fill(y,oo); dist[ex][ey][ez] = 0; Queue q = new LinkedList (); q.add(ex); q.add(ey); q.add(ez); while(!q.isEmpty()) { int cx = q.poll(); int cy = q.poll(); int cz = q.poll(); for(int i=0; i = oo) { out.println("NO PATH FOUND"); out.close(); return; } while(ex != sx || ey != sy || ez != sz) { out.printf("(%d,%d,%d)",sx,sy,sz); for(int i=0; i
This is java, though, so I made my python script invoke his java class to solve the input. This gives us solutions in this format...
(45,0,5)(44,0,5)(43,0,5)(42,0,5)(41,0,5)(40,0,5)(39,0,5)(38,0,5)(37,0,5)(36,0,5)(35,0,5)(34,0,5)(33,0,5)(32,0,5)(31,0,5)(30,0,5)(29,0,5)(28,0,5)(27,0,5)(26,0,5)(25,0,5)(24,0,5)(24,1,5)(24,2,5)(24,3,5)(24,4,5)(24,5,5)(23,5,5)(23,6,5)(22,6,5)(21,6,5)(20,6,5)(19,6,5)(18,6,5)(17,6,5)(16,6,5)(16,7,5)(15,7,5)(15,8,5)(15,9,5)(14,9,5)(13,9,5)(12,9,5)(11,9,5)(11,10,5)(10,10,5)(9,10,5)(8,10,5)(7,10,5)(6,10,5)(6,10,6)(6,10,7)(7,10,7)(7,10,8)(8,10,8)(8,10,9)(9,10,9)(9,10,10)(10,10,10)(10,10,11)(11,10,11)(11,10,12)(11,11,12)(12,11,12)(12,12,12)(12,13,12)(12,13,13)(13,13,13)(13,13,14)(14,13,14)(14,14,14)(14,15,14)(14,16,14)(14,17,14)(14,18,14)(14,19,14)(14,20,14)(14,20,15)(15,20,15)(15,21,15)(15,22,15)(15,23,15)(15,23,16)(16,23,16)(16,23,17)(17,23,17)(17,23,18)(18,23,18)(18,23,19)(19,23,19)(19,23,20)(20,23,20)(20,23,21)(20,24,21)(20,25,21)(21,25,21)(21,25,22)(22,25,22)(22,25,23)(23,25,23)(23,25,24)(24,25,24)(24,25,25)(25,25,25)(25,25,26)(26,25,26)(26,25,27)(27,25,27)(27,25,28)(28,25,28)(28,25,29)(29,25,29)(29,25,30)(30,25,30)(30,26,30)(30,26,31)(31,26,31)(31,26,32)(32,26,32)(32,27,32)(32,28,32)(32,28,33)(33,28,33)(33,28,34)(34,28,34)(34,28,35)(35,28,35)(35,28,36)(36,28,36)(36,28,37)(37,28,37)(37,28,38)(38,28,38)(38,28,39)(39,28,39)(39,28,40)(40,28,40)(40,28,41)(41,28,41)(41,28,42)(42,28,42)(42,28,43)(43,28,43)(43,28,44)(43,28,45)(42,28,45)(42,29,45)(42,30,45)(42,31,45)(41,31,45)(41,32,45)(41,33,45)(41,34,45)(40,34,45)(39,34,45)(38,34,45)(37,34,45)(36,34,45)(35,34,45)(34,34,45)(33,34,45)(32,34,45)(31,34,45)(30,34,45)(29,34,45)(28,34,45)(27,34,45)(26,34,45)(25,34,45)(24,34,45)(23,34,45)(22,34,45)(21,34,45)(20,34,45)(20,35,45)(19,35,45)(18,35,45)(17,35,45)(17,36,45)(16,36,45)(15,36,45)(14,36,45)(13,36,45)(12,36,45)(11,36,45)(10,36,45)(9,36,45)(8,36,45)(7,36,45)(7,37,45)(7,38,45)(7,39,45)(6,39,45)(6,40,45)(6,41,45)(6,42,45)(6,43,45)(6,44,45)(6,45,45)(6,46,45)(6,47,45)(6,48,45)(6,49,45)
After solving a single maze, we noticed it sent us another, so we made our script loop until it stopped sending us mazes. After 16 solutions, it sent us something along the lines of
You win! Enjoy your key ;)
That' s telling us the key has already been sent to us. Using the ListPointPlot3D function of Wolfram Mathematica, Luis #1 plotted the shortest paths we generated and each of these gave us a character. The end result was "NOF3ARNO3XITHER3".
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
Here's the shoddy python I wrote to handle it:
import socket import re import os # Handle connection s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("ctf.phdays.com", 1165)) # We log everything to a file mapcount = 10 def logshit(stuff): tempf = open("map%d.txt" % (mapcount), 'a') tempf.write(stuff) # Dump the map to a text file and run the compiled java class from earlier.. def gomap(mapstr): f = open('map.txt', 'w') f.write(mapstr) f.close() print "running generatorn" os.system("java map") print "sending shortest pathn" shortestpath = open('map.out', 'r').read() print shortestpath + "n" s.sendall(shortestpath) # parse/log captcha data = s.recv(1024) captcha_str = repr(data) print 'Received:', captcha_str # get user id name_match = re.search(r'(d+)', captcha_str) print name_match # send captcha back sendback = 'user%sn' % name_match.group(0) print sendback s.sendall(sendback) # if we receive the chunk below, map is done being sent. end_regex = re.compile('Find a path between.+:') map_data = '' while 1: data = s.recv(1024) logshit(data) if not data: break map_data += data # got the last chunk of the map if end_regex.search(map_data): gomap(map_data) # run the solver map_data = '' # We wanted to see if it spawned a shell, it did not. s.sendall('ls') data = s.recv(1024) print 'data: ', data, 'n' logshit(data) print 'Connection closed.n' s.close()
Credits: Antony Stabile, Ditmar Wendt, Luis Sosa, Luis Santana