Module: Baffle

Defined in:
lib/baffle.rb,
lib/baffle/gui.rb,
lib/baffle/util.rb,
lib/baffle/probe.rb,
lib/baffle/options.rb,
lib/baffle/fingerprint_diagram.rb

Defined Under Namespace

Modules: Probes Classes: Gui, Options, Probe

Constant Summary collapse

WIDTH =
24
HEIGHT =
24

Class Method Summary collapse

Class Method Details

.emit(options, injection_proc, injection_values) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/baffle/util.rb', line 6

def self.emit(options, injection_proc, injection_values)
  @device = Lorcon::Device.new(options.inject, options.driver)
  @device.fmode      = "INJMON"
  @device.channel    = options.channel
  
  injection_values << [nil] if injection_values.empty?

  injection_values.each do |args|
    packet = injection_proc.call(options, *args)
    yield packet if block_given?
    send_p(packet.data)
    sleep 0.05
  end
end

.fingerprint_diagram(vector) ⇒ Object



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
# File 'lib/baffle/fingerprint_diagram.rb', line 9

def self.fingerprint_diagram(vector)
  doc = Document.new '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
  svg = doc.add_element "svg", "width" => "100%", "viewbox" => "0 0 100 100", "version" => "1.1", "xmlns" => "http://www.w3.org/2000/svg"
  
  max_count = 0
  
  x = 0
  
  max_count = vector.max
  
  total_width = 32 * WIDTH *  1.05
  
  vector.each_with_index do |respond_count, flags_value|
    alpha = (respond_count / max_count.to_f) ** 3 + 0.1
    width = (WIDTH * alpha + 1) / total_width * 600.0
    
    alpha = 1 if alpha.nan?
    width = WIDTH if width.nan?
    
    alpha = (respond_count > 1 ? 1 : 0.05)
    width = 3
    
    ("%08d" %flags_value.to_s(2)).split(//).each_with_index do |c, i|
      y = 1 + i * (HEIGHT + 1)
      color = (c == "0") ? "black" : "red"
      
      svg.add_element "rect", "x" => x - (width / 2), "y" => y, "width" => width, "height" => HEIGHT, "style" => "fill:#{color};fill-opacity:#{alpha}"
    end
    
    x += total_width / 256
  end
  
  svg
end

.run(args) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/baffle.rb', line 10

def self.run(args)
  options = Baffle::Options.parse(args)
  
  options
  
  if options.gui?
    require File.expand_path(File.join(File.dirname(__FILE__), 'baffle', 'gui'))
    
    Gui.run(options)
  else
    scan(options)
  end
end

.scan(options) ⇒ Object



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
# File 'lib/baffle.rb', line 24

def self.scan(options)
  hypotheses = {}
  
  Baffle::Probes.each do |probe|
    puts "Running probe #{probe.name}"
    vector = probe.run(options)
    
    unless vector
      warn "Probe was skipped."
      next
    end
    
    if options.fpdiagram
      File.open("#{options.fpdiagram}#{probe.name}.svg", 'w+') do |f|
        f << Baffle.fingerprint_diagram(vector).to_s
      end
    end
    
    puts "Vector: #{vector.inspect}"
    
    unless options.train?
      hypotheses[probe.name] = probe.hypothesize(vector)
      puts "#{probe.name} hypothesizes: #{hypotheses[probe.name]}"
    end
  end
  
  hypotheses
end

.send_p(packet) ⇒ Object



21
22
23
# File 'lib/baffle/util.rb', line 21

def self.send_p(packet)
  @device.write(packet, 1, 0)
end

.sniff(*params) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/baffle/util.rb', line 25

def self.sniff(*params)
  Capture.open(*params) do |capture|
    capture.each do |packet|
      packet = packet[0..-5]
      packet = Dot11::Radiotap.new(packet)
      packet = packet.payload

      yield packet        
    end
  end
end