bettercap 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0302105b4b7c6f181542e22fff7662fa6b4b922b
4
- data.tar.gz: b46e666f283922dbe0bdb09fd6f2883dee7d89b2
3
+ metadata.gz: 724a91086ccfab829ec09e9ad381a9025dfd8380
4
+ data.tar.gz: 59292cebacc9ed01bb85d2ce3ac5a63151fd58fc
5
5
  SHA512:
6
- metadata.gz: ef42d62d1d051931e7b2ea84d56e09498e630628a1293bd3be5fc7a23d5457b57a2470896431171638bd59981ec0736a85847b359f592ca991ba378301831a34
7
- data.tar.gz: ca6291a117033ab2139a616a7e8734fbf0bc5b05b57e25299b222bfceed8bcbc9785b148a988c4c059cfd4079d79b7f24d1cdfd76a439ce3c3b35f42d0c4a6d8
6
+ metadata.gz: 7eb4990aeac1e69a85b87ea3dcd6e09f29701efc6932668919e5ecf1ba2de0a3d2c8da97b33350a7246947eef0adf5247fbc0f44c56b1520816c95a225198720
7
+ data.tar.gz: b0f32c69b41f4308b1bcbe7c9119c2b307579fbe9aaa7f2abc5d29b8c8376ada977e0ca6a8a41caff9a531da8e7b83cb97d4dcb71cf4ba23f6175d23a8a35f1c
data/.gitignore CHANGED
@@ -2,4 +2,9 @@
2
2
  *.swo
3
3
  *.gem
4
4
  *.sh
5
- .idea
5
+ .idea
6
+ cert.crt
7
+ cert.key
8
+ cert.pem
9
+ test_https_proxy.rb
10
+ mkchangelog.rb
@@ -23,6 +23,10 @@ begin
23
23
  OptionParser.new do |opts|
24
24
  opts.banner = "Usage: #{$0} [options]"
25
25
  opts.version = BetterCap::VERSION
26
+
27
+ opts.on( '-G', '--gateway ADDRESS', 'Manually specify the gateway address, if not specified the current gateway will be retrieved and used. ' ) do |v|
28
+ ctx.options[:gateway] = v
29
+ end
26
30
 
27
31
  opts.on( '-I', '--interface IFACE', 'Network interface name - default: ' + ctx.options[:iface].to_s ) do |v|
28
32
  ctx.options[:iface] = v
@@ -53,6 +57,11 @@ begin
53
57
  ctx.options[:sniffer] = true
54
58
  end
55
59
 
60
+ opts.on( '--sniffer-source FILE', 'Load packets from the specified PCAP file instead of the interface ( will enable sniffer ).' ) do |v|
61
+ ctx.options[:sniffer] = true
62
+ ctx.options[:sniffer_src] = File.expand_path v
63
+ end
64
+
56
65
  opts.on( '--sniffer-pcap FILE', 'Save all packets to the specified PCAP file ( will enable sniffer ).' ) do |v|
57
66
  ctx.options[:sniffer] = true
58
67
  ctx.options[:sniffer_pcap] = File.expand_path v
@@ -131,23 +140,7 @@ begin
131
140
 
132
141
  opts.on('-h', '--help', 'Display the available options.') do
133
142
  puts opts
134
- puts "\nExamples:\n".bold
135
- puts " - Sniffer / Credentials Harvester\n".bold
136
- puts " Default sniffer mode, all parsers enabled:\n\n"
137
- puts " sudo bettercap -X\n".bold
138
- puts " Enable sniffer and load only specified parsers:\n\n"
139
- puts " sudo bettercap -X -P \"FTP,HTTPAUTH,MAIL,NTLMSS\"\n".bold
140
- puts " Enable sniffer + all parsers and parse local traffic as well:\n\n"
141
- puts " sudo bettercap -X -L\n".bold
142
- puts " - Transparent Proxy\n".bold
143
- puts " Enable proxy on default ( 8080 ) port with no modules ( quite useless ):\n\n"
144
- puts " sudo bettercap --proxy\n".bold
145
- puts " Enable proxy and use a custom port:\n\n"
146
- puts " sudo bettercap --proxy --proxy-port=8081\n".bold
147
- puts " Enable proxy and load the module example_proxy_module.rb:\n\n"
148
- puts " sudo bettercap --proxy --proxy-module=example_proxy_module.rb\n".bold
149
- puts " Disable spoofer and enable proxy ( stand alone proxy mode ):\n\n"
150
- puts " sudo bettercap -S NONE --proxy".bold
143
+ puts "\nFor examples & instructions please visit " + "http://bettercap.org/features/".bold
151
144
  exit
