metasploit_data_models 0.16.6-java → 0.16.7-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,6 +5,8 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
5
5
  changeme test1234 rapid7
6
6
  }
7
7
 
8
+ SPECIAL_CHARS = %q{!@"#$%&'()*+,-./:;<=>?[\\]^_`{|}~ }
9
+
8
10
  def validate_each(record, attribute, value)
9
11
  return if value.blank?
10
12
 
@@ -28,7 +30,7 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
28
30
  private
29
31
 
30
32
  def is_simple?(password)
31
- not (password =~ /[A-Za-z]/ and password =~ /[0-9]/ and password =~ /[\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5c\x5d\x5e\x5f\x60\x7b\x7c\x7d\x7e]/)
33
+ not (password =~ /[A-Za-z]/ and password =~ /[0-9]/ and password =~ /[#{Regexp.escape(SPECIAL_CHARS)}]/)
32
34
  end
33
35
 
34
36
  def contains_username?(username, password)
@@ -37,14 +39,50 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
37
39
 
38
40
  def is_common_password?(password)
39
41
  COMMON_PASSWORDS.each do |pw|
40
- common_pw = [pw, pw + "!", pw + "1", pw + "12", pw + "123", pw + "1234"]
41
- if common_pw.include?(password.downcase)
42
- return true
42
+ common_pw = [pw] # pw + "!", pw + "1", pw + "12", pw + "123", pw + "1234"]
43
+ common_pw += mutate_pass(pw)
44
+ common_pw.each do |common_pass|
45
+ if password.downcase =~ /#{common_pass}[\d!]*/
46
+ return true
47
+ end
43
48
  end
44
49
  end
45
50
  false
46
51
  end
47
52
 
53
+ def mutate_pass(password)
54
+ mutations = {
55
+ 'a' => '@',
56
+ 'o' => '0',
57
+ 'e' => '3',
58
+ 's' => '$',
59
+ 't' => '7',
60
+ 'l' => '1'
61
+ }
62
+
63
+ iterations = mutations.keys.dup
64
+ results = []
65
+
66
+ # Find PowerSet of all possible mutation combinations
67
+ iterations = iterations.inject([[]]){|c,y|r=[];c.each{|i|r<<i;r<<i+[y]};r}
68
+
69
+ # Iterate through combinations to create each possible mutation
70
+ iterations.each do |iteration|
71
+ next if iteration.flatten.empty?
72
+ first = iteration.shift
73
+ intermediate = password.gsub(/#{first}/i, mutations[first])
74
+ iteration.each do |mutator|
75
+ next unless mutator.kind_of? String
76
+ intermediate.gsub!(/#{mutator}/i, mutations[mutator])
77
+ end
78
+ results << intermediate
79
+ end
80
+
81
+ return results
82
+ end
83
+
84
+
85
+
48
86
  def contains_repetition?(password)
49
87
  # Password repetition (quite basic) -- no "aaaaaa" or "ababab" or "abcabc" or
50
88
  # "abcdabcd" (but note that the user can use "aaaaaab" or something).
@@ -4,5 +4,5 @@ module MetasploitDataModels
4
4
  # metasploit-framework/data/sql/migrate to db/migrate in this project, not all models have specs that verify the
5
5
  # migrations (with have_db_column and have_db_index) and certain models may not be shared between metasploit-framework
6
6
  # and pro, so models may be removed in the future. Because of the unstable API the version should remain below 1.0.0
7
- VERSION = '0.16.6'
7
+ VERSION = '0.16.7'
8
8
  end
@@ -0,0 +1,324 @@
1
+ require 'spec_helper'
2
+
3
+ describe PasswordIsStrongValidator do
4
+
5
+ subject(:password_validator) do
6
+ described_class.new(
7
+ :attributes => attributes
8
+ )
9
+ end
10
+
11
+ let(:attribute) do
12
+ :params
13
+ end
14
+
15
+ let(:attributes) do
16
+ attribute
17
+ end
18
+
19
+
20
+ context '#contains_repetition?' do
21
+
22
+ it 'should return true for aaaa' do
23
+ password_validator.send(:contains_repetition?, 'aaaa').should be_true
24
+ end
25
+
26
+ it 'should return true for ababab' do
27
+ password_validator.send(:contains_repetition?, 'ababab').should be_true
28
+ end
29
+
30
+ it 'should return true for abcabcabc' do
31
+ password_validator.send(:contains_repetition?, 'abcabcabc').should be_true
32
+ end
33
+
34
+ it 'should return true for abcdabcd' do
35
+ password_validator.send(:contains_repetition?, 'abcdabcd').should be_true
36
+ end
37
+
38
+ it 'should return false for abcd1234abcd' do
39
+ password_validator.send(:contains_repetition?, 'abcd1234abcd').should be_false
40
+ end
41
+
42
+ end
43
+
44
+
45
+
46
+ context '#mutate_pass' do
47
+
48
+ variants = [
49
+ "metasp1oit",
50
+ "me7asploi7",
51
+ "me7asp1oi7",
52
+ "meta$ploit",
53
+ "meta$p1oit",
54
+ "me7a$ploi7",
55
+ "me7a$p1oi7",
56
+ "m3tasploit",
57
+ "m3tasp1oit",
58
+ "m37asploi7",
59
+ "m37asp1oi7",
60
+ "m3ta$ploit",
61
+ "m3ta$p1oit",
62
+ "m37a$ploi7",
63
+ "m37a$p1oi7",
64
+ "metaspl0it",
65
+ "metasp10it",
66
+ "me7aspl0i7",
67
+ "me7asp10i7",
68
+ "meta$pl0it",
69
+ "meta$p10it",
70
+ "me7a$pl0i7",
71
+ "me7a$p10i7",
72
+ "m3taspl0it",
73
+ "m3tasp10it",
74
+ "m37aspl0i7",
75
+ "m37asp10i7",
76
+ "m3ta$pl0it",
77
+ "m3ta$p10it",
78
+ "m37a$pl0i7",
79
+ "m37a$p10i7",
80
+ "met@sploit",
81
+ "met@sp1oit",
82
+ "me7@sploi7",
83
+ "me7@sp1oi7",
84
+ "met@$ploit",
85
+ "met@$p1oit",
86
+ "me7@$ploi7",
87
+ "me7@$p1oi7",
88
+ "m3t@sploit",
89
+ "m3t@sp1oit",
90
+ "m37@sploi7",
91
+ "m37@sp1oi7",
92
+ "m3t@$ploit",
93
+ "m3t@$p1oit",
94
+ "m37@$ploi7",
95
+ "m37@$p1oi7",
96
+ "met@spl0it",
97
+ "met@sp10it",
98
+ "me7@spl0i7",
99
+ "me7@sp10i7",
100
+ "met@$pl0it",
101
+ "met@$p10it",
102
+ "me7@$pl0i7",
103
+ "me7@$p10i7",
104
+ "m3t@spl0it",
105
+ "m3t@sp10it",
106
+ "m37@spl0i7",
107
+ "m37@sp10i7",
108
+ "m3t@$pl0it",
109
+ "m3t@$p10it",
110
+ "m37@$pl0i7",
111
+ "m37@$p10i7"
112
+ ]
113
+
114
+ it 'should return all the expected mutations of a password' do
115
+ password_validator.send(:mutate_pass, 'metasploit').should == variants
116
+ end
117
+
118
+ end
119
+
120
+
121
+ context '#is_common_password?' do
122
+
123
+ PasswordIsStrongValidator::COMMON_PASSWORDS.each do |password|
124
+
125
+ it "should return true for #{password}" do
126
+ password_validator.send(:is_common_password?, password).should be_true
127
+ end
128
+
129
+ it "should return true for #{password}!" do
130
+ password_validator.send(:is_common_password?, "#{password}!").should be_true
131
+ end
132
+
133
+ it "should return true for #{password}1" do
134
+ password_validator.send(:is_common_password?, "#{password}1").should be_true
135
+ end
136
+
137
+ it "should return true for #{password}9" do
138
+ password_validator.send(:is_common_password?, "#{password}1").should be_true
139
+ end
140
+
141
+ it "should return true for #{password}99" do
142
+ password_validator.send(:is_common_password?, "#{password}12").should be_true
143
+ end
144
+
145
+ it "should return true for #{password}123" do
146
+ password_validator.send(:is_common_password?, "#{password}123").should be_true
147
+ end
148
+
149
+ it "should return true for #{password}123!" do
150
+ password_validator.send(:is_common_password?, "#{password}123!").should be_true
151
+ end
152
+
153
+ end
154
+
155
+ it "should return true for r00t" do
156
+ password_validator.send(:is_common_password?, "r00t").should be_true
157
+ end
158
+
159
+ it "should return true for m3t@spl0it" do
160
+ password_validator.send(:is_common_password?, "m3t@spl0it").should be_true
161
+ end
162
+
163
+ it "should return true for m3t@spl0it123!" do
164
+ password_validator.send(:is_common_password?, "m3t@spl0it123!").should be_true
165
+ end
166
+ end
167
+
168
+ context '#contains_username' do
169
+
170
+ it 'should return true if username and password are the same' do
171
+ password_validator.send(:contains_username?, 'admin', 'admin').should be_true
172
+ end
173
+
174
+ it 'should return true if the password contains the username as part of it' do
175
+ password_validator.send(:contains_username?, 'admin', '123admin123').should be_true
176
+ end
177
+
178
+ it 'should return false otherwise' do
179
+ password_validator.send(:contains_username?, 'admin', 'foobar').should be_false
180
+ end
181
+ end
182
+
183
+ context '#is_simple?' do
184
+
185
+ it "should return true if no number" do
186
+ password_validator.send(:is_simple?, "b@carat").should be_true
187
+ end
188
+
189
+ it "should return true if no special char" do
190
+ password_validator.send(:is_simple?, "bacarat4").should be_true
191
+ end
192
+
193
+ it "should return true if no letters" do
194
+ password_validator.send(:is_simple?, "1337").should be_true
195
+ end
196
+
197
+ PasswordIsStrongValidator::SPECIAL_CHARS.each_char do |char|
198
+
199
+ it "should return false with a #{char}" do
200
+ password_validator.send(:is_simple?, "bacarat4#{char}").should be_false
201
+ end
202
+ end
203
+ end
204
+
205
+ context '#validate_each' do
206
+
207
+ subject(:errors) do
208
+ record.errors[attribute]
209
+ end
210
+
211
+ def validate_each
212
+ password_validator.validate_each(record, attribute, value)
213
+ end
214
+
215
+ let(:record) do
216
+ Object.new.tap { |object|
217
+ object.extend ActiveModel::Validations
218
+ object.class.module_eval { attr_accessor :username }
219
+ object.username = 'admin'
220
+ }
221
+ end
222
+
223
+
224
+ context 'with a password with no special char' do
225
+ let(:value) { "bacarat4" }
226
+
227
+ it 'should record an error' do
228
+ validate_each
229
+ errors.should_not be_empty
230
+ end
231
+
232
+ it 'should have an error of "must contain letters, numbers, and at least one special character"' do
233
+ validate_each
234
+ errors.include?("must contain letters, numbers, and at least one special character").should be_true
235
+ end
236
+ end
237
+
238
+ context 'with a password with no numbers' do
239
+ let(:value) { "b@carat" }
240
+
241
+ it 'should record an error' do
242
+ validate_each
243
+ errors.should_not be_empty
244
+ end
245
+
246
+ it 'should have an error of "must contain letters, numbers, and at least one special character"' do
247
+ validate_each
248
+ errors.include?("must contain letters, numbers, and at least one special character").should be_true
249
+ end
250
+ end
251
+
252
+ context 'with a password with no letters' do
253
+ let(:value) { "1337@" }
254
+
255
+ it 'should record an error' do
256
+ validate_each
257
+ errors.should_not be_empty
258
+ end
259
+
260
+ it 'should have an error of "must contain letters, numbers, and at least one special character"' do
261
+ validate_each
262
+ errors.include?("must contain letters, numbers, and at least one special character").should be_true
263
+ end
264
+ end
265
+
266
+ context 'with a password containing the username' do
267
+ let(:value) { "admin1" }
268
+
269
+ it 'should record an error' do
270
+ validate_each
271
+ errors.should_not be_empty
272
+ end
273
+
274
+ it 'should have an error of "must not contain the username"' do
275
+ validate_each
276
+ errors.include?("must not contain the username").should be_true
277
+ end
278
+ end
279
+
280
+ context 'with a common password' do
281
+ let(:value) { "password" }
282
+
283
+ it 'should record an error' do
284
+ validate_each
285
+ errors.should_not be_empty
286
+ end
287
+
288
+ it 'should have an error of "must not be a common password"' do
289
+ validate_each
290
+ errors.include?("must not be a common password").should be_true
291
+ end
292
+ end
293
+
294
+ context 'with a mutated common password' do
295
+ let(:value) { "P@ssw0rd1!" }
296
+
297
+ it 'should record an error' do
298
+ validate_each
299
+ errors.should_not be_empty
300
+ end
301
+
302
+ it 'should have an error of "must not be a common password"' do
303
+ validate_each
304
+ errors.include?("must not be a common password").should be_true
305
+ end
306
+ end
307
+
308
+ context 'with a repeated pattern' do
309
+ let(:value) { "abcdabcd" }
310
+
311
+ it 'should record an error' do
312
+ validate_each
313
+ errors.should_not be_empty
314
+ end
315
+
316
+ it 'should have an error of "must not be a predictable sequence of characters"' do
317
+ validate_each
318
+ errors.include?("must not be a predictable sequence of characters").should be_true
319
+ end
320
+ end
321
+
322
+ end
323
+
324
+ end
@@ -6,7 +6,7 @@ FactoryGirl.define do
6
6
  association :web_site, :factory => :mdm_web_site
7
7
 
8
8
  trait :exported do
9
- method { generate :mdm_web_form_method }
9
+ add_attribute(:method) { generate :mdm_web_form_method }
10
10
  params { generate :mdm_web_form_params }
11
11
  path { generate :mdm_web_form_path }
12
12
  end
@@ -20,10 +20,10 @@ FactoryGirl.define do
20
20
 
21
21
  sequence :mdm_web_form_params do |n|
22
22
  [
23
- [
24
- "name#{n}",
25
- "value#{n}"
26
- ]
23
+ [
24
+ "name#{n}",
25
+ "value#{n}"
26
+ ]
27
27
  ]
28
28
  end
29
29
 
@@ -11,7 +11,7 @@ FactoryGirl.define do
11
11
 
12
12
  category { generate :mdm_web_vuln_category }
13
13
  confidence { generate :mdm_web_vuln_confidence }
14
- method { generate :mdm_web_vuln_method }
14
+ add_attribute(:method) { generate :mdm_web_vuln_method }
15
15
  name { generate :mdm_web_vuln_name }
16
16
  path { generate :mdm_web_vuln_path }
17
17
  params { generate :mdm_web_vuln_params }
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: metasploit_data_models
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.16.6
5
+ version: 0.16.7
6
6
  platform: java
7
7
  authors:
8
8
  - Samuel Huckins
@@ -12,23 +12,21 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-08-14 00:00:00.000000000 Z
15
+ date: 2013-11-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rake
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ">="
21
+ - - '>='
22
22
  - !ruby/object:Gem::Version
23
- version: !binary |-
24
- MA==
23
+ version: '0'
25
24
  none: false
26
25
  requirement: !ruby/object:Gem::Requirement
27
26
  requirements:
28
- - - ">="
27
+ - - '>='
29
28
  - !ruby/object:Gem::Version
30
- version: !binary |-
31
- MA==
29
+ version: '0'
32
30
  none: false
33
31
  prerelease: false
34
32
  type: :development
@@ -36,17 +34,15 @@ dependencies:
36
34
  name: yard
37
35
  version_requirements: !ruby/object:Gem::Requirement
38
36
  requirements:
39
- - - ">="
37
+ - - '>='
40
38
  - !ruby/object:Gem::Version
41
- version: !binary |-
42
- MA==
39
+ version: '0'
43
40
  none: false
44
41
  requirement: !ruby/object:Gem::Requirement
45
42
  requirements:
46
- - - ">="
43
+ - - '>='
47
44
  - !ruby/object:Gem::Version
48
- version: !binary |-
49
- MA==
45
+ version: '0'
50
46
  none: false
51
47
  prerelease: false
52
48
  type: :development
@@ -54,17 +50,15 @@ dependencies:
54
50
  name: pry
55
51
  version_requirements: !ruby/object:Gem::Requirement
56
52
  requirements:
57
- - - ">="
53
+ - - '>='
58
54
  - !ruby/object:Gem::Version
59
- version: !binary |-
60
- MA==
55
+ version: '0'
61
56
  none: false
62
57
  requirement: !ruby/object:Gem::Requirement
63
58
  requirements:
64
- - - ">="
59
+ - - '>='
65
60
  - !ruby/object:Gem::Version
66
- version: !binary |-
67
- MA==
61
+ version: '0'
68
62
  none: false
69
63
  prerelease: false
70
64
  type: :development
@@ -72,13 +66,13 @@ dependencies:
72
66
  name: activerecord
73
67
  version_requirements: !ruby/object:Gem::Requirement
74
68
  requirements:
75
- - - ">="
69
+ - - '>='
76
70
  - !ruby/object:Gem::Version
77
71
  version: 3.2.13
78
72
  none: false
79
73
  requirement: !ruby/object:Gem::Requirement
80
74
  requirements:
81
- - - ">="
75
+ - - '>='
82
76
  - !ruby/object:Gem::Version
83
77
  version: 3.2.13
84
78
  none: false
@@ -88,17 +82,15 @@ dependencies:
88
82
  name: activesupport
89
83
  version_requirements: !ruby/object:Gem::Requirement
90
84
  requirements:
91
- - - ">="
85
+ - - '>='
92
86
  - !ruby/object:Gem::Version
93
- version: !binary |-
94
- MA==
87
+ version: '0'
95
88
  none: false
96
89
  requirement: !ruby/object:Gem::Requirement
97
90
  requirements:
98
- - - ">="
91
+ - - '>='
99
92
  - !ruby/object:Gem::Version
100
- version: !binary |-
101
- MA==
93
+ version: '0'
102
94
  none: false
103
95
  prerelease: false
104
96
  type: :runtime
@@ -106,17 +98,15 @@ dependencies:
106
98
  name: kramdown
107
99
  version_requirements: !ruby/object:Gem::Requirement
108
100
  requirements:
109
- - - ">="
101
+ - - '>='
110
102
  - !ruby/object:Gem::Version
111
- version: !binary |-
112
- MA==
103
+ version: '0'
113
104
  none: false
114
105
  requirement: !ruby/object:Gem::Requirement
115
106
  requirements:
116
- - - ">="
107
+ - - '>='
117
108
  - !ruby/object:Gem::Version
118
- version: !binary |-
119
- MA==
109
+ version: '0'
120
110
  none: false
121
111
  prerelease: false
122
112
  type: :development
@@ -124,17 +114,15 @@ dependencies:
124
114
  name: jdbc-postgres
125
115
  version_requirements: !ruby/object:Gem::Requirement
126
116
  requirements:
127
- - - ">="
117
+ - - '>='
128
118
  - !ruby/object:Gem::Version
129
- version: !binary |-
130
- MA==
119
+ version: '0'
131
120
  none: false
132
121
  requirement: !ruby/object:Gem::Requirement
133
122
  requirements:
134
- - - ">="
123
+ - - '>='
135
124
  - !ruby/object:Gem::Version
136
- version: !binary |-
137
- MA==
125
+ version: '0'
138
126
  none: false
139
127
  prerelease: false
140
128
  type: :runtime
@@ -142,17 +130,15 @@ dependencies:
142
130
  name: activerecord-jdbcpostgresql-adapter
143
131
  version_requirements: !ruby/object:Gem::Requirement
144
132
  requirements:
145
- - - ">="
133
+ - - '>='
146
134
  - !ruby/object:Gem::Version
147
- version: !binary |-
148
- MA==
135
+ version: '0'
149
136
  none: false
150
137
  requirement: !ruby/object:Gem::Requirement
151
138
  requirements:
152
- - - ">="
139
+ - - '>='
153
140
  - !ruby/object:Gem::Version
154
- version: !binary |-
155
- MA==
141
+ version: '0'
156
142
  none: false
157
143
  prerelease: false
158
144
  type: :runtime
@@ -167,11 +153,11 @@ executables:
167
153
  extensions: []
168
154
  extra_rdoc_files: []
169
155
  files:
170
- - ".gitignore"
171
- - ".rspec"
172
- - ".simplecov"
173
- - ".travis.yml"
174
- - ".yardopts"
156
+ - .gitignore
157
+ - .rspec
158
+ - .simplecov
159
+ - .travis.yml
160
+ - .yardopts
175
161
  - Gemfile
176
162
  - LICENSE
177
163
  - README.md
@@ -395,6 +381,7 @@ files:
395
381
  - spec/app/models/mdm/web_vuln_spec.rb
396
382
  - spec/app/models/mdm/workspace_spec.rb
397
383
  - spec/app/validators/parameters_validator_spec.rb
384
+ - spec/app/validators/password_is_strong_validator_spec.rb
398
385
  - spec/dummy/Rakefile
399
386
  - spec/dummy/app/assets/javascripts/application.js
400
387
  - spec/dummy/app/assets/stylesheets/application.css
@@ -488,23 +475,21 @@ require_paths:
488
475
  - lib
489
476
  required_ruby_version: !ruby/object:Gem::Requirement
490
477
  requirements:
491
- - - ">="
478
+ - - '>='
492
479
  - !ruby/object:Gem::Version
493
480
  segments:
494
481
  - 0
495
482
  hash: 2
496
- version: !binary |-
497
- MA==
483
+ version: '0'
498
484
  none: false
499
485
  required_rubygems_version: !ruby/object:Gem::Requirement
500
486
  requirements:
501
- - - ">="
487
+ - - '>='
502
488
  - !ruby/object:Gem::Version
503
489
  segments:
504
490
  - 0
505
491
  hash: 2
506
- version: !binary |-
507
- MA==
492
+ version: '0'
508
493
  none: false
509
494
  requirements: []
510
495
  rubyforge_project:
@@ -557,6 +542,7 @@ test_files:
557
542
  - spec/app/models/mdm/web_vuln_spec.rb
558
543
  - spec/app/models/mdm/workspace_spec.rb
559
544
  - spec/app/validators/parameters_validator_spec.rb
545
+ - spec/app/validators/password_is_strong_validator_spec.rb
560
546
  - spec/dummy/Rakefile
561
547
  - spec/dummy/app/assets/javascripts/application.js
562
548
  - spec/dummy/app/assets/stylesheets/application.css