Class: BetterCap::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/bettercap/context.rb

Overview

methods to manipulate the program behaviour.

Constant Summary collapse

@@instance =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeContext

Initialize the global context object.



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

def initialize
  begin
    iface = PCAPRUB::Pcap.lookupdev
  rescue Exception => e
    iface = nil
    Logger.exception e
  end

  @running      = true
  @timeout      = 5
  @options      = Options.new iface
  @discovery    = Discovery::Thread.new self
  @firewall     = Firewalls::Base.get
  @iface        = nil
  @original_mac = nil
  @gateway      = nil
  @targets      = []
  @spoofer      = nil
  @httpd        = nil
  @dnsd         = nil
  @proxies      = []
  @redirections = []
  @packets      = nil
  @endpoints    = []
end

Instance Attribute Details

#discoveryObject

Instance of BetterCap::Discovery::Thread class.



29
30
31
# File 'lib/bettercap/context.rb', line 29

def discovery
  @discovery
end

#dnsdObject

Instance of BetterCap::Network::Servers::DNSD class.



35
36
37
# File 'lib/bettercap/context.rb', line 35

def dnsd
  @dnsd
end

#endpointsObject (readonly)

Precomputed list of possible addresses on the current network.



44
45
46
# File 'lib/bettercap/context.rb', line 44

def endpoints
  @endpoints
end

#firewallObject

Instance of the current BetterCap::Firewalls class.



21
22
23
# File 'lib/bettercap/context.rb', line 21

def firewall
  @firewall
end

#gatewayObject

Network gateway ( as an instance of BetterCap::Network::Target ).



25
26
27
# File 'lib/bettercap/context.rb', line 25

def gateway
  @gateway
end

#httpdObject

Instance of BetterCap::Network::Servers::HTTPD class.



33
34
35
# File 'lib/bettercap/context.rb', line 33

def httpd
  @httpd
end

#ifaceObject

Local interface ( as an instance of BetterCap::Network::Target ).



23
24
25
# File 'lib/bettercap/context.rb', line 23

def iface
  @iface
end

#optionsObject

Instance of BetterCap::Options class.



19
20
21
# File 'lib/bettercap/context.rb', line 19

def options
  @options
end

#packetsObject (readonly)

Instance of BetterCap::PacketQueue.



42
43
44
# File 'lib/bettercap/context.rb', line 42

def packets
  @packets
end

#runningObject

Set to true if the program is running, to false if a shutdown was scheduled by the user which pressed CTRL+C



38
39
40
# File 'lib/bettercap/context.rb', line 38

def running
  @running
end

#spooferObject

A list of BetterCap::Spoofers class instances.



31
32
33
# File 'lib/bettercap/context.rb', line 31

def spoofer
  @spoofer
end

#targetsObject

A list of BetterCap::Target objects which is periodically updated.



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

def targets
  @targets
end

#timeoutObject (readonly)

Timeout for discovery operations.



40
41
42
# File 'lib/bettercap/context.rb', line 40

def timeout
  @timeout
end

Class Method Details

.getObject

Return the global instance of the program Context, if the instance was not yet created it will be initialized and returned.



50
51
52
# File 'lib/bettercap/context.rb', line 50

def self.get
  @@instance ||= self.new
end

Instance Method Details

#finalizeObject

Stop every running daemon that was started and reset system state.



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/bettercap/context.rb', line 197

def finalize
  @running = false

  # Logger is silent if @running == false
  puts "\nShutting down, hang on ...\n"

  Logger.debug 'Stopping target discovery manager ...'
  @discovery.stop

  Logger.debug 'Stopping spoofers ...'
  @spoofer.each do |spoofer|
    spoofer.stop
  end

  # Spoofer might be sending some last packets to restore the targets,
  # the packet queue must be stopped here.
  @packets.stop

  Logger.debug 'Stopping proxies ...'
  @proxies.each do |proxy|
    proxy.stop
  end

  Logger.debug 'Disabling port redirections ...'
  @redirections.each do |r|
    @firewall.del_port_redirection( r, @options.core.use_ipv6 )
  end

  Logger.debug 'Restoring firewall state ...'
  @firewall.restore

  @dnsd.stop unless @dnsd.nil?
  @httpd.stop unless @httpd.nil?

  Shell.ifconfig( "#{@options.core.iface} ether #{@original_mac}") unless @original_mac.nil?
end

#find_target(ip, mac) ⇒ Object

Find a target given its ip and mac addresses inside the #targets list, if not found return nil.



156
157
158
159
160
161
162
163
# File 'lib/bettercap/context.rb', line 156

def find_target ip, mac
  @targets.each do |target|
    if target.equals?(ip,mac)
      return target
    end
  end
  nil
