public
Description: ddtek defcon ctf quals 2009 - beware, there's cusses
Homepage:
Clone URL: git://github.com/bkerley/quals09.git
quals09 / trivia300 / mazer.rb
100644 143 lines (134 sloc) 3.575 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
require 'socket'
pass = "MAZE4J002PLAY"
sock = IO.popen('nc -i1 pwn2.ddtek.biz 11511', 'w+')
mazes = File.open('mazes.txt','a')
sock.puts pass
$stderr.puts sock.gets # password / good luck
$stderr.puts sock.gets # solutions
n = 0
200.times do
  $stderr.puts `figlet #{n}`
  n += 1
  maze = []
  start_row = nil
  finish_row = nil
  start_col = nil
  finish_col = nil
  loop do
    begin
      mazeline = sock.gets.chomp
      $stderr.puts mazeline
      start_row = maze.length if mazeline =~ /s/
      finish_row = maze.length if mazeline =~ /f/
      start_col = mazeline =~ /s/ if start_row == maze.length
      finish_col = mazeline =~ /f/ if finish_row == maze.length
      maze << mazeline
      break if mazeline =~ /^\#+$/ && maze.length > 1 # fence
    rescue NoMethodError
      next
    end
  end
  if start_col.nil?
    sock.puts
    next
  end
# $stderr.puts "s #{start_row} #{start_col}"
# $stderr.puts "f #{finish_row} #{finish_col}"
# $stderr.puts "#{maze[start_row][start_col].chr} -> #{maze[finish_row][finish_col].chr}"
 
  mazes.puts maze, ''
 
  def adjacency(row, col)
    [[row+1, col], [row, col+1], [row-1, col], [row, col-1]]
  end
 
  def pathable(maze, row, col)
    candidates = adjacency(row, col)
    visitable = candidates.select do |c|
      maze[c[0]][c[1]].chr == '.' ||
      maze[c[0]][c[1]].chr == 'f'
    end
    visitable.each do |c|
      maze[c[0]][c[1]] = '_' unless maze[c[0]][c[1]].chr == 'f'
  # $stderr.puts maze.join("\n"), ''
    end
    if visitable == []
      maze[row][col] = '!'
    end
    visitable
  end
 
  def finished(maze, pathables)
    pathables.detect do |c|
      maze[c[0]][c[1]].chr == 'f'
    end
  end
 
  finished = nil
  processing_queue = [[start_row, start_col, []]]
  begin
    loop do
      if processing_queue == []
        raise "FUCK UNSOLVABLES!!!"
      end
      current = processing_queue.shift
      row = current[0]
      col = current[1]
      path = current[2]
      new_path = path + [[row, col]]
      pathables = pathable(maze, row, col)
      # $stderr.puts maze.join("\n"), ''
      finished = finished(maze, pathables)
      if finished
        finished << (new_path + [[finish_row, finish_col]])
        break
      end
      queued_pathables = pathables.map{ |p| p << new_path }
      # $stderr.puts queued_pathables.inspect
      processing_queue += queued_pathables
    end
  rescue
    sock.puts
    next
  end
 
# $stderr.puts maze.join("\n")
# $stderr.puts finished[2].inspect
 
  def direction(prev, cur)
    dr = prev[0] - cur[0]
    dc = prev[1] - cur[1]
    case [dr, dc]
    when [1, 0]
      'n'
    when [-1, 0]
      's'
    when [0, 1]
      'w'
    when [0, -1]
      'e'
    else
      raise "FFFFFFFFFFFFFFFFUUUUUUUUUUUUUU"
    end
  end
 
  dirs = finished[2][1..-1].inject(['', finished[2][0]]) do |memo, cur|
    dir = memo[0]
    prev = memo[1]
  # $stderr.puts memo.inspect, cur.inspect
    dir << direction(prev, cur)
    [dir, cur]
  end
  $stderr.puts
  $stderr.puts dirs[0]
  sock.puts dirs[0]
# sleep 1
end
sleep 1
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions
$stderr.puts sock.gets # solutions