152
145
  end
153
146
  end.parse!
@@ -168,10 +161,18 @@ begin
168
161
 
169
162
  Logger.logfile = ctx.options[:logfile]
170
163
 
164
+
165
+ if !ctx.options[:gateway].nil?
166
+ raise BetterCap::Error, "Invalid gateway" if !Network.is_ip?(ctx.options[:gateway])
167
+ ctx.gateway = ctx.options[:gateway]
168
+ Logger.info("Targetting manual gateway #{ctx.gateway}")
169
+ end
170
+
171
171
  ctx.update_network
172
172
 
173
173
  if ctx.options[:target].nil?
174
- Logger.info "Targeting the whole subnet #{ctx.network.to_range} ..."
174
+ Logger.info( "Targeting the whole subnet #{ctx.network.to_range} ..." ) unless \
175
+ ctx.options[:spoofer] == 'NONE' or ctx.options[:spoofer] == 'none'
175
176
 
176
177
  ctx.start_discovery_thread
177
178
  else
@@ -192,7 +193,6 @@ begin
192
193
  ctx.spoofer=Array.new
193
194
  spoofer_modules_names=ctx.options[:spoofer].split(",")
194
195
  spoofer_modules_names.each do |module_name|
195
- Logger.info "Loading module : #{module_name}"
196
196
  ctx.spoofer << SpooferFactory.get_by_name( module_name )
197
197
  ctx.spoofer.last.start
198
198
  end
@@ -12,6 +12,10 @@
12
12
 
13
13
  =end
14
14
 
15
+ # they hate us 'cause they ain't us
16
+ Encoding.default_external = Encoding::UTF_8
17
+ Encoding.default_internal = Encoding::UTF_8
18
+
15
19
  require 'optparse'
16
20
  require 'colorize'
17
21
  require 'packetfu'
