bettercap 1.1.8 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,7 +28,7 @@ class HttpsParser < BaseParser
28
28
  end
29
29
 
30
30
  if @@prev.nil? or @@prev != hostname
31
- Logger.write "[#{addr2s(pkt.ip_saddr)}:#{pkt.tcp_src} > #{addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
31
+ Logger.raw "[#{addr2s(pkt.ip_saddr)}:#{pkt.tcp_src} > #{addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
32
32
  '[HTTPS] '.green +
33
33
  "https://#{hostname}/".yellow
34
34
 
@@ -30,7 +30,7 @@ class NtlmssParser < BaseParser
30
30
  s = pkt.to_s
31
31
  if s =~ /NTLMSSP\x00\x03\x00\x00\x00.+/
32
32
  # TODO: Parse NTLMSSP packet.
33
- Logger.write "[#{addr2s(pkt.ip_saddr)} > #{addr2s(pkt.ip_daddr)} #{pkt.proto.last}] " +
33
+ Logger.raw "[#{addr2s(pkt.ip_saddr)} > #{addr2s(pkt.ip_daddr)} #{pkt.proto.last}] " +
34
34
  '[NTLMSS] '.green +
35
35
  bin2hex( pkt.payload ).yellow
36
36
  end
@@ -16,7 +16,7 @@ class PostParser < BaseParser
16
16
  def on_packet( pkt )
17
17
  s = pkt.to_s
18
18
  if s =~ /POST\s+[^\s]+\s+HTTP.+/
19
- Logger.write "[#{addr2s(pkt.ip_saddr)}:#{pkt.tcp_src} > #{addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
19
+ Logger.raw "[#{addr2s(pkt.ip_saddr)}:#{pkt.tcp_src} > #{addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
20
20
  "[POST]\n".green +
21
21
  pkt.payload.strip.yellow
22
22
  end
@@ -19,7 +19,7 @@ class UrlParser < BaseParser
19
19
  host = $2
20
20
  url = $1
21
21
  if not url =~ /.+\.(png|jpg|jpeg|bmp|gif|img|ttf|woff|css|js).*/i
22
- Logger.write "[#{addr2s(pkt.ip_saddr)}:#{pkt.tcp_src} > #{addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
22
+ Logger.raw "[#{addr2s(pkt.ip_saddr)}:#{pkt.tcp_src} > #{addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
23
23
  '[GET] '.green +
24
24
  "http://#{host}#{url}".yellow
25
25
  end
@@ -23,21 +23,24 @@ class Sniffer
23
23
  @@cap = nil
24
24
 
25
25
  def self.start( ctx )
26
- Logger.info 'Starting sniffer ...'
27
-
28
- setup( ctx )
29
-
30
- self.stream.each do |p|
31
- begin
32
- parsed = Packet.parse p
33
- rescue Exception => e
34
- parsed = nil
35
- Logger.debug e.message
36
- end
37
-
38
- if not parsed.nil? and parsed.is_ip? and !skip_packet?(parsed)
39
- append_packet p
40
- parse_packet parsed
26
+ Thread.new do
27
+ Logger.info 'Starting sniffer ...'
28
+
29
+ setup( ctx )
30
+
31
+ self.stream.each do |p|
32
+ break unless @@ctx.running
33
+ begin
34
+ parsed = Packet.parse p
35
+ rescue Exception => e
36
+ parsed = nil
37
+ Logger.debug e.message
38
+ end
39
+
40
+ if not parsed.nil? and parsed.is_ip? and !skip_packet?(parsed)
41
+ append_packet p
42
+ parse_packet parsed
43
+ end
41
44
  end
42
45
  end
43
46
  end
@@ -19,22 +19,21 @@ require 'colorize'
19
19
  class ArpSpoofer < ISpoofer
20
20
  def initialize
21
21
  @ctx = Context.get
22
- @gw_hw = nil
22
+ @gateway = nil
23
23
  @forwarding = @ctx.firewall.forwarding_enabled?
24
24
  @spoof_thread = nil
25
25
  @sniff_thread = nil
26
26
  @capture = nil
27
27
  @running = false
28
28
 
29
- Logger.debug 'ARP SPOOFER SELECTED'
30
-
31
29
  Logger.info "Getting gateway #{@ctx.gateway} MAC address ..."
32
- @gw_hw = Network.get_hw_address( @ctx.ifconfig, @ctx.gateway )
33
- if @gw_hw.nil?
34
- raise BetterCap::Error, "Couldn't determine router MAC"
35
- end
36
30
 
37
- Logger.info " Gateway : #{@ctx.gateway} ( #{@gw_hw} )"
31
+ hw = Network.get_hw_address( @ctx.ifconfig, @ctx.gateway )
32
+ raise BetterCap::Error, "Couldn't determine router MAC" if hw.nil?
33
+
34
+ @gateway = Target.new( @ctx.gateway, hw )
35
+
36
+ Logger.info " #{@gateway}"
38
37
  end