end

#start!Object

Start everything!



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/bettercap/context.rb', line 166

def start!
  # Start targets auto discovery.
  @discovery.start

  # Start network spoofers if any.
  @spoofer.each do |spoofer|
    spoofer.start
  end

  # Start proxies and setup port redirection.
  if @options.proxies.any?
    if ( @options.proxies.proxy or @options.proxies.proxy_https ) and @options.sniff.enabled?('URL')
      BetterCap::Logger.warn "WARNING: Both HTTP transparent proxy and URL parser are enabled, you're gonna see duplicated logs."
    end
    create_proxies!
  end

  enable_port_redirection!

  create_servers!

  # Start network sniffer.
  if @options.sniff.enabled?
    Sniffer.start self
  elsif @options.spoof.enabled? and !@options.proxies.any?
    Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this '\
                'will cause the MITM to run but no data to be collected.'
  end
end

#update!Object

Update the Context state parsing network related informations.

Raises:



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
144
145
146
147
148
149
150
151
152
# File 'lib/bettercap/context.rb', line 82

def update!
  unless @options.core.use_mac.nil?
    cfg = PacketFu::Utils.ifconfig @options.core.iface
    raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.core.iface}', make sure this interface "\
                            'is active and connected.' if cfg[:ip4_obj].nil?

    @original_mac = Network::Target.normalized_mac(cfg[:eth_saddr])

    Logger.info "Changing interface MAC address to #{@options.core.use_mac}"

    Shell.change_mac( @options.core.iface, @options.core.use_mac )
  end

  cfg = PacketFu::Utils.ifconfig @options.core.iface
  raise BetterCap::Error, "Could not determine IPv4 address of '#{@options.core.iface}', make sure this interface "\
                          'is active and connected.' if ( cfg[:ip4_obj].nil? and cfg[:ip6_saddr].nil? )

  # check if we're on an IPv6 interface
  if @options.core.use_ipv6 
    @iface = Network::Target.new( cfg[:ip6_saddr], cfg[:eth_saddr], cfg[:ip6_obj], cfg[:iface] )
  else
    @iface = Network::Target.new( cfg[:ip_saddr], cfg[:eth_saddr], cfg[:ip4_obj], cfg[:iface] )
  end

  raise BetterCap::Error, "Could not determine MAC address of '#{@options.core.iface}', make sure this interface "\
                          'is active and connected.' unless Network::Validator::is_mac?(@iface.mac)

  if @options.core.use_ipv6
    gw = @options.core.gateway || Network.get_ipv6_gateway
    raise BetterCap::Error, "Could not detect the gateway address for interface #{@options.core.iface}, "\
                            'make sure you\'ve specified the correct network interface to use and to have the '\
                            'correct network configuration, this could also happen if bettercap '\
                            'is launched from a virtual environment.' unless Network::Validator.is_ipv6?(gw)

  else
    gw = @options.core.gateway || Network.get_gateway
    raise BetterCap::Error, "Could not detect the gateway address for interface #{@options.core.iface}, "\
                            'make sure you\'ve specified the correct network interface to use and to have the '\
                            'correct network configuration, this could also happen if bettercap '\
                            'is launched from a virtual environment.' unless Network::Validator.is_ip?(gw)
  end

  @gateway = Network::Target.new gw
  Logger.info "[#{@iface.name.green}] #{@iface.to_s(false)}"

  Logger.debug '----- NETWORK INFORMATIONS -----'
  Logger.debug "  network  = #{@iface.network} ( #{@iface.network.to_range.to_s.split('..').join( ' -> ')} )"
  Logger.debug "  gateway  = #{@gateway.ip}"
  Logger.debug "  local_ip = #{@iface.ip}"
  Logger.debug "--------------------------------\n"

  @targets = @options.core.targets unless @options.core.targets.nil?
  @packets = Network::PacketQueue.new( @iface.name, @options.core.packet_throttle, 4 )
  # Spoofers need the context network data to be initialized.
  @spoofer = @options.spoof.parse_spoofers(self)

  if @options.core.discovery?
    tstart = Time.now
    Logger.info "[#{'DISCOVERY'.green}] Precomputing list of possible endpoints, this could take a while depending on your subnet ..."
    net = ip = @iface.network
    # loop each ip in our subnet and push it to the queue
    while net.include?ip
      if ip != @gateway.ip and ip != @iface.ip
        @endpoints << ip
      end
      ip = ip.succ
    end
    tend = Time.now
    Logger.info "[#{'DISCOVERY'.green}] Done in #{'%.01f' % ((tend - tstart) * 1000.0)} ms"
  end
end