@@ -3,4 +3,5 @@
3
3
  | '_ \ / _ \ __| __/ _ \ '__/ __/ _` | '_ \
4
4
  | |_) | __/ |_| || __/ | | (_| (_| | |_) |
5
5
  |_.__/ \___|\__|\__\___|_| \___\__,_| .__/
6
- |_| #VERSION#
6
+ |_| #VERSION#
7
+ http://bettercap.org/
@@ -36,6 +36,7 @@ class Context
36
36
  end
37
37
 
38
38
  @options = {
39
+ gateway: nil,
39
40
  iface: iface,
40
41
  spoofer: 'ARP',
41
42
  half_duplex: false,
@@ -47,6 +48,7 @@ class Context
47
48
  sniffer: false,
48
49
  sniffer_pcap: nil,
49
50
  sniffer_filter: nil,
51
+ sniffer_src: nil,
50
52
  parsers: ['*'],
51
53
  local: false,
52
54
 
@@ -113,7 +115,7 @@ class Context
113
115
  @firewall = FirewallFactory.get_firewall
114
116
  @ifconfig = PacketFu::Utils.ifconfig @options[:iface]
115
117
  @network = @ifconfig[:ip4_obj]
116
- @gateway = Network.get_gateway
118
+ @gateway = Network.get_gateway if @gateway.nil?
117
119
 
118
120
  raise BetterCap::Error, "Could not determine IPv4 address of '#{@options[:iface]}' interface." unless !@network.nil?
119
121
 
@@ -124,7 +126,7 @@ class Context
124
126
  def start_discovery_thread
125
127
  @discovery_running = true
126
128
  @discovery_thread = Thread.new {
127
- Logger.info 'Network discovery thread started.'
129
+ Logger.info( 'Network discovery thread started.' ) unless @options[:arpcache]
128
130
 
129
131
  while @discovery_running
130
132
  empty_list = false
@@ -158,11 +160,10 @@ class Context
158
160
  @discovery_running = false
159
161
 
160
162
  if @discovery_thread != nil
161
- Logger.info 'Stopping network discovery thread ...'
163
+ Logger.info( 'Stopping network discovery thread ...' ) unless @options[:arpcache]
162
164
 
163
- # I doubt this will ever raise an exception
164
165
  begin
165
- @discovery_thread.join
166
+ @discovery_thread.exit
166
167
  rescue
167
168
  end
168
169
  end
@@ -22,7 +22,7 @@ class IcmpAgent
22
22
  if RUBY_PLATFORM =~ /darwin/
23
23
  ping = Shell.execute("ping -i #{timeout} -c 2 255.255.255.255")
24
24
  elsif RUBY_PLATFORM =~ /linux/
25
- ping = Shell.execute("ping -i #{timeout} -c 2 -b 255.255.255.255")
25
+ ping = Shell.execute("ping -i #{timeout} -c 2 -b 255.255.255.255 2> /dev/null")
26
26
  end
27
27
  }
28
28
  end
@@ -26,10 +26,6 @@ class LinuxFirewall < IFirewall
26
26
  end
27
27
 
28
28
  def add_port_redirection( iface, proto, from, addr, to )
29
- # clear nat
30
- shell.execute('iptables -t nat -F')
31
- # clear
32
- shell.execute('iptables -F')
33
29
  # post route
34
30
  shell.execute('iptables -t nat -I POSTROUTING -s 0/0 -j MASQUERADE')
35
31
  # accept all
@@ -18,7 +18,6 @@ require 'bettercap/target'
18
18
  require 'bettercap/factories/firewall_factory'
19
19
  require 'bettercap/discovery/icmp'
20
20
  require 'bettercap/discovery/udp'
21
- require 'bettercap/discovery/syn'
22
21
  require 'bettercap/discovery/arp'
23
22
 
24
23
  class Network
@@ -70,10 +69,8 @@ class Network
70
69
  if ctx.options[:arpcache] == false
71
70
  icmp = IcmpAgent.new timeout
72
71
  udp = UdpAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
73
- syn = SynAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
74
72
  arp = ArpAgent.new ctx.ifconfig, ctx.gateway, ctx.ifconfig[:ip_saddr]
75
73
 
76
- syn.wait
77
74
  icmp.wait
78
75
  arp.wait
79
76
  udp.wait
@@ -85,8 +82,6 @@ class Network
85
82
  end
86
83
 
87
84
  =begin
88
- FIXME:
89
-
90
85
  Apparently on Mac OSX the gem pcaprub ( or libpcap itself ) has
91
86
  a bug, so we can't use 'PacketFu::Utils::arp' since the funtion
92
87
  it's using:
@@ -121,13 +121,14 @@ class Proxy
121
121
  total_size = opts[:request].content_length unless opts[:request].content_length.nil?
122
122
  end
123
123
 
124
- buff = ""
124
+ buff = ''
125
125
  read = 0
126
126
 
127
+
127
128
  if total_size
128
- chunk_size = 1024
129
- else
130
129
  chunk_size = [ 1024, total_size ].min
130
+ else
131
+ chunk_size = 1024
131
132
  end
132
133
 
133
134
  if chunk_size > 0
@@ -154,11 +155,17 @@ class Proxy
154
155
 
155
156
  def html_streaming( request, response, from, to )
156
157
  buff = ''
157
- loop do
158
- from.read 1024, buff
159
158
 
160
- break unless buff.size > 0
159
+ if response.content_length.nil?
160
+ loop do
161
+ from.read 1024, buff
162
+
163
+ break unless buff.size > 0
161
164
 
165
+ response << buff
166
+ end
167
+ else
168
+ from.read response.content_length, buff
162
169
  response << buff
163
170
  end
164
171
 
@@ -13,11 +13,12 @@ This project is released under the GPL 3 license.
13
13
  module Proxy
14
14
 
15
15
  class Response
16
- attr_reader :content_type, :content_length, :headers, :code, :headers_done
16
+ attr_reader :content_type, :charset, :content_length, :headers, :code, :headers_done
17
17
  attr_accessor :body
18
18
 
19
19
  def initialize
20
20
  @content_type = nil
21
+ @charset = 'UTF-8'
21
22
  @content_length = nil
22
23
  @body = ''
23
24
  @code = nil
@@ -43,22 +44,25 @@ class Response
43
44
  def <<(line)
44
45
  # we already parsed the heders, collect response body
45
46
  if @headers_done
46
- @body += line
47
+ @body += line.force_encoding( @charset )
47
48
  else
48
49
  # parse the response status
49
50
  if @code.nil? and line =~ /^HTTP\/[\d\.]+\s+(.+)/
50
51
  @code = $1.chomp
51
52
 
52
- # parse the content type
53
- elsif line =~ /^Content-Type: ([^;]+).*/i
53
+ # parse the content type
54
+ elsif line =~ /^Content-Type:\s*([^;]+).*/i
54
55
  @content_type = $1.chomp
56
+ if line =~ /^.+;\s*charset=(.+)/i
57
+ @charset = $1.chomp
58
+ end
55
59
 
56
- # parse content length
60
+ # parse content length
57
61
  elsif line =~ /^Content-Length:\s+(\d+)\s*$/i
58
62
  @content_length = $1.to_i
59
63
 
60
- # last line, we're done with the headers
61
- elsif line.chomp == ""
64
+ # last line, we're done with the headers
65
+ elsif line.chomp.empty?
62
66
  @headers_done = true
63
67
 
64
68
  end
@@ -14,23 +14,29 @@ require 'colorize'
14
14
  require 'resolv'
15
15
 
16
16
  class HttpsParser < BaseParser
17
- def on_packet( pkt )
18
- begin
19
- if pkt.tcp_dst == 443
20
- # the DNS resolution could take a while and block other parsers.
21
- Thread.new do
22
- begin
23
- hostname = Resolv.getname pkt.ip_daddr
24
- rescue
25
- hostname = pkt.ip_daddr.to_s
26
- end
27
-
28
- Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
29
- '[HTTPS] '.green +
30
- "https://#{hostname}/".yellow
31
- end
17
+ @@prev = nil
18
+
19
+ def on_packet( pkt )
20
+ begin
21
+ if pkt.tcp_dst == 443
22
+ # the DNS resolution could take a while and block other parsers.
23
+ Thread.new do
24
+ begin
25
+ hostname = Resolv.getname pkt.ip_daddr
26
+ rescue
27
+ hostname = pkt.ip_daddr.to_s
28
+ end
29
+
30
+ if @@prev.nil? or @@prev != hostname
31
+ Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
32
+ '[HTTPS] '.green +
33
+ "https://#{hostname}/".yellow
34
+
35
+ @@prev = hostname
32
36
  end
33
- rescue
34
37
  end
38
+ end
39
+ rescue
35
40
  end
41
+ end
36
42
  end
@@ -27,7 +27,7 @@ class Sniffer
27
27
 
28
28
  setup( ctx )
29
29
 
30
- @@cap.stream.each do |p|
30
+ self.stream.each do |p|
31
31
  begin
32
32
  parsed = Packet.parse p
33
33
  rescue Exception => e
@@ -44,6 +44,16 @@ class Sniffer
44
44
 
45
45
  private
46
46
 
47
+ def self.stream
48
+ if @@ctx.options[:sniffer_src].nil?
49
+ @@cap.stream
50
+ else
51
+ Logger.info "Reading packets from #{@@ctx.options[:sniffer_src]} ..."
52
+
53
+ PcapFile.file_to_array @@ctx.options[:sniffer_src]
54
+ end
55
+ end
56
+
47
57
  def self.skip_packet?( pkt )
48
58
  !@@ctx.options[:local] and
49
59
  ( pkt.ip_saddr == @@ctx.ifconfig[:ip_saddr] or
@@ -147,7 +147,10 @@ class ArpSpoofer < ISpoofer
147
147
  @ctx.firewall.enable_forwarding( @forwarding )
148
148
 
149
149
  @running = false
150
- @spoof_thread.join
150
+ begin
151
+ @spoof_thread.exit
152
+ rescue
153
+ end
151
154
 
152
155
  Logger.info "Restoring ARP table of #{@ctx.targets.size} targets ..."
153
156
 
@@ -10,6 +10,6 @@ This project is released under the GPL 3 license.
10
10
 
11
11
  =end
12
12
  module BetterCap
13
- VERSION = '1.1.4'
13
+ VERSION = '1.1.5'
14
14
  BANNER = File.read( File.dirname(__FILE__) + '/banner' ).gsub( '#VERSION#', "v#{VERSION}")
15
15
  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.1.4
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simone Margaritelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-08 00:00:00.000000000 Z
11
+ date: 2015-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -91,7 +91,6 @@ files:
91
91
  - lib/bettercap/discovery/arp.rb
92
92
  - lib/bettercap/discovery/base.rb
93
93
  - lib/bettercap/discovery/icmp.rb
94
- - lib/bettercap/discovery/syn.rb
95
94
  - lib/bettercap/discovery/udp.rb
96
95
  - lib/bettercap/error.rb
97
96
  - lib/bettercap/factories/firewall_factory.rb
@@ -142,7 +141,6 @@ files:
142
141
  - test/sniffer/parsers/url_parser_test.rb
143
142
  - test/target_test.rb
144
143
  - test/test_helper.rb
145
- - test_https_proxy.rb
146
144
  homepage: http://github.com/evilsocket/bettercap
147
145
  licenses:
148
146
  - GPL3
@@ -1,45 +0,0 @@
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/discovery/base'
13
-
14
- # Send SYN probes trying to filling the ARP table.
15
- class SynAgent < BaseAgent
16
- private
17
-
18
- def send_probe( ip )
19
- pkt = PacketFu::TCPPacket.new
20
- pkt.ip_v = 4
21
- pkt.ip_hl = 5
22
- pkt.ip_tos = 0
23
- pkt.ip_len = 20
24
- pkt.ip_frag = 0
25
- pkt.ip_ttl = 115
26
- pkt.ip_proto = 6 # TCP
27
- pkt.ip_saddr = @local_ip
28
- pkt.ip_daddr = ip
29
- pkt.payload = "\xC\x0\xF\xF\xE\xE"
30
- pkt.tcp_flags.ack = 0
31
- pkt.tcp_flags.fin = 0
32
- pkt.tcp_flags.psh = 0
33
- pkt.tcp_flags.rst = 0
34
- pkt.tcp_flags.syn = 1
35
- pkt.tcp_flags.urg = 0
36
- pkt.tcp_ecn = 0
37
- pkt.tcp_win = 8192
38
- pkt.tcp_hlen = 5
39
- pkt.tcp_dst = rand(1024..65535)
40
- pkt.recalc
41
-
42
- pkt.to_w( @ifconfig[:iface] )
43
- end
44
- end
45
-
@@ -1,29 +0,0 @@
1
- require 'openssl'
2
- require 'socket'
3
-
4
- sock = TCPSocket.new( '172.20.10.2', 8083 )
5
-
6
- ctx = OpenSSL::SSL::SSLContext.new
7
-
8
- # we need this? :P ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_PEER)
9
-
10
- socket = OpenSSL::SSL::SSLSocket.new(sock, ctx).tap do |socket|
11
- socket.sync_close = true
12
- socket.connect
13
-
14
- socket.write "GET / HTTP/1.1\n" +
15
- "Host: www.facebook.com\n" +
16
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\n" +
17
- "Accept-encoding: gzip, deflate, sdch\n" +
18
- "Accept-language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4,la;q=0.2\n" +
19
- "Cache-control: max-age=0\n" +
20
- "User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36\n" +
21
- "\n\n"
22
-
23
- while line = socket.gets # Read lines from socket
24
- puts line # and print them
25
- end
26
-
27
- socket.close
28
- end
29
-