ciphersurfer 1.0.0.rc1 → 1.0.0
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.
- data/Gemfile +0 -2
- data/Gemfile.lock +0 -4
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +92 -8
- data/Rakefile +7 -3
- data/VERSION +1 -1
- data/bin/ciphersurfer +70 -43
- data/lib/ciphersurfer/scanner.rb +36 -15
- data/lib/ciphersurfer/score.rb +0 -4
- data/lib/ciphersurfer/version.rb +7 -86
- data/spec/scoring_spec.rb +30 -30
- metadata +24 -47
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
awesome_print (1.0.2)
|
5
4
|
diff-lcs (1.1.3)
|
6
5
|
git (1.2.5)
|
7
6
|
httpclient (2.2.4)
|
@@ -10,7 +9,6 @@ GEM
|
|
10
9
|
git (>= 1.2.5)
|
11
10
|
rake
|
12
11
|
json (1.6.5)
|
13
|
-
progressbar (0.9.2)
|
14
12
|
rainbow (1.1.3)
|
15
13
|
rake (0.9.2.2)
|
16
14
|
rcov (0.9.11)
|
@@ -27,12 +25,10 @@ PLATFORMS
|
|
27
25
|
ruby
|
28
26
|
|
29
27
|
DEPENDENCIES
|
30
|
-
awesome_print
|
31
28
|
bundler (~> 1.0.0)
|
32
29
|
httpclient
|
33
30
|
jeweler (~> 1.6.4)
|
34
31
|
json
|
35
|
-
progressbar
|
36
32
|
rainbow
|
37
33
|
rcov
|
38
34
|
rspec (~> 2.3.0)
|
data/{LICENSE → LICENSE.txt}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,24 +1,108 @@
|
|
1
1
|
# ciphersurfer
|
2
2
|
|
3
|
-
ciphersurfer is a tool
|
4
|
-
|
5
|
-
|
3
|
+
ciphersurfer is a tool written for the early stages of a penetration test
|
4
|
+
activities. While gathering information about an host, it's important to
|
5
|
+
evaluate how strong is the cryptography applied to the HTTP traffic. This is
|
6
|
+
the ciphersurfer goal.
|
7
|
+
|
8
|
+
The tool tries for every SSL protocols it supports to connect to the host with
|
9
|
+
all ciphers saving the ones the server supports.
|
10
|
+
|
11
|
+
This information used with certificate key lenght and the list of supported
|
12
|
+
protocols by the server it's used to evaluate how strong is the target HTTPS
|
13
|
+
configuration. This gives the penetration test an information about how secure
|
14
|
+
is the communication between clients and the target machine.
|
15
|
+
|
16
|
+
## Some disclaimer
|
17
|
+
|
18
|
+
ciphersurfer performs neither of the followings:
|
19
|
+
|
20
|
+
* denial of service attacks
|
21
|
+
* cross site scripting or injection attempts
|
22
|
+
* data manipulation or leakage
|
23
|
+
|
24
|
+
The requests the tool makes are just an HTTP GET / of target website to ensure
|
25
|
+
the server accept an HTTP communication given a SSL protocol and cipher
|
26
|
+
proposed by the client. No more. Really, ciphersurer won't hurt your webserver,
|
27
|
+
nor your business.
|
28
|
+
|
29
|
+
If you don't trust this disclaimer, just check the source code.
|
6
30
|
|
7
31
|
## Installing ciphersurfer
|
8
32
|
|
9
|
-
|
33
|
+
ciphersurfer is deployed as standard gem served by
|
34
|
+
[rubygems](http://rubygems.org).
|
35
|
+
|
36
|
+
To install latest ciphersurfer stable release, just issue this command:
|
37
|
+
|
38
|
+
```
|
39
|
+
gem install ciphersurfer
|
40
|
+
```
|
41
|
+
|
42
|
+
If you want to install a _pre_ release, such as a _release candidate_ you can do it this way:
|
43
|
+
|
44
|
+
```
|
45
|
+
gem install ciphersurfer --pre
|
46
|
+
```
|
47
|
+
|
48
|
+
I recommend you to install [rvm](https://rvm.beginrescueend.com/) in order to
|
49
|
+
have your gem binaries tool installed in your home directory, otherwise
|
50
|
+
ciphersurfer will try to install itself in standard /usr/bin directory if no
|
51
|
+
other flags are passed to gem command.
|
52
|
+
|
53
|
+
## Using ciphersurfer
|
54
|
+
|
55
|
+
After ciphersurfer has been installed, using it it's very simple.
|
56
|
+
|
57
|
+
To evaluate secure communication with the target host _test-this.com_ at the
|
58
|
+
standard HTTPS port, you just give the tool the target name as option:
|
59
|
+
|
60
|
+
```
|
61
|
+
ciphersurfer test-this.com
|
62
|
+
```
|
63
|
+
|
64
|
+
As output you will see an evaluation for HTTPS test-this.com configuration.
|
65
|
+
The evaluation scale is:
|
66
|
+
|
67
|
+
* A: _prime class_ HTTPS configuration. Servers handling **very** sensitive
|
68
|
+
information
|
69
|
+
* B: strong HTTPS configuration, suitable for must production servers
|
70
|
+
* C: quite goot HTTPS configuration. If your web server is a private server and
|
71
|
+
for development or testing purposes, it can be acceptable. If your server is
|
72
|
+
exposed to the Internet, you want to improve your SSL configuration.
|
73
|
+
* D: poor HTTPS configuration. Suitable **only** for development machines.
|
74
|
+
* E: weak HTTPS configuration. You really don't want to have this score
|
75
|
+
|
76
|
+
If your HTTPS server is listening to a non standard port, you can supply the
|
77
|
+
port number (e.g. 4433) this way:
|
78
|
+
|
79
|
+
```
|
80
|
+
ciphersurfer test-this.com:4433
|
81
|
+
```
|
82
|
+
|
83
|
+
You can also just listen ciphers supported by your web server instead of having
|
84
|
+
an SSL evaluation:
|
85
|
+
|
86
|
+
```
|
87
|
+
$ ciphersurfer -l gmail.com
|
10
88
|
|
11
|
-
|
89
|
+
"Evaluating secure communication with gmail.com:443"
|
90
|
+
"[+] accepted RC4-MD5"
|
91
|
+
"[+] accepted AES256-SHA"
|
92
|
+
"[+] accepted DES-CBC3-SHA"
|
93
|
+
"[+] accepted AES128-SHA"
|
94
|
+
"[+] accepted RC4-SHA"
|
95
|
+
```
|
12
96
|
|
13
|
-
|
97
|
+
## Some theory behind ciphersurfer
|
14
98
|
|
15
|
-
|
99
|
+
### SSLabs
|
16
100
|
|
17
101
|
For the SSL security evaluation, we use [SSLabs
|
18
102
|
document](https://www.ssllabs.com/downloads/SSL_Server_Rating_Guide_2009.pdf)
|
19
103
|
as reference.
|
20
104
|
|
21
|
-
|
105
|
+
### OWASP Testing guide
|
22
106
|
|
23
107
|
ciphersurfer goal is to make tests described in the [Owasp Testing
|
24
108
|
guide](https://www.owasp.org/index.php/Testing_for_SSL-TLS_(OWASP-CM-001\))
|
data/Rakefile
CHANGED
@@ -12,14 +12,18 @@ end
|
|
12
12
|
require 'rake'
|
13
13
|
|
14
14
|
require 'jeweler'
|
15
|
+
require './lib/ciphersurfer/version'
|
16
|
+
|
15
17
|
Jeweler::Tasks.new do |gem|
|
16
18
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
19
|
gem.name = "ciphersurfer"
|
18
20
|
gem.homepage = "http://github.com/thesp0nge/ciphersurfer"
|
19
21
|
gem.license = "BSD"
|
20
|
-
gem.version =
|
21
|
-
|
22
|
-
|
22
|
+
gem.version = Ciphersurfer::Version::STRING
|
23
|
+
File.open('VERSION', 'w') {|f| f.write(Ciphersurfer::Version::STRING) }
|
24
|
+
|
25
|
+
gem.summary = %Q{evaluates web server SSL configuration}
|
26
|
+
gem.description = %Q{ciphersurfer is a security tool that evaluates web server SSL configuration}
|
23
27
|
gem.email = "thesp0nge@gmail.com"
|
24
28
|
gem.authors = ["Paolo Perego"]
|
25
29
|
gem.executables = ['ciphersurfer']
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0
|
1
|
+
1.0.0
|
data/bin/ciphersurfer
CHANGED
@@ -1,42 +1,59 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
|
3
3
|
require 'rainbow'
|
4
|
-
require '
|
5
|
-
require 'progressbar'
|
4
|
+
require 'ciphersurfer'
|
6
5
|
require 'getoptlong'
|
7
6
|
require 'json'
|
8
7
|
|
8
|
+
def score_to_color(score)
|
9
|
+
case score
|
10
|
+
when 1...40
|
11
|
+
return "red".to_sym
|
12
|
+
when 40...80
|
13
|
+
return "yellow".to_sym
|
14
|
+
when 80..100
|
15
|
+
return "green".to_sym
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
9
19
|
opts = GetoptLong.new(
|
10
20
|
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
11
21
|
[ '--version', '-v', GetoptLong::NO_ARGUMENT ],
|
12
|
-
[ '--list-ciphers', '-l', GetoptLong::NO_ARGUMENT ]
|
13
|
-
|
22
|
+
[ '--list-ciphers', '-l', GetoptLong::NO_ARGUMENT ],
|
23
|
+
[ '--json', '-j', GetoptLong::NO_ARGUMENT]
|
14
24
|
)
|
25
|
+
trap("INT") { puts '['+'INTERRUPTED'.color(:red)+']'; exit -1 }
|
15
26
|
|
16
27
|
options={:json=>false,:list_ciphers=>false}
|
17
28
|
|
18
29
|
opts.each do |opt, arg|
|
19
30
|
case opt
|
20
31
|
when '--help'
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
32
|
+
puts "usage: ciphersurfer [-ljvh] server[:port]"
|
33
|
+
puts " -l: lists supported ciphers instead of just evaluate the security level"
|
34
|
+
puts " -j: formats the output using JSON"
|
35
|
+
puts " -v: shows version"
|
36
|
+
puts " -h: this help"
|
26
37
|
exit 0
|
27
38
|
when '--version'
|
28
|
-
|
39
|
+
puts "ciphersurfer " + Ciphersurfer::Version::STRING
|
29
40
|
exit 0
|
30
|
-
|
31
|
-
|
32
|
-
# options[:json]=true
|
41
|
+
when '--json'
|
42
|
+
options[:json]=true
|
33
43
|
when '--list-ciphers'
|
34
44
|
options[:list_ciphers]=true
|
35
45
|
end
|
36
46
|
end
|
37
47
|
|
38
48
|
if ( ARGV.length != 1 )
|
39
|
-
|
49
|
+
puts 'missing target'.color(:red)
|
50
|
+
|
51
|
+
puts "usage: ciphersurfer [-ljvh] server[:port]"
|
52
|
+
puts " -l: lists supported ciphers instead of just evaluate the security level"
|
53
|
+
puts " -j: formats the output using JSON"
|
54
|
+
puts " -v: shows version"
|
55
|
+
puts " -h: this help"
|
56
|
+
|
40
57
|
exit -1
|
41
58
|
end
|
42
59
|
|
@@ -44,19 +61,17 @@ target = ARGV.shift
|
|
44
61
|
host = target.split(':')[0] ||= "localhost" #fallback here should never occur... however it's better to be paranoid
|
45
62
|
port = target.split(':')[1] ||= 443 # more common here
|
46
63
|
|
47
|
-
|
64
|
+
puts "Evaluating secure communication with #{host}:#{port}"
|
48
65
|
|
49
66
|
if ! Ciphersurfer::Scanner.alive?(host, port)
|
50
|
-
ap "it seems there is no server listening @#{host}:#{port}"
|
51
67
|
exit -2
|
52
68
|
end
|
53
69
|
|
54
70
|
protocol_version = [:SSLv2, :SSLv3, :TLSv1]#, :TLSv11, :TLSv12]
|
55
71
|
|
56
|
-
# ok = {}
|
57
72
|
supported_protocols = []
|
58
73
|
cipher_bits=[]
|
59
|
-
|
74
|
+
ciphers=[]
|
60
75
|
|
61
76
|
|
62
77
|
protocol_version.each do |version|
|
@@ -66,36 +81,48 @@ protocol_version.each do |version|
|
|
66
81
|
if (s.ok_ciphers.size != 0)
|
67
82
|
supported_protocols << version
|
68
83
|
cipher_bits = cipher_bits | s.ok_bits
|
84
|
+
ciphers = ciphers | s.ok_ciphers
|
69
85
|
end
|
70
|
-
|
71
|
-
# ok << {:proto=>version, :ciphers=>s.ok_ciphers}
|
72
86
|
|
73
87
|
end
|
74
88
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
cipher_score= Ciphersurfer::Score.evaluate_ciphers(cipher_bits)
|
82
|
-
key_score= Ciphersurfer::Score.evaluate_key(key_size.to_i)
|
83
|
-
score= Ciphersurfer::Score.score(proto_score, key_score, cipher_score)
|
84
|
-
ap Ciphersurfer::Score.evaluate(score) + " ("+score.to_s+")"
|
85
|
-
|
86
|
-
ap "Protocol support: " + proto_score.to_s
|
87
|
-
ap "Key exchange: " + key_score.to_s
|
88
|
-
ap "Cipher strength: " + cipher_score.to_s
|
89
|
-
|
89
|
+
if (options[:list_ciphers])
|
90
|
+
ciphers.each do |c|
|
91
|
+
puts "[+] accepted #{c}".green
|
92
|
+
end
|
93
|
+
exit 0
|
94
|
+
end
|
90
95
|
|
96
|
+
cert= Ciphersurfer::Scanner.cert(host, port)
|
97
|
+
if ! cert.nil?
|
98
|
+
a=cert.public_key.to_text
|
99
|
+
key_size=/Modulus \((\d+)/i.match(a)[1]
|
100
|
+
else
|
101
|
+
puts "warning: the server didn't give us the certificate".color(:yellow)
|
102
|
+
key_size=0
|
103
|
+
end
|
104
|
+
|
91
105
|
|
106
|
+
proto_score= Ciphersurfer::Score.evaluate_protocols(supported_protocols)
|
107
|
+
cipher_score= Ciphersurfer::Score.evaluate_ciphers(cipher_bits)
|
108
|
+
key_score= Ciphersurfer::Score.evaluate_key(key_size.to_i)
|
109
|
+
score= Ciphersurfer::Score.score(proto_score, key_score, cipher_score)
|
92
110
|
|
93
|
-
|
94
|
-
|
111
|
+
if (options[:json])
|
112
|
+
a={:evaluation => Ciphersurfer::Score.evaluate(score), :score => score, :protocol_score=>proto_score, :key_exchange_score=>key_score, :cipher_score=>cipher_score}
|
113
|
+
puts a.to_json
|
114
|
+
|
115
|
+
exit 0
|
116
|
+
end
|
95
117
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
118
|
+
printf "%20s : %s (%s)\n", "Overall evaluation", Ciphersurfer::Score.evaluate(score), score.to_s
|
119
|
+
printf "%20s : ", "Protocol support"
|
120
|
+
proto_score.to_i.times{print 'o'.color(score_to_color(proto_score))}
|
121
|
+
puts ' ('+proto_score.to_s+')'
|
122
|
+
printf "%20s : ", "Key exchange"
|
123
|
+
key_score.to_i.times{print 'o'.color(score_to_color(key_score))}
|
124
|
+
puts ' ('+key_score.to_s+')'
|
125
|
+
printf "%20s : ", "Cipher strength"
|
126
|
+
cipher_score.to_i.times{print 'o'.color(score_to_color(cipher_score))}
|
127
|
+
puts ' ('+cipher_score.to_s+')'
|
101
128
|
|
data/lib/ciphersurfer/scanner.rb
CHANGED
@@ -9,35 +9,58 @@ module Ciphersurfer
|
|
9
9
|
attr_reader :ok_ciphers, :ok_bits
|
10
10
|
attr_reader :peer_cert
|
11
11
|
|
12
|
+
|
13
|
+
|
12
14
|
def initialize(options={})
|
13
15
|
@host=options[:host]
|
14
16
|
@port=options[:port] ||= 443
|
15
17
|
@proto=options[:proto]
|
16
18
|
@ok_ciphers=[]
|
17
19
|
@ok_bits=[]
|
20
|
+
@alive=false
|
18
21
|
end
|
19
22
|
|
20
23
|
def self.cert(host, port)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
if (! @alive)
|
25
|
+
self.alive?(host.port)
|
26
|
+
end
|
27
|
+
|
28
|
+
@peer_cert
|
29
|
+
|
30
|
+
# client=HTTPClient.new
|
31
|
+
# response=client.get("https://#{host}:#{port}")
|
32
|
+
# peer_cert = response.peer_cert
|
24
33
|
end
|
25
34
|
|
26
35
|
def self.alive?(host, port)
|
27
|
-
|
28
|
-
request.use_ssl = true
|
29
|
-
request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
36
|
+
client=HTTPClient.new
|
30
37
|
begin
|
31
|
-
|
38
|
+
@alive=true
|
39
|
+
response=client.get("https://#{host}:#{port}")
|
40
|
+
@peer_cert = response.peer_cert
|
32
41
|
return true
|
33
|
-
rescue
|
34
|
-
|
35
|
-
rescue OpenSSL::SSL::SSLError => e
|
36
|
-
return false
|
37
|
-
rescue
|
42
|
+
rescue => e
|
43
|
+
puts "alive?(): #{e.message}".color(:red)
|
38
44
|
return false
|
39
45
|
end
|
46
|
+
|
40
47
|
end
|
48
|
+
|
49
|
+
# def self.alive?(host, port)
|
50
|
+
# request = Net::HTTP.new(host, port)
|
51
|
+
# request.use_ssl = true
|
52
|
+
# request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
53
|
+
# begin
|
54
|
+
# response = request.get("/")
|
55
|
+
# return true
|
56
|
+
# rescue Errno::ECONNREFUSED => e
|
57
|
+
# return false
|
58
|
+
# rescue OpenSSL::SSL::SSLError => e
|
59
|
+
# return false
|
60
|
+
# rescue
|
61
|
+
# return false
|
62
|
+
# end
|
63
|
+
# end
|
41
64
|
|
42
65
|
def go
|
43
66
|
context=OpenSSL::SSL::SSLContext.new(@proto)
|
@@ -46,14 +69,12 @@ module Ciphersurfer
|
|
46
69
|
|
47
70
|
request = Net::HTTP.new(@host, @port)
|
48
71
|
request.use_ssl = true
|
49
|
-
|
50
|
-
request.ca_file='/Users/thesp0nge/src/hacking/ciphersurfer/cacert.pem'
|
51
72
|
request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
52
73
|
request.ciphers= cipher_name
|
53
74
|
begin
|
54
75
|
response = request.get("/")
|
55
76
|
@ok_bits << bits
|
56
|
-
@ok_ciphers <<
|
77
|
+
@ok_ciphers << cipher_name
|
57
78
|
rescue OpenSSL::SSL::SSLError => e
|
58
79
|
# Quietly discard SSLErrors, really I don't care if the cipher has
|
59
80
|
# not been accepted
|
data/lib/ciphersurfer/score.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
module Ciphersurfer
|
2
|
-
PROTOCOL_SUPPORT_RATIO = 0.3
|
3
|
-
KEY_EXCHANGE_RATIO = 0.3
|
4
|
-
CIPHER_STRENGTH = 0.4
|
5
2
|
|
6
3
|
class Score
|
7
4
|
|
@@ -92,7 +89,6 @@ module Ciphersurfer
|
|
92
89
|
|
93
90
|
|
94
91
|
# FIXME: How can I test Weak key (Debian OpenSSL flaw)?
|
95
|
-
# FIXME: Evaluate if "Exportable key exchange limited to 512 bits is fully covered in k_len<1024
|
96
92
|
def self.evaluate_key(key_length)
|
97
93
|
case (key_length)
|
98
94
|
when 0
|
data/lib/ciphersurfer/version.rb
CHANGED
@@ -1,89 +1,10 @@
|
|
1
1
|
module Ciphersurfer
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
9
|
-
# If ciphersurfer is checked out from Git, the `:rev` key will have the revision hash.
|
10
|
-
#
|
11
|
-
# For example:
|
12
|
-
#
|
13
|
-
# {
|
14
|
-
# :string => "0.1.4.160676a",
|
15
|
-
# :rev => "160676ab8924ef36639c7e82aa88a51a24d16949",
|
16
|
-
# :number => "0.1.4",
|
17
|
-
# :major => 0, :minor => 1, :patch => 4
|
18
|
-
# }
|
19
|
-
#
|
20
|
-
# If a prerelease version of ciphersurfer is being used,
|
21
|
-
# the `:string` and `:number` fields will reflect the full version
|
22
|
-
# (e.g. `"1.0.beta.1"`), and the `:patch` field will be `-1`.
|
23
|
-
#
|
24
|
-
# A `:prerelease` key will contain the name of the prerelease (e.g. `"beta"`),
|
25
|
-
# and a `:prerelease_number` key will contain the rerelease number.
|
26
|
-
#
|
27
|
-
# For example:
|
28
|
-
#
|
29
|
-
# {
|
30
|
-
# :string => "1.0.beta.1",
|
31
|
-
# :number => "1.0.beta.1",
|
32
|
-
# :major => 1, :minor => 0, :patch => -1,
|
33
|
-
# :prerelease => "beta",
|
34
|
-
# :prerelease_number => 1
|
35
|
-
# }
|
36
|
-
#
|
37
|
-
# @return [{Symbol => String/Fixnum}] The version hash
|
38
|
-
def self.version
|
39
|
-
return @@version if defined?(@@version)
|
40
|
-
numbers = File.read('VERSION').strip.split('.').map {|n| n =~ /^[0-9]+$/ ? n.to_i : n}
|
41
|
-
@@version = {
|
42
|
-
:major => numbers[0],
|
43
|
-
:minor => numbers[1],
|
44
|
-
:patch => numbers[2]
|
45
|
-
}
|
46
|
-
if numbers[3].is_a?(String)
|
47
|
-
@@version[:patch] = -1
|
48
|
-
@@version[:prerelease] = numbers[3]
|
49
|
-
@@version[:prerelease_number] = numbers[4]
|
50
|
-
end
|
51
|
-
@@version[:number] = numbers.join('.')
|
52
|
-
@@version[:string] = @@version[:number].dup
|
53
|
-
|
54
|
-
rev = revision_number
|
55
|
-
@@version[:rev] = rev
|
56
|
-
unless rev[0] == ?(
|
57
|
-
@@version[:string] << "." << rev[0...7]
|
58
|
-
end
|
59
|
-
|
60
|
-
@@version
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.revision_number
|
64
|
-
if File.exists?('REVISION')
|
65
|
-
rev = File.read('REVISION').strip
|
66
|
-
return rev unless rev =~ /^([a-f0-9]+|\(.*\))$/ || rev == '(unknown)'
|
67
|
-
end
|
68
|
-
|
69
|
-
return unless File.exists?('.git/HEAD')
|
70
|
-
rev = File.read('.git/HEAD').strip
|
71
|
-
return rev unless rev =~ /^ref: (.*)$/
|
72
|
-
|
73
|
-
ref_name = $1
|
74
|
-
ref_file = "./.git/#{ref_name}"
|
75
|
-
info_file = "./.git/info/refs"
|
76
|
-
return File.read(ref_file).strip if File.exists?(ref_file)
|
77
|
-
return unless File.exists?(info_file)
|
78
|
-
File.open(info_file) do |f|
|
79
|
-
f.each do |l|
|
80
|
-
sha, ref = l.strip.split("\t", 2)
|
81
|
-
next unless ref == ref_name
|
82
|
-
return sha
|
83
|
-
end
|
84
|
-
end
|
85
|
-
return nil
|
86
|
-
end
|
87
|
-
|
2
|
+
module Version
|
3
|
+
MAJOR = 1
|
4
|
+
MINOR = 0
|
5
|
+
PATCH = 0
|
6
|
+
#BUILD = ''
|
7
|
+
#STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
|
8
|
+
STRING = [MAJOR, MINOR, PATCH].compact.join('.')
|
88
9
|
end
|
89
10
|
end
|
data/spec/scoring_spec.rb
CHANGED
@@ -40,22 +40,22 @@ describe 'Ciphersurfer' do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should give a 0.5 if both SSLv2 and SSLv3 are supported but no TLS" do
|
43
|
-
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :SSLv3]).should ==
|
43
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :SSLv3]).should == 50
|
44
44
|
end
|
45
45
|
it "should give a 0.2 if only SSLv2 protocol is supported" do
|
46
|
-
Ciphersurfer::Score.evaluate_protocols([:SSLv2]).should ==
|
46
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2]).should == 20
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should give a 0.55 if SSLv2 and TLSv1 are supported but no SSLv3" do
|
50
|
-
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :TLSv1]).should ==
|
50
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :TLSv1]).should == 55
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should give a 0.55 if SSLv2, SSLv3 and TLSv1 are supported" do
|
54
|
-
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :SSLv3, :TLSv1]).should ==
|
54
|
+
Ciphersurfer::Score.evaluate_protocols([:SSLv2, :SSLv3, :TLSv1]).should == 55
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should give a 1 if only TLSv1.2 is supported" do
|
58
|
-
Ciphersurfer::Score.evaluate_protocols([:TLSv12]).should ==
|
58
|
+
Ciphersurfer::Score.evaluate_protocols([:TLSv12]).should == 100
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should give a 0 if cipher has 0 length" do
|
@@ -63,27 +63,27 @@ describe 'Ciphersurfer' do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should give a 0.2 if ciphers supported have length < 128" do
|
66
|
-
Ciphersurfer::Score.evaluate_ciphers([40, 56, 64]).should ==
|
66
|
+
Ciphersurfer::Score.evaluate_ciphers([40, 56, 64]).should == 20
|
67
67
|
end
|
68
68
|
|
69
69
|
it "should give a 0.8 if ciphers supported have length < 256" do
|
70
|
-
Ciphersurfer::Score.evaluate_ciphers([128, 168, 255]).should ==
|
70
|
+
Ciphersurfer::Score.evaluate_ciphers([128, 168, 255]).should == 80
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should give a 1.0 if ciphers supported have length >= 256" do
|
74
|
-
Ciphersurfer::Score.evaluate_ciphers([256, 512, 2048]).should ==
|
74
|
+
Ciphersurfer::Score.evaluate_ciphers([256, 512, 2048]).should == 100
|
75
75
|
end
|
76
76
|
|
77
77
|
it "should give 0.1 if no encryption or ciphers lenght < 128" do
|
78
|
-
Ciphersurfer::Score.evaluate_ciphers([0, 40, 56, 64]).should ==
|
78
|
+
Ciphersurfer::Score.evaluate_ciphers([0, 40, 56, 64]).should == 10
|
79
79
|
end
|
80
80
|
|
81
81
|
it "should give a 0.5 if ciphers supported have length < 256 and < 128" do
|
82
|
-
Ciphersurfer::Score.evaluate_ciphers([40, 56, 128, 168, 255]).should ==
|
82
|
+
Ciphersurfer::Score.evaluate_ciphers([40, 56, 128, 168, 255]).should == 50
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should give a 0.6 if ciphers supported have length >= 256 and < 128" do
|
86
|
-
Ciphersurfer::Score.evaluate_ciphers([40, 56, 1024, 2048]).should ==
|
86
|
+
Ciphersurfer::Score.evaluate_ciphers([40, 56, 1024, 2048]).should == 60
|
87
87
|
end
|
88
88
|
|
89
89
|
it "should give a 0 if no key provided" do
|
@@ -91,41 +91,41 @@ describe 'Ciphersurfer' do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "should give a 0.2 if key < 512" do
|
94
|
-
Ciphersurfer::Score.evaluate_key(128).should ==
|
95
|
-
Ciphersurfer::Score.evaluate_key(256).should ==
|
96
|
-
Ciphersurfer::Score.evaluate_key(511).should ==
|
97
|
-
Ciphersurfer::Score.evaluate_key(512).should_not ==
|
94
|
+
Ciphersurfer::Score.evaluate_key(128).should == 20
|
95
|
+
Ciphersurfer::Score.evaluate_key(256).should == 20
|
96
|
+
Ciphersurfer::Score.evaluate_key(511).should == 20
|
97
|
+
Ciphersurfer::Score.evaluate_key(512).should_not == 20
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should give a 0.4 if 512 <= key < 1024" do
|
101
|
-
Ciphersurfer::Score.evaluate_key(512).should ==
|
102
|
-
Ciphersurfer::Score.evaluate_key(1000).should ==
|
103
|
-
Ciphersurfer::Score.evaluate_key(1024).should_not ==
|
101
|
+
Ciphersurfer::Score.evaluate_key(512).should == 40
|
102
|
+
Ciphersurfer::Score.evaluate_key(1000).should == 40
|
103
|
+
Ciphersurfer::Score.evaluate_key(1024).should_not == 40
|
104
104
|
end
|
105
105
|
|
106
106
|
it "should give a 0.8 if 1024 <= key < 2048" do
|
107
|
-
Ciphersurfer::Score.evaluate_key(1024).should ==
|
108
|
-
Ciphersurfer::Score.evaluate_key(2043).should ==
|
109
|
-
Ciphersurfer::Score.evaluate_key(2048).should_not ==
|
107
|
+
Ciphersurfer::Score.evaluate_key(1024).should == 80
|
108
|
+
Ciphersurfer::Score.evaluate_key(2043).should == 80
|
109
|
+
Ciphersurfer::Score.evaluate_key(2048).should_not == 80
|
110
110
|
end
|
111
111
|
|
112
112
|
it "should give a 0.9 if 2048 <= key < 4096" do
|
113
|
-
Ciphersurfer::Score.evaluate_key(2048).should ==
|
114
|
-
Ciphersurfer::Score.evaluate_key(4095).should ==
|
115
|
-
Ciphersurfer::Score.evaluate_key(4096).should_not ==
|
113
|
+
Ciphersurfer::Score.evaluate_key(2048).should == 90
|
114
|
+
Ciphersurfer::Score.evaluate_key(4095).should == 90
|
115
|
+
Ciphersurfer::Score.evaluate_key(4096).should_not == 90
|
116
116
|
end
|
117
117
|
|
118
118
|
it "should give a 1.0 if key >= 4096" do
|
119
|
-
Ciphersurfer::Score.evaluate_key(4096).should ==
|
119
|
+
Ciphersurfer::Score.evaluate_key(4096).should == 100
|
120
120
|
end
|
121
121
|
|
122
122
|
|
123
123
|
it "should evalute the overall score" do
|
124
|
-
Ciphersurfer::Score.score(
|
125
|
-
Ciphersurfer::Score.score(
|
126
|
-
Ciphersurfer::Score.score(
|
127
|
-
Ciphersurfer::Score.score(
|
128
|
-
Ciphersurfer::Score.score(
|
124
|
+
Ciphersurfer::Score.score(100, 100, 100).should == 100
|
125
|
+
Ciphersurfer::Score.score(0, 100, 100).should == 70
|
126
|
+
Ciphersurfer::Score.score(100, 0, 100).should == 70
|
127
|
+
Ciphersurfer::Score.score(100, 100, 0).should == 60
|
128
|
+
Ciphersurfer::Score.score(0, 0, 100).should == 40
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ciphersurfer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Paolo Perego
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-31 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rainbow
|
16
|
-
requirement: &
|
16
|
+
requirement: &70151800022700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,32 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: progressbar
|
27
|
-
requirement: &70292333332820 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ! '>='
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '0'
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *70292333332820
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: awesome_print
|
38
|
-
requirement: &70292333332280 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
|
-
requirements:
|
41
|
-
- - ! '>='
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: '0'
|
44
|
-
type: :runtime
|
45
|
-
prerelease: false
|
46
|
-
version_requirements: *70292333332280
|
24
|
+
version_requirements: *70151800022700
|
47
25
|
- !ruby/object:Gem::Dependency
|
48
26
|
name: json
|
49
|
-
requirement: &
|
27
|
+
requirement: &70151800022200 !ruby/object:Gem::Requirement
|
50
28
|
none: false
|
51
29
|
requirements:
|
52
30
|
- - ! '>='
|
@@ -54,10 +32,10 @@ dependencies:
|
|
54
32
|
version: '0'
|
55
33
|
type: :runtime
|
56
34
|
prerelease: false
|
57
|
-
version_requirements: *
|
35
|
+
version_requirements: *70151800022200
|
58
36
|
- !ruby/object:Gem::Dependency
|
59
37
|
name: httpclient
|
60
|
-
requirement: &
|
38
|
+
requirement: &70151800021680 !ruby/object:Gem::Requirement
|
61
39
|
none: false
|
62
40
|
requirements:
|
63
41
|
- - ! '>='
|
@@ -65,10 +43,10 @@ dependencies:
|
|
65
43
|
version: '0'
|
66
44
|
type: :runtime
|
67
45
|
prerelease: false
|
68
|
-
version_requirements: *
|
46
|
+
version_requirements: *70151800021680
|
69
47
|
- !ruby/object:Gem::Dependency
|
70
48
|
name: rspec
|
71
|
-
requirement: &
|
49
|
+
requirement: &70151800021200 !ruby/object:Gem::Requirement
|
72
50
|
none: false
|
73
51
|
requirements:
|
74
52
|
- - ~>
|
@@ -76,10 +54,10 @@ dependencies:
|
|
76
54
|
version: 2.3.0
|
77
55
|
type: :development
|
78
56
|
prerelease: false
|
79
|
-
version_requirements: *
|
57
|
+
version_requirements: *70151800021200
|
80
58
|
- !ruby/object:Gem::Dependency
|
81
59
|
name: bundler
|
82
|
-
requirement: &
|
60
|
+
requirement: &70151800020700 !ruby/object:Gem::Requirement
|
83
61
|
none: false
|
84
62
|
requirements:
|
85
63
|
- - ~>
|
@@ -87,10 +65,10 @@ dependencies:
|
|
87
65
|
version: 1.0.0
|
88
66
|
type: :development
|
89
67
|
prerelease: false
|
90
|
-
version_requirements: *
|
68
|
+
version_requirements: *70151800020700
|
91
69
|
- !ruby/object:Gem::Dependency
|
92
70
|
name: jeweler
|
93
|
-
requirement: &
|
71
|
+
requirement: &70151800020200 !ruby/object:Gem::Requirement
|
94
72
|
none: false
|
95
73
|
requirements:
|
96
74
|
- - ~>
|
@@ -98,10 +76,10 @@ dependencies:
|
|
98
76
|
version: 1.6.4
|
99
77
|
type: :development
|
100
78
|
prerelease: false
|
101
|
-
version_requirements: *
|
79
|
+
version_requirements: *70151800020200
|
102
80
|
- !ruby/object:Gem::Dependency
|
103
81
|
name: rcov
|
104
|
-
requirement: &
|
82
|
+
requirement: &70151800019680 !ruby/object:Gem::Requirement
|
105
83
|
none: false
|
106
84
|
requirements:
|
107
85
|
- - ! '>='
|
@@ -109,22 +87,21 @@ dependencies:
|
|
109
87
|
version: '0'
|
110
88
|
type: :development
|
111
89
|
prerelease: false
|
112
|
-
version_requirements: *
|
113
|
-
description: ciphersurfer is a security tool that
|
114
|
-
HTTP connection
|
90
|
+
version_requirements: *70151800019680
|
91
|
+
description: ciphersurfer is a security tool that evaluates web server SSL configuration
|
115
92
|
email: thesp0nge@gmail.com
|
116
93
|
executables:
|
117
94
|
- ciphersurfer
|
118
95
|
extensions: []
|
119
96
|
extra_rdoc_files:
|
120
|
-
- LICENSE
|
97
|
+
- LICENSE.txt
|
121
98
|
- README.md
|
122
99
|
files:
|
123
100
|
- .document
|
124
101
|
- .rspec
|
125
102
|
- Gemfile
|
126
103
|
- Gemfile.lock
|
127
|
-
- LICENSE
|
104
|
+
- LICENSE.txt
|
128
105
|
- README.md
|
129
106
|
- Rakefile
|
130
107
|
- VERSION
|
@@ -151,17 +128,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
128
|
version: '0'
|
152
129
|
segments:
|
153
130
|
- 0
|
154
|
-
hash: -
|
131
|
+
hash: -144423805926763558
|
155
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
133
|
none: false
|
157
134
|
requirements:
|
158
|
-
- - ! '
|
135
|
+
- - ! '>='
|
159
136
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
137
|
+
version: '0'
|
161
138
|
requirements: []
|
162
139
|
rubyforge_project:
|
163
140
|
rubygems_version: 1.8.10
|
164
141
|
signing_key:
|
165
142
|
specification_version: 3
|
166
|
-
summary:
|
143
|
+
summary: evaluates web server SSL configuration
|
167
144
|
test_files: []
|