39
38
 
40
39
  def send_spoofed_packet( saddr, smac, daddr, dmac )
@@ -122,8 +121,8 @@ class ArpSpoofer < ISpoofer
122
121
  end
123
122
  end
124
123
 
125
- send_spoofed_packet( @ctx.gateway, @ctx.ifconfig[:eth_saddr], target.ip, target.mac )
126
- send_spoofed_packet( target.ip, @ctx.ifconfig[:eth_saddr], @ctx.gateway, @gw_hw ) unless @ctx.options.half_duplex
124
+ send_spoofed_packet( @gateway.ip, @ctx.ifconfig[:eth_saddr], target.ip, target.mac )
125
+ send_spoofed_packet( target.ip, @ctx.ifconfig[:eth_saddr], @gateway.ip, @gateway.mac ) unless @ctx.options.half_duplex
127
126
  end
128
127
 
129
128
  prev_size = @ctx.targets.size
@@ -150,9 +149,11 @@ class ArpSpoofer < ISpoofer
150
149
  Logger.info "Restoring ARP table of #{@ctx.targets.size} targets ..."
151
150
 
152
151
  @ctx.targets.each do |target|
153
- if !target.mac.nil?
154
- send_spoofed_packet( @ctx.gateway, @gw_hw, target.ip, target.mac )
155
- send_spoofed_packet( target.ip, target.mac, @ctx.gateway, @gw_hw ) unless @ctx.options.half_duplex
152
+ unless target.mac.nil?
153
+ begin
154
+ send_spoofed_packet( @gateway.ip, @gateway.mac, target.ip, target.mac )
155
+ send_spoofed_packet( target.ip, target.mac, @gateway.ip, @gateway.mac ) unless @ctx.options.half_duplex
156
+ rescue; end
156
157
  end
157
158
  end
158
159
  sleep 1
@@ -24,22 +24,25 @@ class Target
24
24
 
25
25
  def initialize( ip, mac=nil )
26
26
  @ip = ip
27
- @mac = mac
28
- @vendor = Target.lookup_vendor(mac) if not mac.nil?
27
+ @mac = normalized_mac mac unless mac.nil?
28
+ @vendor = Target.lookup_vendor(@mac) unless mac.nil?
29
29
  @hostname = nil
30
30
  @resolver = Thread.new { resolve! }
31
31
  end
32
32
 
33
+ def sortable_ip
34
+ @ip.split('.').inject(0) {|total,value| (total << 8 ) + value.to_i}
35
+ end
36
+
33
37
  def mac=(value)
34
- @mac = value
38
+ @mac = normalized_mac value
35
39
  @vendor = Target.lookup_vendor(@mac) if not @mac.nil?
36
40
  end
37
41
 
38
42
  def to_s
39
- s = @ip
40
- s += " ( #{@hostname} )" unless @hostname.nil?
41
- s += " : #{@mac}"
42
- s += " ( #{@vendor} )" unless @vendor.nil?
43
+ s = sprintf( '%-15s : %-17s', @ip, @mac )
44
+ s += " / #{@hostname}" unless @hostname.nil?
45
+ s += if @vendor.nil? then " ( ??? )" else " ( #{@vendor} )" end
43
46
  s
44
47
  end
45
48
 
@@ -51,8 +54,16 @@ class Target
51
54
  end
52
55
  end
53
56
 
57
+ def equals?(ip, mac)
58
+ ( @ip == ip && ( mac.nil? || @mac == normalized_mac(mac) ) )
59
+ end
60
+
54
61
  private
55
62
 
63
+ def normalized_mac(v)
64
+ v.split(':').map { |e| if e.size == 2 then e.upcase else "0#{e.upcase}" end }.join(':')
65
+ end
66
+
56
67
  def resolve!
57
68
  resp, sock = nil, nil
58
69
  begin
@@ -0,0 +1,53 @@
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/version'
13
+ require 'bettercap/error'
14
+ require 'bettercap/logger'
15
+ require 'net/http'
16
+ require 'json'
17
+
18
+ class UpdateChecker
19
+ def self.check
20
+ ver = self.get_latest_version
21
+ if self.vton( BetterCap::VERSION ) < self.vton( ver )
22
+ Logger.warn "New version '#{ver}' available!"
23
+ else
24
+ Logger.info 'You are running the latest version.'
25
+ end
26
+ rescue Exception => e
27
+ Logger.error("Error '#{e.class}' while checking for updates: #{e.message}")
28
+ end
29
+
30
+ def self.vton v
31
+ vi = 0.0
32
+ v.split('.').reverse.each_with_index do |e,i|
33
+ vi += ( e.to_i * 10**i ) - ( if e =~ /[\d+]b/ then 0.5 else 0 end )
34
+ end
35
+ vi
36
+ end
37
+
38
+ def self.get_latest_version
39
+ Logger.info 'Checking for updates ...'
40
+
41
+ api = URI('https://rubygems.org/api/v1/versions/bettercap/latest.json')
42
+ response = Net::HTTP.get_response(api)
43
+
44
+ case response
45
+ when Net::HTTPSuccess
46
+ json = JSON.parse(response.body)
47
+ else
48
+ raise response.message
49
+ end
50
+
51
+ return json['version']
52
+ end
53
+ end
@@ -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.8'
13
+ VERSION = '1.1.9'
14
14
  BANNER = File.read( File.dirname(__FILE__) + '/banner' ).gsub( '#VERSION#', "v#{VERSION}")
