metasploit_data_models 0.16.6 → 0.16.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTAzNmVjZDU3NmE5MDQxYTBlZjUwODM3NzJkNmJhM2I2YWNhZTMxZA==
5
+ data.tar.gz: !binary |-
6
+ M2EwYjkyNTA1ZjRlMGQxMDZmYTQ1MGVmYmFjYmVhNGU4ODc3MzgzOA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ N2Y2MjIwNTg3NzY5MTU1YjVjNjYxMjQ1MjFkMTBjNDUwYWMxNWQ5ZGE2MTVm
10
+ YWU1ZmRiNjEyZWJmNTkyOTliMGRjMTE5NzM0YjBlMjliYWFmOGJiZjgyYmQx
11
+ ZWI4NTBiMWIwMDFkOTE4ZDVjODFhNzRlMDJiMDk2ZjkyODM2OTE=
12
+ data.tar.gz: !binary |-
13
+ ZDJhMDYyOTQwOTI3YzI2N2E4NDM5NDFlOWUwMGFkYTQzYTIyNWJiODQyZmUx
14
+ NTFiN2NkOWMxMjk1ODIzNjVkNDAxYWZhMzFiYTA5MjRmMmJlY2QxMmNhY2Iy
15
+ MzE0OTQ2ZjRkMmMyMWJiMTkwM2RmYjFiZGMxODU1MWQzMGMyZmQ=
@@ -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
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit_data_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.6
5
- prerelease:
4
+ version: 0.16.7
6
5
  platform: ruby
7
6
  authors:
8
7
  - Samuel Huckins
@@ -12,12 +11,11 @@ authors:
12
11
  autorequire:
13
12
  bindir: bin
14
13
  cert_chain: []
15
- date: 2013-08-14 00:00:00.000000000 Z
14
+ date: 2013-11-20 00:00:00.000000000 Z
16
15
  dependencies:
17
16
  - !ruby/object:Gem::Dependency
18
17
  name: rake
19
18
  requirement: !ruby/object:Gem::Requirement
20
- none: false
21
19
  requirements:
22
20
  - - ! '>='
23
21
  - !ruby/object:Gem::Version
@@ -25,7 +23,6 @@ dependencies:
25
23
  type: :development
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
27
  - - ! '>='
31
28
  - !ruby/object:Gem::Version
@@ -33,7 +30,6 @@ dependencies:
33
30
  - !ruby/object:Gem::Dependency
34
31
  name: yard
35
32
  requirement: !ruby/object:Gem::Requirement
36
- none: false
37
33
  requirements:
38
34
  - - ! '>='
39
35
  - !ruby/object:Gem::Version
@@ -41,7 +37,6 @@ dependencies:
41
37
  type: :development
42
38
  prerelease: false
43
39
  version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
40
  requirements:
46
41
  - - ! '>='
47
42
  - !ruby/object:Gem::Version
@@ -49,7 +44,6 @@ dependencies:
49
44
  - !ruby/object:Gem::Dependency
50
45
  name: pry
51
46
  requirement: !ruby/object:Gem::Requirement
52
- none: false
53
47
  requirements:
54
48
  - - ! '>='
55
49
  - !ruby/object:Gem::Version
@@ -57,7 +51,6 @@ dependencies:
57
51
  type: :development
58
52
  prerelease: false
59
53
  version_requirements: !ruby/object:Gem::Requirement
60
- none: false
61
54
  requirements:
62
55
  - - ! '>='
63
56
  - !ruby/object:Gem::Version
@@ -65,7 +58,6 @@ dependencies:
65
58
  - !ruby/object:Gem::Dependency
66
59
  name: activerecord
67
60
  requirement: !ruby/object:Gem::Requirement
68
- none: false
69
61
  requirements:
70
62
  - - ! '>='
71
63
  - !ruby/object:Gem::Version
@@ -73,7 +65,6 @@ dependencies:
73
65
  type: :runtime
74
66
  prerelease: false
75
67
  version_requirements: !ruby/object:Gem::Requirement
76
- none: false
77
68
  requirements:
78
69
  - - ! '>='
79
70
  - !ruby/object:Gem::Version
@@ -81,7 +72,6 @@ dependencies:
81
72
  - !ruby/object:Gem::Dependency
