bettercap 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +225 -0
  3. data/README.md +96 -0
  4. data/bettercap.gemspec +28 -0
  5. data/bin/bettercap +184 -0
  6. data/example_proxy_module.rb +21 -0
  7. data/lib/bettercap/base/ifirewall.rb +28 -0
  8. data/lib/bettercap/base/ispoofer.rb +24 -0
  9. data/lib/bettercap/context.rb +124 -0
  10. data/lib/bettercap/discovery/arp.rb +37 -0
  11. data/lib/bettercap/discovery/icmp.rb +37 -0
  12. data/lib/bettercap/discovery/syn.rb +88 -0
  13. data/lib/bettercap/discovery/udp.rb +74 -0
  14. data/lib/bettercap/error.rb +16 -0
  15. data/lib/bettercap/factories/firewall_factory.rb +32 -0
  16. data/lib/bettercap/factories/parser_factory.rb +53 -0
  17. data/lib/bettercap/factories/spoofer_factory.rb +36 -0
  18. data/lib/bettercap/firewalls/linux.rb +55 -0
  19. data/lib/bettercap/firewalls/osx.rb +70 -0
  20. data/lib/bettercap/hw-prefixes +19651 -0
  21. data/lib/bettercap/logger.rb +53 -0
  22. data/lib/bettercap/monkey/packetfu/utils.rb +96 -0
  23. data/lib/bettercap/network.rb +131 -0
  24. data/lib/bettercap/proxy/module.rb +39 -0
  25. data/lib/bettercap/proxy/proxy.rb +262 -0
  26. data/lib/bettercap/proxy/request.rb +77 -0
  27. data/lib/bettercap/proxy/response.rb +76 -0
  28. data/lib/bettercap/shell.rb +31 -0
  29. data/lib/bettercap/sniffer/parsers/base.rb +31 -0
  30. data/lib/bettercap/sniffer/parsers/ftp.rb +19 -0
  31. data/lib/bettercap/sniffer/parsers/httpauth.rb +45 -0
  32. data/lib/bettercap/sniffer/parsers/https.rb +36 -0
  33. data/lib/bettercap/sniffer/parsers/irc.rb +19 -0
  34. data/lib/bettercap/sniffer/parsers/mail.rb +19 -0
  35. data/lib/bettercap/sniffer/parsers/ntlmss.rb +38 -0
  36. data/lib/bettercap/sniffer/parsers/post.rb +24 -0
  37. data/lib/bettercap/sniffer/parsers/url.rb +28 -0
  38. data/lib/bettercap/sniffer/sniffer.rb +39 -0
  39. data/lib/bettercap/spoofers/arp.rb +130 -0
  40. data/lib/bettercap/spoofers/none.rb +23 -0
  41. data/lib/bettercap/target.rb +52 -0
  42. data/lib/bettercap/version.rb +14 -0
  43. metadata +129 -0
