bettercap 1.4.6 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bettercap +1 -1
- data/lib/bettercap.rb +1 -0
- data/lib/bettercap/context.rb +63 -70
- data/lib/bettercap/discovery/agents/base.rb +2 -2
- data/lib/bettercap/discovery/thread.rb +5 -4
- data/lib/bettercap/firewalls/base.rb +2 -4
- data/lib/bettercap/firewalls/{osx.rb → bsd.rb} +3 -3
- data/lib/bettercap/firewalls/linux.rb +2 -2
- data/lib/bettercap/firewalls/redirection.rb +5 -2
- data/lib/bettercap/logger.rb +6 -11
- data/lib/bettercap/memory.rb +56 -0
- data/lib/bettercap/monkey/em-proxy/proxy.rb +23 -0
- data/lib/bettercap/monkey/packetfu/pcap.rb +51 -0
- data/lib/bettercap/network/arp_reader.rb +2 -2
- data/lib/bettercap/network/network.rb +2 -2
- data/lib/bettercap/network/packet_queue.rb +2 -2
- data/lib/bettercap/network/protos/base.rb +8 -5
- data/lib/bettercap/network/protos/dhcp.rb +5 -124
- data/lib/bettercap/network/target.rb +7 -2
- data/lib/bettercap/options/core_options.rb +189 -0
- data/lib/bettercap/options/options.rb +167 -0
- data/lib/bettercap/options/proxy_options.rb +258 -0
- data/lib/bettercap/options/server_options.rb +71 -0
- data/lib/bettercap/options/sniff_options.rb +90 -0
- data/lib/bettercap/options/spoof_options.rb +71 -0
- data/lib/bettercap/proxy/{module.rb → http/module.rb} +8 -4
- data/lib/bettercap/proxy/{modules → http/modules}/injectcss.rb +2 -2
- data/lib/bettercap/proxy/{modules → http/modules}/injecthtml.rb +2 -2
- data/lib/bettercap/proxy/{modules → http/modules}/injectjs.rb +2 -2
- data/lib/bettercap/proxy/{proxy.rb → http/proxy.rb} +5 -2
- data/lib/bettercap/proxy/{request.rb → http/request.rb} +4 -0
- data/lib/bettercap/proxy/{response.rb → http/response.rb} +3 -0
- data/lib/bettercap/proxy/{ssl → http/ssl}/authority.rb +3 -1
- data/lib/bettercap/proxy/{ssl → http/ssl}/bettercap-ca.pem +0 -0
- data/lib/bettercap/proxy/{ssl → http/ssl}/server.rb +3 -1
- data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/cookiemonitor.rb +2 -0
- data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/lock.ico +0 -0
- data/lib/bettercap/proxy/{sslstrip → http/sslstrip}/strip.rb +4 -2
- data/lib/bettercap/proxy/{streamer.rb → http/streamer.rb} +7 -4
- data/lib/bettercap/proxy/stream_logger.rb +25 -9
- data/lib/bettercap/proxy/tcp/module.rb +75 -0
- data/lib/bettercap/proxy/tcp/proxy.rb +123 -0
- data/lib/bettercap/proxy/thread_pool.rb +1 -1
- data/lib/bettercap/sniffer/parsers/post.rb +1 -1
- data/lib/bettercap/sniffer/parsers/url.rb +1 -1
- data/lib/bettercap/sniffer/sniffer.rb +23 -17
- data/lib/bettercap/spoofers/arp.rb +21 -9
- data/lib/bettercap/spoofers/base.rb +12 -16
- data/lib/bettercap/spoofers/icmp.rb +4 -5
- data/lib/bettercap/spoofers/none.rb +0 -1
- data/lib/bettercap/version.rb +1 -1
- metadata +48 -19
- data/lib/bettercap/firewalls/openbsd.rb +0 -77
- data/lib/bettercap/options.rb +0 -600
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
|
4
|
+
BETTERCAP
|
5
|
+
|
6
|
+
Author : Simone 'evilsocket' Margaritelli
|
7
|
+
Email : evilsocket@gmail.com
|
8
|
+
Blog : http://www.evilsocket.net/
|
9
|
+
|
10
|
+
This project is released under the GPL 3 license.
|
11
|
+
|
12
|
+
=end
|
13
|
+
|
14
|
+
module BetterCap
|
15
|
+
module Proxy
|
16
|
+
module TCP
|
17
|
+
|
18
|
+
# Base class for transparent TCP proxy modules, example:
|
19
|
+
#
|
20
|
+
# class SampleModule < BetterCap::Proxy::TCP::Module
|
21
|
+
# def on_data( event )
|
22
|
+
# event.data = 'aaa'
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# def on_response( event )
|
26
|
+
# event.data = 'bbb'
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
class Module
|
30
|
+
# This callback is called when the target is sending data to the upstream server.
|
31
|
+
# +event+ is an instance of the BetterCap::Proxy::TCP::Event class.
|
32
|
+
def on_data( event ); end
|
33
|
+
# This callback is called when the upstream server is sending data to the target.
|
34
|
+
# +event+ is an instance of the BetterCap::Proxy::TCP::Event class.
|
35
|
+
def on_response( event ); end
|
36
|
+
# This callback is called when the connection is terminated.
|
37
|
+
# +event+ is an instance of the BetterCap::Proxy::TCP::Event class.
|
38
|
+
def on_finish( event ); end
|
39
|
+
|
40
|
+
# Loaded modules.
|
41
|
+
@@loaded = {}
|
42
|
+
|
43
|
+
class << self
|
44
|
+
# Called when a class inherits this base class.
|
45
|
+
def inherited(subclass)
|
46
|
+
name = subclass.name.upcase
|
47
|
+
@@loaded[name] = subclass
|
48
|
+
end
|
49
|
+
|
50
|
+
# Load +file+ as a proxy module.
|
51
|
+
def load( file )
|
52
|
+
begin
|
53
|
+
require file
|
54
|
+
rescue LoadError
|
55
|
+
raise BetterCap::Error, "Invalid TCP proxy module specified."
|
56
|
+
end
|
57
|
+
|
58
|
+
@@loaded.each do |name,mod|
|
59
|
+
@@loaded[name] = mod.new
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Execute method +even_name+ for each loaded module instance using +event+
|
64
|
+
# as its argument.
|
65
|
+
def dispatch( event_name, event )
|
66
|
+
@@loaded.each do |name,mod|
|
67
|
+
mod.send( event_name, event )
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
|
4
|
+
BETTERCAP
|
5
|
+
|
6
|
+
Author : Simone 'evilsocket' Margaritelli
|
7
|
+
Email : evilsocket@gmail.com
|
8
|
+
Blog : http://www.evilsocket.net/
|
9
|
+
|
10
|
+
This project is released under the GPL 3 license.
|
11
|
+
|
12
|
+
=end
|
13
|
+
|
14
|
+
module BetterCap
|
15
|
+
module Proxy
|
16
|
+
module TCP
|
17
|
+
|
18
|
+
# Class used to encapsulate ( and keep references ) of a single TCP event-.
|
19
|
+
# http://stackoverflow.com/questions/161510/pass-parameter-by-reference-in-ruby
|
20
|
+
class Event
|
21
|
+
# The source IP address of this event.
|
22
|
+
attr_accessor :ip
|
23
|
+
# Source port.
|
24
|
+
attr_accessor :port
|
25
|
+
# Reference to the buffer being transmitted.
|
26
|
+
attr_accessor :data
|
27
|
+
|
28
|
+
def initialize( ip, port, data = nil )
|
29
|
+
@ip = ip
|
30
|
+
@port = port
|
31
|
+
@data = data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Transparent TCP proxy class.
|
36
|
+
class Proxy
|
37
|
+
# Initialize the TCP proxy with given arguments.
|
38
|
+
def initialize( address, port, up_address, up_port )
|
39
|
+
@address = address
|
40
|
+
@port = port
|
41
|
+
@upstream_address = up_address
|
42
|
+
@upstream_port = up_port
|
43
|
+
@ctx = BetterCap::Context.get
|
44
|
+
@worker = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
# Start the proxy.
|
48
|
+
def start
|
49
|
+
Logger.info "[#{'TCP PROXY'.green}] Starting on #{@address}:#{@port} ( -> #{@upstream_address}:#{@upstream_port} ) ..."
|
50
|
+
@worker = Thread.new &method(:worker)
|
51
|
+
# If the upstream server is in this network, we need to make sure that its MAC
|
52
|
+
# address is discovered and put in the ARP cache before we even start the proxy,
|
53
|
+
# otherwise internal connections won't be spoofed and the proxy will be useless
|
54
|
+
# until some random event will fill the ARP cache for the server.
|
55
|
+
if @ctx.ifconfig[:ip4_obj].include?( @upstream_address )
|
56
|
+
Logger.debug "[#{'TCP PROXY'.green}] Sending probe to upstream server address ..."
|
57
|
+
BetterCap::Network.get_hw_address( @ctx, @upstream_address )
|
58
|
+
# wait for the system to acknowledge the ARP cache changes.
|
59
|
+
sleep( 1 )
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Stop the proxy.
|
64
|
+
def stop
|
65
|
+
Logger.info "Stopping TCP proxy ..."
|
66
|
+
::Proxy.stop
|
67
|
+
@worker.join
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def worker
|
73
|
+
begin
|
74
|
+
up_addr = @upstream_address
|
75
|
+
up_port = @upstream_port
|
76
|
+
up_svc = BetterCap::StreamLogger.service( :tcp, @upstream_port )
|
77
|
+
|
78
|
+
::Proxy.start(:host => @address, :port => @port) do |conn|
|
79
|
+
conn.server :srv, :host => up_addr, :port => up_port
|
80
|
+
|
81
|
+
# ip -> upstream
|
82
|
+
conn.on_data do |data|
|
83
|
+
ip, port = peer
|
84
|
+
event = Event.new( ip, port, data )
|
85
|
+
|
86
|
+
Logger.info "[#{'TCP PROXY'.green}] #{ip} #{'->'.green} #{'upstream'.yellow}:#{up_svc} ( #{event.data.bytesize} bytes )"
|
87
|
+
|
88
|
+
Module.dispatch( 'on_data', event )
|
89
|
+
event.data
|
90
|
+
end
|
91
|
+
|
92
|
+
# upstream -> ip
|
93
|
+
conn.on_response do |backend, resp|
|
94
|
+
ip, port = peer
|
95
|
+
event = Event.new( ip, port, resp )
|
96
|
+
|
97
|
+
Logger.info "[#{'TCP PROXY'.green}] #{'upstream'.yellow}:#{up_svc} #{'->'.green} #{ip} ( #{event.data.bytesize} bytes )"
|
98
|
+
|
99
|
+
Module.dispatch( 'on_response', event )
|
100
|
+
event.data
|
101
|
+
end
|
102
|
+
|
103
|
+
# termination
|
104
|
+
conn.on_finish do |backend, name|
|
105
|
+
ip, port = peer
|
106
|
+
event = Event.new( ip, port )
|
107
|
+
|
108
|
+
Logger.info "[#{'TCP PROXY'.green}] #{ip} <- #{'closed'.red} -> #{'upstream'.yellow}:#{up_svc}"
|
109
|
+
|
110
|
+
Module.dispatch( 'on_finish', event )
|
111
|
+
unbind
|
112
|
+
end
|
113
|
+
end
|
114
|
+
rescue Exception => e
|
115
|
+
Logger.error e.message
|
116
|
+
Logger.exception e
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -19,7 +19,7 @@ class Post < Base
|
|
19
19
|
s = pkt.to_s
|
20
20
|
if s =~ /POST\s+[^\s]+\s+HTTP.+/
|
21
21
|
begin
|
22
|
-
req = BetterCap::Proxy::Request.parse(pkt.payload)
|
22
|
+
req = BetterCap::Proxy::HTTP::Request.parse(pkt.payload)
|
23
23
|
# the packet could be incomplete
|
24
24
|
unless req.body.nil? or req.body.empty?
|
25
25
|
StreamLogger.log_raw( pkt, "POST", req.to_url(1000) )
|
@@ -20,7 +20,7 @@ class Url < Base
|
|
20
20
|
if s =~ /GET\s+([^\s]+)\s+HTTP.+Host:\s+([^\s]+).+/m
|
21
21
|
host = $2
|
22
22
|
url = $1
|
23
|
-
|
23
|
+
unless url =~ /.+\.(png|jpg|jpeg|bmp|gif|img|ttf|woff|css|js).*/i
|
24
24
|
StreamLogger.log_raw( pkt, 'GET', "http://#{host}#{url}" )
|
25
25
|
end
|
26
26
|
end
|
@@ -31,7 +31,7 @@ class Sniffer
|
|
31
31
|
|
32
32
|
setup( ctx )
|
33
33
|
|
34
|
-
start = Time.now
|
34
|
+
start = Time.now
|
35
35
|
skipped = 0
|
36
36
|
processed = 0
|
37
37
|
|
@@ -52,11 +52,11 @@ class Sniffer
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
stop = Time.now
|
56
|
-
delta = stop - start
|
55
|
+
stop = Time.now
|
56
|
+
delta = ( stop - start ) * 1000.0
|
57
57
|
total = skipped + processed
|
58
58
|
|
59
|
-
Logger.info "[#{'SNIFFER'.green}] #{total} packets processed in #{delta}
|
59
|
+
Logger.info "[#{'SNIFFER'.green}] #{total} packets processed in #{delta} ms ( #{skipped} skipped packets, #{processed} processed packets )"
|
60
60
|
}
|
61
61
|
end
|
62
62
|
|
@@ -64,13 +64,19 @@ class Sniffer
|
|
64
64
|
|
65
65
|
# Return the current PCAP stream.
|
66
66
|
def self.stream
|
67
|
-
if @@ctx.options.
|
68
|
-
@@cap.stream
|
67
|
+
if @@ctx.options.sniff.src.nil?
|
68
|
+
return @@cap.stream
|
69
69
|
else
|
70
|
-
Logger.info "[#{'SNIFFER'.green}] Reading packets from #{@@ctx.options.
|
70
|
+
Logger.info "[#{'SNIFFER'.green}] Reading packets from #{@@ctx.options.sniff.src} ..."
|
71
71
|
|
72
|
-
|
72
|
+
begin
|
73
|
+
return PacketFu::PcapFile.file_to_array @@ctx.options.sniff.src
|
74
|
+
rescue Exception => e
|
75
|
+
Logger.error "Error while parsing #{@@ctx.options.sniff.src}: #{e.message}"
|
76
|
+
Logger.exception e
|
77
|
+
end
|
73
78
|
end
|
79
|
+
return []
|
74
80
|
end
|
75
81
|
|
76
82
|
# Return true if the +pkt+ packet instance must be skipped.
|
@@ -81,7 +87,7 @@ class Sniffer
|
|
81
87
|
# not IP packet
|
82
88
|
return true unless pkt.is_ip?
|
83
89
|
# skip if local packet and --local|-L was not specified.
|
84
|
-
unless @@ctx.options.local
|
90
|
+
unless @@ctx.options.sniff.local
|
85
91
|
return ( pkt.ip_saddr == @@ctx.ifconfig[:ip_saddr] or pkt.ip_daddr == @@ctx.ifconfig[:ip_saddr] )
|
86
92
|
end
|
87
93
|
rescue; end
|
@@ -103,7 +109,7 @@ class Sniffer
|
|
103
109
|
def self.append_packet( p )
|
104
110
|
begin
|
105
111
|
@@pcap.array_to_file(
|
106
|
-
filename: @@ctx.options.
|
112
|
+
filename: @@ctx.options.sniff.output,
|
107
113
|
array: [p],
|
108
114
|
append: true ) unless @@pcap.nil?
|
109
115
|
rescue Exception => e
|
@@ -115,20 +121,20 @@ class Sniffer
|
|
115
121
|
def self.setup( ctx )
|
116
122
|
@@ctx = ctx
|
117
123
|
|
118
|
-
unless @@ctx.options.
|
124
|
+
unless @@ctx.options.sniff.output.nil?
|
119
125
|
@@pcap = PacketFu::PcapFile.new
|
120
|
-
Logger.info "[#{'SNIFFER'.green}] Saving packets to #{@@ctx.options.
|
126
|
+
Logger.info "[#{'SNIFFER'.green}] Saving packets to #{@@ctx.options.sniff.output} ."
|
121
127
|
end
|
122
128
|
|
123
|
-
if @@ctx.options.custom_parser.nil?
|
124
|
-
@@parsers = Parsers::Base.load_by_names @@ctx.options.parsers
|
129
|
+
if @@ctx.options.sniff.custom_parser.nil?
|
130
|
+
@@parsers = Parsers::Base.load_by_names @@ctx.options.sniff.parsers
|
125
131
|
else
|
126
|
-
@@parsers = Parsers::Base.load_custom @@ctx.options.custom_parser
|
132
|
+
@@parsers = Parsers::Base.load_custom @@ctx.options.sniff.custom_parser
|
127
133
|
end
|
128
134
|
|
129
135
|
@@cap = Capture.new(
|
130
|
-
iface: @@ctx.options.iface,
|
131
|
-
filter: @@ctx.options.
|
136
|
+
iface: @@ctx.options.core.iface,
|
137
|
+
filter: @@ctx.options.sniff.filter,
|
132
138
|
start: true
|
133
139
|
)
|
134
140
|
end
|
@@ -18,7 +18,6 @@ class Arp < Base
|
|
18
18
|
# Initialize the BetterCap::Spoofers::Arp object.
|
19
19
|
def initialize
|
20
20
|
@ctx = Context.get
|
21
|
-
@gateway = nil
|
22
21
|
@forwarding = @ctx.firewall.forwarding_enabled?
|
23
22
|
@spoof_thread = nil
|
24
23
|
@sniff_thread = nil
|
@@ -46,12 +45,12 @@ class Arp < Base
|
|
46
45
|
|
47
46
|
# Start the ARP spoofing.
|
48
47
|
def start
|
49
|
-
Logger.debug "Starting ARP spoofer ( #{@ctx.options.half_duplex ? 'Half' : 'Full'} Duplex ) ..."
|
48
|
+
Logger.debug "Starting ARP spoofer ( #{@ctx.options.spoof.half_duplex ? 'Half' : 'Full'} Duplex ) ..."
|
50
49
|
|
51
50
|
stop() if @running
|
52
51
|
@running = true
|
53
52
|
|
54
|
-
if @ctx.options.kill
|
53
|
+
if @ctx.options.spoof.kill
|
55
54
|
Logger.warn "Disabling packet forwarding."
|
56
55
|
@ctx.firewall.enable_forwarding(false) if @forwarding
|
57
56
|
else
|
@@ -77,7 +76,7 @@ class Arp < Base
|
|
77
76
|
Logger.debug "Restoring ARP table of #{@ctx.targets.size} targets ..."
|
78
77
|
|
79
78
|
@ctx.targets.each do |target|
|
80
|
-
|
79
|
+
if target.spoofable?
|
81
80
|
5.times do
|
82
81
|
spoof(target, true)
|
83
82
|
sleep 0.3
|
@@ -96,18 +95,31 @@ class Arp < Base
|
|
96
95
|
# restore its ARP cache instead.
|
97
96
|
def spoof( target, restore = false )
|
98
97
|
if restore
|
99
|
-
send_spoofed_packet( @gateway.ip, @gateway.mac, target.ip, 'ff:ff:ff:ff:ff:ff' )
|
100
|
-
send_spoofed_packet( target.ip, target.mac, @gateway.ip, 'ff:ff:ff:ff:ff:ff' ) unless @ctx.options.half_duplex
|
98
|
+
send_spoofed_packet( @ctx.gateway.ip, @ctx.gateway.mac, target.ip, 'ff:ff:ff:ff:ff:ff' )
|
99
|
+
send_spoofed_packet( target.ip, target.mac, @ctx.gateway.ip, 'ff:ff:ff:ff:ff:ff' ) unless @ctx.options.spoof.half_duplex
|
100
|
+
@ctx.targets.each do |e|
|
101
|
+
if e.spoofable? and e.ip != target.ip and e.ip != @ctx.gateway.ip
|
102
|
+
send_spoofed_packet( e.ip, e.mac, target.ip, 'ff:ff:ff:ff:ff:ff' )
|
103
|
+
end
|
104
|
+
end
|
101
105
|
else
|
102
|
-
|
103
|
-
send_spoofed_packet(
|
106
|
+
# tell the target we're the gateway
|
107
|
+
send_spoofed_packet( @ctx.gateway.ip, @ctx.ifconfig[:eth_saddr], target.ip, target.mac )
|
108
|
+
# tell the gateway we're the target
|
109
|
+
send_spoofed_packet( target.ip, @ctx.ifconfig[:eth_saddr], @ctx.gateway.ip, @ctx.gateway.mac ) unless @ctx.options.spoof.half_duplex
|
110
|
+
# tell the target we're everybody else in the network :D
|
111
|
+
@ctx.targets.each do |e|
|
112
|
+
if e.spoofable? and e.ip != target.ip and e.ip != @ctx.gateway.ip
|
113
|
+
send_spoofed_packet( e.ip, @ctx.ifconfig[:eth_saddr], target.ip, target.mac )
|
114
|
+
end
|
115
|
+
end
|
104
116
|
end
|
105
117
|
end
|
106
118
|
|
107
119
|
# Main spoofer loop.
|
108
120
|
def arp_spoofer
|
109
121
|
spoof_loop(1) { |target|
|
110
|
-
|
122
|
+
if target.spoofable?
|
111
123
|
spoof(target)
|
112
124
|
end
|
113
125
|
}
|
@@ -57,7 +57,7 @@ private
|
|
57
57
|
def sniff_packets( filter )
|
58
58
|
begin
|
59
59
|
@capture = PacketFu::Capture.new(
|
60
|
-
iface: @ctx.options.iface,
|
60
|
+
iface: @ctx.options.core.iface,
|
61
61
|
filter: filter,
|
62
62
|
start: true
|
63
63
|
)
|
@@ -67,10 +67,10 @@ private
|
|
67
67
|
|
68
68
|
@capture.stream.each do |p|
|
69
69
|
begin
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
unless @running
|
71
|
+
Logger.debug 'Stopping thread ...'
|
72
|
+
Thread.exit
|
73
|
+
break
|
74
74
|
end
|
75
75
|
|
76
76
|
pkt = PacketFu::Packet.parse p rescue nil
|
@@ -92,7 +92,7 @@ private
|
|
92
92
|
break
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
Logger.debug "Spoofing #{@ctx.targets.size} targets ..."
|
96
96
|
|
97
97
|
update_targets!
|
98
98
|
|
@@ -106,17 +106,13 @@ private
|
|
106
106
|
|
107
107
|
# Get the MAC address of the gateway and update it.
|
108
108
|
def update_gateway!
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
# notify the system that the gateway mac is resolved, this will prevent
|
116
|
-
# the gateway ip to be unnecessarily probed from discovery agents.
|
117
|
-
@ctx.gateway_mac_resolved = !hw.nil?
|
109
|
+
unless @ctx.gateway.spoofable?
|
110
|
+
hw = Network.get_hw_address( @ctx, @ctx.gateway.ip )
|
111
|
+
raise BetterCap::Error, "Couldn't determine router MAC" if ( @ctx.options.need_gateway? and hw.nil? )
|
112
|
+
@ctx.gateway.mac = hw unless hw.nil?
|
113
|
+
end
|
118
114
|
|
119
|
-
Logger.info "[#{'GATEWAY'.green}] #{@gateway.to_s(false)}"
|
115
|
+
Logger.info "[#{'GATEWAY'.green}] #{@ctx.gateway.to_s(false)}"
|
120
116
|
end
|
121
117
|
|
122
118
|
# Update each target that needs to be updated.
|
@@ -79,7 +79,6 @@ class Icmp < Base
|
|
79
79
|
def initialize
|
80
80
|
@ctx = Context.get
|
81
81
|
@forwarding = @ctx.firewall.forwarding_enabled?
|
82
|
-
@gateway = nil
|
83
82
|
@local = @ctx.ifconfig[:ip_saddr]
|
84
83
|
@spoof_thread = nil
|
85
84
|
@watch_thread = nil
|
@@ -93,12 +92,12 @@ class Icmp < Base
|
|
93
92
|
# Send ICMP redirect to the +target+, redirecting the gateway ip and
|
94
93
|
# everything in the @entries list of addresses to us.
|
95
94
|
def send_spoofed_packet( target )
|
96
|
-
( [@gateway.ip] + @entries ).each do |address|
|
95
|
+
( [@ctx.gateway.ip] + @entries ).each do |address|
|
97
96
|
begin
|
98
97
|
Logger.debug "Sending ICMP Redirect to #{target.to_s_compact} redirecting #{address} to us ..."
|
99
98
|
|
100
99
|
pkt = ICMPRedirectPacket.new
|
101
|
-
pkt.update!( @gateway, target, @local, address )
|
100
|
+
pkt.update!( @ctx.gateway, target, @local, address )
|
102
101
|
@ctx.packets.push(pkt)
|
103
102
|
rescue Exception => e
|
104
103
|
Logger.debug "#{self.class.name} : #{e.message}"
|
@@ -113,7 +112,7 @@ class Icmp < Base
|
|
113
112
|
stop() if @running
|
114
113
|
@running = true
|
115
114
|
|
116
|
-
if @ctx.options.kill
|
115
|
+
if @ctx.options.spoof.kill
|
117
116
|
Logger.warn "Disabling packet forwarding."
|
118
117
|
@ctx.firewall.enable_forwarding(false) if @forwarding
|
119
118
|
else
|
@@ -194,7 +193,7 @@ class Icmp < Base
|
|
194
193
|
# Main spoofer loop.
|
195
194
|
def icmp_spoofer
|
196
195
|
spoof_loop(3) { |target|
|
197
|
-
|
196
|
+
if target.spoofable?
|
198
197
|
send_spoofed_packet target
|
199
198
|
end
|
200
199
|
}
|