class PacketGen::Utils::ARPSpoofer

@note This class is provided for test purpose. Utility class to make ARP spoofing.

spoofer = PacketGen::Utils::ARPSpoofer.new
# start an ARP spoof: send forged ARP packets to target to spoof spoofed_ip
spoofer.start target_ip, spoofed_ip
# start another ARP spoof. Say to target2 spoofed_ip has given MAC address
spoofer.start target2_ip, spoofed_ip, mac: '00:00:00:00:00:01'
# stop spoofing on target2
spoofer.stop target2_ip
# stop all spoofings
spoofer.stop_all

@author Sylvain Daubert @since 2.1.3

Public Class Methods

new(timeout: nil, interval: 1.0, iface: nil) click to toggle source

@param [Integer,Float,nil] timeout spoof will happen for this amount

of time

@param [Integer,Float] interval time between 2 ARP packets @param [String,nil] iface network interface on which do spoofing.

Defaults to {PacketGen.default_iface}
# File lib/packetgen/utils/arp_spoofer.rb, line 29
def initialize(timeout: nil, interval: 1.0, iface: nil)
  @timeout = timeout
  @timeout = @timeout.to_f if @timeout
  @interval = interval
  @iface = iface || PacketGen.default_iface
  @targets = {}
  @arp_packets = {}
  @spoof_thread = nil
  @queue = Queue.new
end

Public Instance Methods

active?(target_ip) click to toggle source

Say if spoofing on given target is active or not @param [String] target_ip target IP address @return [Boolean,nil]

# File lib/packetgen/utils/arp_spoofer.rb, line 116
def active?(target_ip)
  return unless @targets.key?(target_ip)

  @targets[target_ip][:active]
end
active_targets() click to toggle source

Get active targets (registered with {#start}, or all after using {#start_all}) @return [Array<String>] list of target IP addresses

# File lib/packetgen/utils/arp_spoofer.rb, line 71
def active_targets
  @arp_packets.keys
end
add(target_ip, spoofed_ip, options={}) click to toggle source

Add a target to spoofer, without starting attack. Spoofing should be enabled with {#start_all}. @param [String] target_ip target IP address @param [String] spoofed_ip spoofed IP address @param [Hash] options @option options [String] :mac attacker's MAC address. Defaults to

local MAC address.

@option options [String] :target_mac target MAC address. If not given,

an ARP request is made to get it.

@return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 50
def add(target_ip, spoofed_ip, options={})
  @targets[target_ip] = options.merge(spoofed_ip: spoofed_ip, active: false)
end
registered_targets() click to toggle source

Get registered targets (all targets, registered with {#add} and {#start}) @return [Array<String>] list of target IP addresses

# File lib/packetgen/utils/arp_spoofer.rb, line 64
def registered_targets
  @targets.keys
end
remove(target_ip) click to toggle source

Remove target from spoofer. @param [String] target_ip target IP address @return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 57
def remove(target_ip)
  @targets.delete target_ip
  @arp_packets.delete target_ip
end
start(target_ip, spoofed_ip, options={}) click to toggle source

Start spoofing on given target @param [String] target_ip target IP address @param [String] spoofed_ip spoofed IP address @param [Hash] options @option options [String] :mac attacker's MAC address. Defaults to

local MAC address.

@option options [String] :target_mac target MAC address. If not given,

an ARP request is made to get it.

@return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 84
def start(target_ip, spoofed_ip, options={})
  add target_ip, spoofed_ip, options
  activate target_ip
end
start_all() click to toggle source

Start spoofing on all targets added with {#add}. @return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 99
def start_all
  @targets.each do |target_ip, _|
    activate target_ip
  end
end
stop(target_ip) click to toggle source

Stop spoofing on given target @param [String] target_ip target IP address @return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 92
def stop(target_ip)
  deactivate target_ip
  remove target_ip
end
stop_all() click to toggle source

Stop spoofing on all targets. @return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 107
def stop_all
  @targets.each do |target_ip, _|
    deactivate target_ip
  end
end
wait() click to toggle source

Wait for spoofing to finish. Wait forever if no timeout options was set on {#initialize}.

# File lib/packetgen/utils/arp_spoofer.rb, line 124
def wait
  @spoof_thread.join
end

Private Instance Methods

activate(target_ip) click to toggle source

Activate spoofing for given target @param [String] target_ip @return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 133
def activate(target_ip)
  @arp_packets[target_ip] = make_arp_packet(target_ip)
  @queue << @arp_packets.values
  create_spoof_thread unless @spoof_thread
  @targets[target_ip][:active] = true
end
create_spoof_thread() click to toggle source

Create spoof thread

# File lib/packetgen/utils/arp_spoofer.rb, line 141
def create_spoof_thread
  @spoof_thread = Thread.new(@queue, @timeout, @interval) do |queue, timeout, interval|
    while timeout.nil? || timeout > 0.0
      packets = queue.pop unless queue.empty?
      send_packets_on_wire(packets) unless packets.empty?
      timeout -= interval if timeout
      sleep interval
    end
  end
end
deactivate(target_ip) click to toggle source

Deactivate spoofing for given target @param [String] target_ip @return [void]

# File lib/packetgen/utils/arp_spoofer.rb, line 160
def deactivate(target_ip)
  @arp_packets.delete target_ip
  if @arp_packets.empty?
    @spoof_thread.kill
    @spoof_thread = nil
  else
    @queue << @arp_packets.values
  end
  @targets[target_ip][:active] = false
end
make_arp_packet(target_ip) click to toggle source

Create ARP packet to spoof given target @param [String] target_ip @return [Packet]

# File lib/packetgen/utils/arp_spoofer.rb, line 174
def make_arp_packet(target_ip)
  params = @targets[target_ip]
  mac = params[:mac] || Config.instance.hwaddr(@iface)

  target_mac = params[:target_mac] || Utils.arp(target_ip)

  Packet.gen('Eth', dst: target_mac, src: mac)
        .add('ARP', op: 'reply', sha: mac, spa: params[:spoofed_ip],
                    tha: target_mac, tpa: target_ip)
end
send_packets_on_wire(packets) click to toggle source

send packets on wire

# File lib/packetgen/utils/arp_spoofer.rb, line 153
def send_packets_on_wire(packets)
  packets.each { |pkt| pkt.to_w(@iface) }
end