@@ -0,0 +1,77 @@
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
+ module Proxy
14
+
15
+ class Request
16
+ attr_reader :lines, :verb, :url, :host, :port, :content_length
17
+
18
+ def initialize
19
+ @lines = []
20
+ @verb = nil
21
+ @url = nil
22
+ @host = nil
23
+ @port = 80
24
+ @content_length = 0
25
+ end
26
+
27
+ def <<(line)
28
+ line = line.chomp
29
+
30
+ # is this the first line '<VERB> <URI> HTTP/<VERSION>' ?
31
+ if @url.nil? and line =~ /^(\w+)\s+(\S+)\s+HTTP\/[\d\.]+\s*$/
32
+ @verb = $1
33
+ @url = $2
34
+
35
+ # fix url
36
+ if @url.include? '://'
37
+ uri = URI::parse @url
38
+ @url = "#{uri.path}" + ( uri.query ? "?#{uri.query}" : "" )
39
+ end
40
+
41
+ line = "#{@verb} #{url} HTTP/1.0"
42
+
43
+ # get the host header value
44
+ elsif line =~ /^Host: (.*)$/
45
+ @host = $1
46
+ if host =~ /([^:]*):([0-9]*)$/
47
+ @host = $1
48
+ @port = $2.to_i
49
+ end
50
+
51
+ # parse content length, this will speed up data streaming
52
+ elsif line =~ /^Content-Length:\s+(\d+)\s*$/i
53
+ @content_length = $1.to_i
54
+
55
+ # we don't want to have hundreds of threads running
56
+ elsif line =~ /Connection: keep-alive/i
57
+ line = 'Connection: close'
58
+
59
+ # disable gzip, chunked, etc encodings
60
+ elsif line =~ /^Accept-Encoding:.*/i
61
+ line = 'Accept-Encoding: identity'
62
+
63
+ end
64
+
65
+ @lines << line
66
+ end
67
+
68
+ def is_post?
69
+ return @verb == 'POST'
70
+ end
71
+
72
+ def to_s
73
+ return @lines.join("\n") + "\n"
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,76 @@
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
+ module Proxy
14
+
15
+ class Response
16
+ attr_reader :content_type, :content_length, :headers, :code, :headers_done
17
+ attr_accessor :body
18
+
19
+ def initialize
20
+ @content_type = nil
21
+ @content_length = nil
22
+ @body = ''
23
+ @code = nil
24
+ @headers = []
25
+ @headers_done = false
26
+ end
27
+
28
+ def <<(line)
29
+ # we already parsed the heders, collect response body
30
+ if @headers_done
31
+ @body += line
32
+ else
33
+ # parse the response status
34
+ if @code.nil? and line =~ /^HTTP\/[\d\.]+\s+(.+)/
35
+ @code = $1.chomp
36
+
37
+ # parse the content type
38
+ elsif line =~ /^Content-Type: ([^;]+).*/i
39
+ @content_type = $1.chomp
40
+
41
+ # parse content length
42
+ elsif line =~ /^Content-Length:\s+(\d+)\s*$/i
43
+ @content_length = $1.to_i
44
+
45
+ # last line, we're done with the headers
46
+ elsif line.chomp == ""
47
+ @headers_done = true
48
+
49
+ end
50
+
51
+ @headers << line.chomp
52
+ end
53
+ end
54
+
55
+ def is_textual?
56
+ @content_type and ( @content_type =~ /^text\/.+/ or @content_type =~ /^application\/.+/ )
57
+ end
58
+
59
+ def to_s
60
+ if is_textual?
61
+ @headers.map! do |header|
62
+ # update content length in case the body was
63
+ # modified
64
+ if header =~ /Content-Length:\s*(\d+)/i
65
+ "Content-Length: #{@body.size}"
66
+ else
67
+ header
68
+ end
69
+ end
70
+ end
71
+
72
+ @headers.join("\n") + "\n" + @body
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,31 @@
1
+ =begin
2
+ BETTERCAP
3
+ Author : Simone 'evilsocket' Margaritelli
4
+ Email : evilsocket@gmail.com
5
+ Blog : http://www.evilsocket.net/
6
+ This project is released under the GPL 3 license.
7
+ =end
8
+ require 'bettercap/error'
9
+
10
+ module Shell
11
+ class << self
12
+
13
+ #return the output of command
14
+ def execute(command)
15
+ r=%x(#{command})
16
+ if $? != 0
17
+ raise BetterCap::Error, "Error, executing #{command}"
18
+ end
19
+ return r
20
+ end
21
+
22
+ def ifconfig(iface = '')
23
+ self.execute( "LANG=en && ifconfig #{iface}" )
24
+ end
25
+
26
+ def arp
27
+ self.execute( 'LANG=en && arp -a' )
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,31 @@
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/logger'
13
+ require 'colorize'
14
+
15
+ class BaseParser
16
+ def initialize
17
+ @filters = []
18
+ @name = 'BASE'
19
+ end
20
+
21
+ def on_packet( pkt )
22
+ s = pkt.to_s
23
+ @filters.each do |filter|
24
+ if s =~ filter
25
+ Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
26
+ "[#{@name}] ".green +
27
+ pkt.payload.strip.yellow
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
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
+ class FtpParser < BaseParser
15
+ def initialize
16
+ @filters = [ /(USER|PASS)\s+.+/ ]
17
+ @name = 'FTP'
18
+ end
19
+ end
@@ -0,0 +1,45 @@
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
+ require 'colorize'
14
+ require 'base64'
15
+
16
+ class HttpauthParser < BaseParser
17
+ def on_packet( pkt )
18
+ lines = pkt.to_s.split("\n")
19
+ hostname = nil
20
+ path = nil
21
+
22
+ lines.each do |line|
23
+ if line =~ /[A-Z]+\s+(\/[^\s]+)\s+HTTP\/\d\.\d/
24
+ path = $1
25
+
26
+ elsif line =~ /Host:\s*([^\s]+)/i
27
+ hostname = $1
28
+
29
+ elsif line =~ /Authorization:\s*Basic\s+([^\s]+)/i
30
+ encoded = $1
31
+ decoded = Base64.decode64(encoded)
32
+ user, pass = decoded.split(':')
33
+
34
+ Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
35
+ '[HTTP BASIC AUTH]'.green + " http://#{hostname}#{path} - username=#{user} password=#{pass}".yellow
36
+
37
+ elsif line =~ /Authorization:\s*Digest\s+(.+)/i
38
+ Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
39
+ '[HTTP DIGEST AUTH]'.green + " http://#{hostname}#{path}\n#{$1}".yellow
40
+
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,36 @@
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
+ require 'colorize'
14
+ require 'resolv'
15
+
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
32
+ end
33
+ rescue
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
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
+ class IrcParser < BaseParser
15
+ def initialize
16
+ @filters = [ /NICK\s+.+/, /NS IDENTIFY\s+.+/, /nickserv :identify\s+.+/ ]
17
+ @name = 'IRC'
18
+ end
19
+ end
@@ -0,0 +1,19 @@
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
+ class MailParser < BaseParser
15
+ def initialize
16
+ @filters = [ /(\d+ )?(auth|authenticate) (login|plain)/i, /(\d+ )?login/i ]
17
+ @name = 'MAIL'
18
+ end
19
+ end
@@ -0,0 +1,38 @@
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
+ require 'colorize'
14
+
15
+ class NtlmssParser < BaseParser
16
+ def bin2hex( data )
17
+ hex = ''
18
+ data.each_byte do |byte|
19
+ if /[[:print:]]/ === byte.chr
20
+ hex += byte.chr
21
+ else
22
+ hex += "\\x" + byte.to_s(16)
23
+ end
24
+ end
25
+
26
+ hex
27
+ end
28
+
29
+ def on_packet( pkt )
30
+ s = pkt.to_s
31
+ if s =~ /NTLMSSP\x00\x03\x00\x00\x00.+/
32
+ # TODO: Parse NTLMSSP packet.
33
+ Logger.write "[#{pkt.ip_saddr} > #{pkt.ip_daddr} #{pkt.proto.last}] " +
34
+ '[NTLMSS] '.green +
35
+ bin2hex( pkt.payload ).yellow
36
+ end
37
+ end
38
+ end
@@ -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
+ require 'colorize'
14
+
15
+ class PostParser < BaseParser
16
+ def on_packet( pkt )
17
+ s = pkt.to_s
18
+ if s =~ /POST\s+[^\s]+\s+HTTP.+/
19
+ Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
20
+ "[POST]\n".green +
21
+ pkt.payload.strip.yellow
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
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
+ require 'colorize'
14
+
15
+ class UrlParser < BaseParser
16
+ def on_packet( pkt )
17
+ s = pkt.to_s
18
+ if s =~ /GET\s+([^\s]+)\s+HTTP.+Host:\s+([^\s]+).+/m
19
+ host = $2
20
+ url = $1
21
+ if not url =~ /.+\.(png|jpg|jpeg|bmp|gif|img|ttf|woff|css|js).*/i
22
+ Logger.write "[#{pkt.ip_saddr}:#{pkt.tcp_src} > #{pkt.ip_daddr}:#{pkt.tcp_dst} #{pkt.proto.last}] " +
23
+ '[GET] '.green +
24
+ "http://#{host}#{url}".yellow
25
+ end
26
+ end
27
+ end
28
+ end