metasploit_data_models 0.16.6-java → 0.16.7-java

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