bettercap 1.4.6 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
}
|