metasploit_data_models 0.16.6 → 0.16.7

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.
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