Module: BetterCap::Network

Defined in:
lib/bettercap/network/network.rb,
lib/bettercap/network/target.rb,
lib/bettercap/network/arp_reader.rb,
lib/bettercap/network/packet_queue.rb

Overview

Handles various network related tasks.

Defined Under Namespace

Classes: ArpReader, PacketQueue, Target

Class Method Summary collapse

Class Method Details

.get_alive_targets(ctx) ⇒ Object

Return a list of BetterCap::Target objects found on the network, given a BetterCap::Context ( ctx ) and a timeout in seconds for the operation.


66
67
68
69
70
71
72
73
74
# File 'lib/bettercap/network/network.rb', line 66

def get_alive_targets( ctx )
  if ctx.options.should_discover_hosts?
    start_agents( ctx )
  else
    Logger.debug 'Using current ARP cache.'
  end

  ArpReader.parse ctx
end

.get_gatewayObject

Return the current network gateway or nil.


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/bettercap/network/network.rb', line 32

def get_gateway
  nstat = Shell.execute('netstat -nr')

  Logger.debug "NETSTAT:\n#{nstat}"

  out = nstat.split(/\n/).select {|n| n =~ /UG/ }
  gw  = nil
  out.each do |line|
    if line.include?( Context.get.options.iface )
      tmp = line.split[1]
      if is_ip?(tmp)
        gw = tmp
        break
      end
    end
  end
  gw
end

.get_hw_address(iface, ip_address, attempts = 2) ⇒ Object

Return the hardware address associated with the specified ip_address using the iface network interface. The resolution will be performed for the specified number of attempts.


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
# File 'lib/bettercap/network/network.rb', line 90

def get_hw_address( iface, ip_address, attempts = 2 )
  hw_address = ArpReader.find_address( ip_address )

  if hw_address.nil?
    attempts.times do
      arp_pkt = PacketFu::ARPPacket.new

      arp_pkt.eth_saddr     = arp_pkt.arp_saddr_mac = iface[:eth_saddr]
      arp_pkt.eth_daddr     = 'ff:ff:ff:ff:ff:ff'
      arp_pkt.arp_daddr_mac = '00:00:00:00:00:00'
      arp_pkt.arp_saddr_ip  = iface[:ip_saddr]
      arp_pkt.arp_daddr_ip  = ip_address

      cap_thread = Thread.new do
        Context.get.packets.push(arp_pkt)

        target_mac = nil
        timeout = 0

        cap = PacketFu::Capture.new(
          iface: iface[:iface],
          start: true,
          filter: "arp src #{ip_address} and ether dst #{arp_pkt.eth_saddr}"
        )

        begin
          Logger.debug 'Attempting to get MAC from packet capture ...'
          target_mac = Timeout::timeout(0.5) { get_mac_from_capture(cap, ip_address) }
        rescue Timeout::Error
          timeout += 0.1
          retry if target_mac.nil? && timeout <= 5
        end

        target_mac
      end
      hw_address = cap_thread.value

      break unless hw_address.nil?
    end
  end

  hw_address
end

.get_ip_address(ctx, mac) ⇒ Object

Return the IP address associated with the mac hardware address using the given BetterCap::Context ( ctx ).


78
79
80
81
82
83
84
85
# File 'lib/bettercap/network/network.rb', line 78

def get_ip_address( ctx, mac )
  ip = ArpReader.find_mac( mac )
  if ip.nil?
    start_agents( ctx )
    ip = ArpReader.find_mac( mac )
  end
  ip
end

.get_local_ipsObject

Return a list of IP addresses associated to this device network interfaces.


52
53
54
55
56
57
58
59
60
61
62
# File 'lib/bettercap/network/network.rb', line 52

def get_local_ips
  ips = []

  Shell.ifconfig.split("\n").each do |line|
    if line =~ /inet [adr:]*([\d\.]+)/
      ips << $1
    end
  end

  ips
end

.is_ip?(ip) ⇒ Boolean

Return true if ip is a valid IP address, otherwise false.

Returns:

  • (Boolean)

19
20
21
22
23
24
# File 'lib/bettercap/network/network.rb', line 19

def is_ip?(ip)
  if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ ip.to_s
    return $~.captures.all? {|i| i.to_i < 256}
  end
  false
end

.is_mac?(mac) ⇒ Boolean

Return true if mac is a valid MAC address, otherwise false.

Returns:

  • (Boolean)

27
28
29
# File 'lib/bettercap/network/network.rb', line 27

def is_mac?(mac)
  ( /^[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}\:[a-f0-9]{1,2}$/i =~ mac.to_s )
end