15
15
  end
data/test/logger_test.rb CHANGED
@@ -5,7 +5,7 @@ require 'logger'
5
5
  class LoggerTest < MiniTest::Test
6
6
  def test_writing_with_a_logfile
7
7
  silence do |output|
8
- Logger.write 'Test log message'
8
+ Logger.raw 'Test log message'
9
9
  assert_equal output.read, "Test log message\n"
10
10
  end
11
11
  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.8
4
+ version: 1.1.9
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-12-14 00:00:00.000000000 Z
11
+ date: 2016-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -87,17 +87,11 @@ executables:
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - .gitignore
91
90
  - CONTRIBUTING.md
92
- - Gemfile
93
- - Gemfile.lock
94
91
  - LICENSE.md
95
92
  - README.md
96
- - Rakefile
97
93
  - TODO.md
98
- - bettercap.gemspec
99
- - bin/bettercap
100
- - lib/bettercap.rb
94
+ - Rakefile
101
95
  - lib/bettercap/banner
102
96
  - lib/bettercap/base/ifirewall.rb
103
97
  - lib/bettercap/base/ispoofer.rb
@@ -106,6 +100,7 @@ files:
106
100
  - lib/bettercap/discovery/base.rb
107
101
  - lib/bettercap/discovery/icmp.rb
108
102
  - lib/bettercap/discovery/udp.rb
103
+ - lib/bettercap/discovery.rb
109
104
  - lib/bettercap/error.rb
110
105
  - lib/bettercap/factories/firewall_factory.rb
111
106
  - lib/bettercap/factories/parser_factory.rb
@@ -141,7 +136,10 @@ files:
141
136
  - lib/bettercap/spoofers/arp.rb
142
137
  - lib/bettercap/spoofers/none.rb
143
138
  - lib/bettercap/target.rb
139
+ - lib/bettercap/update_checker.rb
144
140
  - lib/bettercap/version.rb
141
+ - lib/bettercap.rb
142
+ - bin/bettercap
145
143
  - test/factories/firewall_factory_test.rb
146
144
  - test/factories/parser_factory_test.rb
147
145
  - test/factories/spoofer_factory_test.rb
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- *.swp
2
- *.swo
3
- *.gem
4
- *.sh
5
- .idea
6
- cert.crt
7
- cert.key
8
- cert.pem
9
- test_https_proxy.rb
10
- test_chunked.rb
11
- mkchangelog.rb
12
- .tags*
data/Gemfile DELETED
@@ -1,2 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
data/Gemfile.lock DELETED
@@ -1,25 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- bettercap (1.1.3)
5
- colorize (~> 0.7.5)
6
- packetfu (~> 1.1.10)
7
- pcaprub (~> 0.12.0)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- colorize (0.7.7)
13
- minitest (5.7.0)
14
- packetfu (1.1.10)
15
- pcaprub (0.12.0)
16
-
17
- PLATFORMS
18
- ruby
19
-
20
- DEPENDENCIES
21
- bettercap!
22
- minitest
23
-
24
- BUNDLED WITH
25
- 1.10.3
data/bettercap.gemspec DELETED
@@ -1,28 +0,0 @@
1
- require './lib/bettercap/version'
2
-
3
- Gem::Specification.new do |gem|
4
- gem.name = %q{bettercap}
5
- gem.version = BetterCap::VERSION
6
- gem.license = 'GPL3'
7
- gem.description = %q{A complete, modular, portable and easily extensible MITM framework.}
8
- gem.summary = %q{A complete, modular, portable and easily extensible MITM framework.}
9
- gem.required_ruby_version = '>= 1.9'
10
-
11
-
12
- gem.authors = ['Simone Margaritelli']
13
- gem.email = %q{evilsocket@gmail.com}
14
- gem.homepage = %q{http://github.com/evilsocket/bettercap}
15
-
16
- gem.add_dependency( 'colorize', '~> 0.7.5' )
17
- gem.add_dependency( 'packetfu', '~> 1.1.10' )
18
- gem.add_dependency( 'pcaprub', '~> 0.12.0' )
19
- gem.add_dependency( 'network_interface', '~> 0.0.1' )
20
-
21
- gem.add_development_dependency( 'minitest' )
22
-
23
- gem.files = `git ls-files`.split("\n")
24
- gem.require_paths = ["lib"]
25
-
26
- gem.executables = %w(bettercap)
27
- gem.rdoc_options = ["--charset=UTF-8"]
28
- end