82
73
  name: activesupport
83
74
  requirement: !ruby/object:Gem::Requirement
84
- none: false
85
75
  requirements:
86
76
  - - ! '>='
87
77
  - !ruby/object:Gem::Version
@@ -89,7 +79,6 @@ dependencies:
89
79
  type: :runtime
90
80
  prerelease: false
91
81
  version_requirements: !ruby/object:Gem::Requirement
92
- none: false
93
82
  requirements:
94
83
  - - ! '>='
95
84
  - !ruby/object:Gem::Version
@@ -97,7 +86,6 @@ dependencies:
97
86
  - !ruby/object:Gem::Dependency
98
87
  name: redcarpet
99
88
  requirement: !ruby/object:Gem::Requirement
100
- none: false
101
89
  requirements:
102
90
  - - ! '>='
103
91
  - !ruby/object:Gem::Version
@@ -105,7 +93,6 @@ dependencies:
105
93
  type: :development
106
94
  prerelease: false
107
95
  version_requirements: !ruby/object:Gem::Requirement
108
- none: false
109
96
  requirements:
110
97
  - - ! '>='
111
98
  - !ruby/object:Gem::Version
@@ -113,7 +100,6 @@ dependencies:
113
100
  - !ruby/object:Gem::Dependency
114
101
  name: pg
115
102
  requirement: !ruby/object:Gem::Requirement
116
- none: false
117
103
  requirements:
118
104
  - - ! '>='
119
105
  - !ruby/object:Gem::Version
@@ -121,7 +107,6 @@ dependencies:
121
107
  type: :runtime
122
108
  prerelease: false
123
109
  version_requirements: !ruby/object:Gem::Requirement
124
- none: false
125
110
  requirements:
126
111
  - - ! '>='
127
112
  - !ruby/object:Gem::Version
@@ -366,6 +351,7 @@ files:
366
351
  - spec/app/models/mdm/web_vuln_spec.rb
367
352
  - spec/app/models/mdm/workspace_spec.rb
368
353
  - spec/app/validators/parameters_validator_spec.rb
354
+ - spec/app/validators/password_is_strong_validator_spec.rb
369
355
  - spec/dummy/Rakefile
370
356
  - spec/dummy/app/assets/javascripts/application.js
371
357
  - spec/dummy/app/assets/stylesheets/application.css
@@ -453,33 +439,26 @@ files:
453
439
  - spec/support/shared/examples/mdm/module/detail/supports_stance_with_mtype.rb
454
440
  homepage: ''
455
441
  licenses: []
442
+ metadata: {}
456
443
  post_install_message:
457
444
  rdoc_options: []
458
445
  require_paths:
459
446
  - lib
460
447
  required_ruby_version: !ruby/object:Gem::Requirement
461
- none: false
462
448
  requirements:
463
449
  - - ! '>='
464
450
  - !ruby/object:Gem::Version
465
451
  version: '0'
466
- segments:
467
- - 0
468
- hash: -967868952609158407
469
452
  required_rubygems_version: !ruby/object:Gem::Requirement
470
- none: false
471
453
  requirements:
472
454
  - - ! '>='
473
455
  - !ruby/object:Gem::Version
474
456
  version: '0'
475
- segments:
476
- - 0
477
- hash: -967868952609158407
478
457
  requirements: []
479
458
  rubyforge_project:
480
- rubygems_version: 1.8.25
459
+ rubygems_version: 2.1.9
481
460
  signing_key:
482
- specification_version: 3
461
+ specification_version: 4
483
462
  summary: Database code for MSF and Metasploit Pro
484
463
  test_files:
485
464
  - spec/app/models/mdm/client_spec.rb
@@ -526,6 +505,7 @@ test_files:
526
505
  - spec/app/models/mdm/web_vuln_spec.rb
527
506
  - spec/app/models/mdm/workspace_spec.rb
528
507
  - spec/app/validators/parameters_validator_spec.rb
508
+ - spec/app/validators/password_is_strong_validator_spec.rb
529
509
  - spec/dummy/Rakefile
530
510
  - spec/dummy/app/assets/javascripts/application.js
531
511
  - spec/dummy/app/assets/stylesheets/application.css