metasploit_data_models 0.23.1 → 0.23.2

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/mdm/host.rb +42 -33
  3. data/app/models/mdm/loot.rb +9 -0
  4. data/app/models/mdm/module/detail.rb +28 -7
  5. data/app/models/mdm/module/ref.rb +4 -4
  6. data/app/models/mdm/ref.rb +5 -5
  7. data/app/models/mdm/session.rb +18 -1
  8. data/app/models/mdm/user.rb +13 -0
  9. data/app/models/mdm/vuln.rb +16 -7
  10. data/app/models/mdm/workspace.rb +16 -8
  11. data/app/models/metasploit_data_models/automatic_exploitation.rb +5 -0
  12. data/app/models/metasploit_data_models/automatic_exploitation/match.rb +42 -0
  13. data/app/models/metasploit_data_models/automatic_exploitation/match_result.rb +40 -0
  14. data/app/models/metasploit_data_models/automatic_exploitation/match_set.rb +30 -0
  15. data/app/models/metasploit_data_models/automatic_exploitation/run.rb +27 -0
  16. data/app/models/metasploit_data_models/module_run.rb +213 -0
  17. data/app/validators/password_is_strong_validator.rb +5 -5
  18. data/db/migrate/20131002004641_create_automatic_exploitation_matches.rb +13 -0
  19. data/db/migrate/20131002164449_create_automatic_exploitation_match_sets.rb +12 -0
  20. data/db/migrate/20131008213344_create_automatic_exploitation_runs.rb +11 -0
  21. data/db/migrate/20131011184338_module_detail_on_automatic_exploitation_match.rb +10 -0
  22. data/db/migrate/20131017150735_create_automatic_exploitation_match_results.rb +11 -0
  23. data/db/migrate/20131021185657_make_match_polymorphic.rb +11 -0
  24. data/db/migrate/20150219173821_create_module_runs.rb +23 -0
  25. data/db/migrate/20150219215039_add_module_run_to_session.rb +8 -0
  26. data/db/migrate/20150226151459_add_module_run_fk_to_loot.rb +8 -0
  27. data/db/migrate/20150312155312_add_module_full_name_to_match.rb +6 -0
  28. data/db/migrate/20150326183742_add_missing_ae_indices.rb +13 -0
  29. data/lib/metasploit_data_models/version.rb +1 -1
  30. data/spec/app/models/mdm/host_spec.rb +28 -27
  31. data/spec/app/models/mdm/loot_spec.rb +1 -0
  32. data/spec/app/models/mdm/module/detail_spec.rb +2 -2
  33. data/spec/app/models/mdm/session_spec.rb +21 -18
  34. data/spec/app/models/mdm/vuln_spec.rb +9 -10
  35. data/spec/app/models/metasploit_data_models/automatic_exploitation/match_result_spec.rb +88 -0
  36. data/spec/app/models/metasploit_data_models/automatic_exploitation/match_set_spec.rb +48 -0
  37. data/spec/app/models/metasploit_data_models/automatic_exploitation/match_spec.rb +25 -0
  38. data/spec/app/models/metasploit_data_models/automatic_exploitation/run_spec.rb +40 -0
  39. data/spec/app/models/metasploit_data_models/module_run_spec.rb +136 -0
  40. data/spec/dummy/db/structure.sql +369 -2
  41. data/spec/factories/mdm/module/details.rb +21 -21
  42. data/spec/factories/metasploit_data_models/automatic_exploitation/match_results.rb +7 -0
  43. data/spec/factories/metasploit_data_models/automatic_exploitation/match_sets.rb +8 -0
  44. data/spec/factories/metasploit_data_models/automatic_exploitation/matches.rb +6 -0
  45. data/spec/factories/metasploit_data_models/automatic_exploitation/runs.rb +6 -0
  46. data/spec/factories/module_runs.rb +40 -0
  47. metadata +30 -172
@@ -15,6 +15,14 @@ class Mdm::Workspace < ActiveRecord::Base
15
15
  # Relations
16
16
  #
17
17
 
18
+ has_many :automatic_exploitation_runs,
19
+ class_name: 'MetasploitDataModels::AutomaticExploitation::Run',
20
+ inverse_of: :workspace
21
+
22
+ has_many :automatic_exploitation_match_sets,
23
+ class_name: 'MetasploitDataModels::AutomaticExploitation:MatchSet',
24
+ inverse_of: :workspace
25
+
18
26
  has_many :creds, :through => :services, :class_name => 'Mdm::Cred'
19
27
  has_many :events, :class_name => 'Mdm::Event'
20
28
  has_many :hosts, :dependent => :destroy, :class_name => 'Mdm::Host'
@@ -58,7 +66,7 @@ class Mdm::Workspace < ActiveRecord::Base
58
66
  allowed = false
59
67
  boundaries.each do |boundary_range|
60
68
  ok_range = Rex::Socket::RangeWalker.new(boundary)
61
- allowed = true if ok_range.include_range? given_range
69
+ allowed = true if ok_range.include_range? given_range
62
70
  end
63
71
  return allowed
64
72
  end
@@ -69,9 +77,9 @@ class Mdm::Workspace < ActiveRecord::Base
69
77
 
70
78
  def creds
71
79
  Mdm::Cred.find(
72
- :all,
73
- :include => {:service => :host},
74
- :conditions => ["hosts.workspace_id = ?", self.id]
80
+ :all,
81
+ :include => {:service => :host},
82
+ :conditions => ["hosts.workspace_id = ?", self.id]
75
83
  )
76
84
  end
77
85
 
@@ -101,9 +109,9 @@ class Mdm::Workspace < ActiveRecord::Base
101
109
 
102
110
  def host_tags
103
111
  Mdm::Tag.find(
104
- :all,
105
- :include => :hosts,
106
- :conditions => ["hosts.workspace_id = ?", self.id]
112
+ :all,
113
+ :include => :hosts,
114
+ :conditions => ["hosts.workspace_id = ?", self.id]
107
115
  )
108
116
  end
109
117
 
@@ -169,7 +177,7 @@ class Mdm::Workspace < ActiveRecord::Base
169
177
  def web_unique_forms(addrs=nil)
170
178
  forms = unique_web_forms
171
179
  if addrs
172
- forms.reject!{|f| not addrs.include?( f.web_site.service.host.address ) }
180
+ forms.reject! { |f| not addrs.include?(f.web_site.service.host.address) }
173
181
  end
174
182
  forms
175
183
  end
@@ -0,0 +1,5 @@
1
+ module MetasploitDataModels::AutomaticExploitation
2
+ def self.table_name_prefix
3
+ 'automatic_exploitation_'
4
+ end
5
+ end
@@ -0,0 +1,42 @@
1
+ class MetasploitDataModels::AutomaticExploitation::Match < ActiveRecord::Base
2
+ attr_accessible :match_set_id, :module_fullname
3
+
4
+
5
+ #
6
+ # Associations
7
+ #
8
+
9
+ # @!attribute matchable
10
+ # A (polymorphic) "matchable" entity like a {Mdm::Vuln} or {Mdm::Service}
11
+ #
12
+ # @return [Mdm::Vuln, Mdm::Service]
13
+ belongs_to :matchable, polymorphic: true
14
+ attr_accessible :matchable
15
+
16
+ # @!attribute module_detail
17
+ # The MSF module that this match connects to
18
+ #
19
+ # @return [Mdm::Module::Detail]
20
+ belongs_to :module_detail,
21
+ class_name: 'Mdm::Module::Detail',
22
+ foreign_key: :module_fullname,
23
+ primary_key: :fullname
24
+
25
+ # @!attribute match_set
26
+ # The {MatchSet} this match is part of
27
+ #
28
+ # @return [MetasploitDataModels::AutomaticExploitation::MatchResult]
29
+ has_many :match_results,
30
+ class_name: 'MetasploitDataModels::AutomaticExploitation::MatchResult',
31
+ inverse_of: :match
32
+
33
+ # @!attribute match_set
34
+ # The {MatchSet} this match is part of
35
+ #
36
+ # @return [MetasploitDataModels::AutomaticExploitation::MatchSet]
37
+ belongs_to :match_set,
38
+ class_name: 'MetasploitDataModels::AutomaticExploitation::MatchSet',
39
+ inverse_of: :matches
40
+
41
+ Metasploit::Concern.run(self)
42
+ end
@@ -0,0 +1,40 @@
1
+ class MetasploitDataModels::AutomaticExploitation::MatchResult < ActiveRecord::Base
2
+ attr_accessible :match_id, :run_id, :state
3
+
4
+ # Running associated exploit did NOT create a session
5
+ FAILED = "failed"
6
+ # Running associated exploit created a session
7
+ SUCCEEDED = "succeeded"
8
+
9
+ VALID_STATES = [FAILED, SUCCEEDED]
10
+
11
+ #
12
+ # ASSOCIATIONS
13
+ #
14
+
15
+ belongs_to :match,
16
+ class_name: 'MetasploitDataModels::AutomaticExploitation::Match',
17
+ inverse_of: :match_results,
18
+ dependent: :destroy
19
+
20
+ belongs_to :run,
21
+ inverse_of: :match_results,
22
+ class_name: 'MetasploitDataModels::AutomaticExploitation::Run'
23
+
24
+ #
25
+ # VALIDATIONS
26
+ #
27
+
28
+ # must be present and one of allowable values
29
+ validates :state,
30
+ presence: true,
31
+ inclusion: VALID_STATES
32
+
33
+ #
34
+ # SCOPES
35
+ #
36
+ scope :succeeded, lambda { where(state:"succeeded") }
37
+ scope :failed, lambda { where(state:"failed") }
38
+
39
+ Metasploit::Concern.run(self)
40
+ end
@@ -0,0 +1,30 @@
1
+ class MetasploitDataModels::AutomaticExploitation::MatchSet < ActiveRecord::Base
2
+ attr_accessible :user_id, :workspace_id, :minimum_rank
3
+
4
+ has_many :runs,
5
+ class_name: "MetasploitDataModels::AutomaticExploitation::Run",
6
+ inverse_of: :match_set
7
+
8
+ has_many :matches,
9
+ class_name: "MetasploitDataModels::AutomaticExploitation::Match",
10
+ inverse_of: :match_set,
11
+ dependent: :destroy
12
+
13
+ belongs_to :workspace,
14
+ inverse_of: :automatic_exploitation_match_sets,
15
+ class_name: "Mdm::Workspace"
16
+
17
+ belongs_to :user,
18
+ inverse_of: :automatic_exploitation_match_sets,
19
+ class_name: "Mdm::User"
20
+
21
+
22
+ validates :user,
23
+ presence: true
24
+
25
+ validates :workspace,
26
+ presence: true
27
+
28
+
29
+ Metasploit::Concern.run(self)
30
+ end
@@ -0,0 +1,27 @@
1
+ class MetasploitDataModels::AutomaticExploitation::Run < ActiveRecord::Base
2
+ attr_accessible :user_id, :workspace_id, :match_set_id
3
+
4
+ #
5
+ # ASSOCIATIONS
6
+ #
7
+ has_many :match_results,
8
+ class_name:'MetasploitDataModels::AutomaticExploitation::MatchResult',
9
+ inverse_of: :run,
10
+ dependent: :destroy
11
+
12
+ belongs_to :match_set,
13
+ class_name: 'MetasploitDataModels::AutomaticExploitation::MatchSet',
14
+ inverse_of: :runs
15
+
16
+ belongs_to :user,
17
+ class_name: "Mdm::User",
18
+ inverse_of: :automatic_exploitation_runs
19
+
20
+ belongs_to :workspace,
21
+ class_name: "Mdm::Workspace",
22
+ inverse_of: :automatic_exploitation_runs
23
+
24
+
25
+
26
+ Metasploit::Concern.run(self)
27
+ end
@@ -0,0 +1,213 @@
1
+ # {MetasploitDataModels::ModuleRun} holds the record of having launched a piece of Metasploit content.
2
+ # It has associations to {Mdm::User} for audit purposes, and makes polymorphic associations to things like
3
+ # {Mdm::Vuln} and {Mdm::Host} for flexible record keeping about activity attacking either specific vulns or just
4
+ # making mischief on specific remote targets w/out the context of a vuln or even a remote IP service.
5
+ #
6
+ # There are also associations to {Mdm::Session} for two use cases: a `spawned_session` is a
7
+ # session created by the ModuleRun. A `target_session` is a session that the ModuleRun
8
+ # is acting upon (e.g.) for running a post module.
9
+ class MetasploitDataModels::ModuleRun < ActiveRecord::Base
10
+ #
11
+ # Constants
12
+ #
13
+
14
+ # Marks the module as having successfully run
15
+ SUCCEED = 'succeeded'
16
+ # Marks the run as having not run successfully
17
+ FAIL = 'failed'
18
+ # Marks the module as having had a runtime error
19
+ ERROR = 'error'
20
+ # {ModuleRun} objects will be validated against these statuses
21
+ VALID_STATUSES = [SUCCEED, FAIL, ERROR]
22
+
23
+
24
+ #
25
+ # Attributes
26
+ #
27
+
28
+ # @!attribute [rw] attempted_at
29
+ # The date/time when this module was run
30
+ # @return [Datetime]
31
+
32
+ # @!attribute [rw] fail_detail
33
+ # Arbitrary information captured by the module to give in-depth reason for failure
34
+ # @return [String]
35
+
36
+ # @!attribute [rw] fail_reason
37
+ # One of the values of the constants in {Msf::Module::Failure}
38
+ # @return [String]
39
+
40
+ # @!attribute [rw] module_name
41
+ # The Msf::Module#fullname of the module being run
42
+ # @return [String]
43
+
44
+ # @!attribute [rw] port
45
+ # The port that the remote host was attacked on, if any
46
+ # @return [Fixnum]
47
+
48
+ # @!attribute [rw] proto
49
+ # The name of the protocol that the host was attacked on, if any
50
+ # @return [String]
51
+
52
+ # @!attribute [rw] session_id
53
+ # The {Mdm::Session} that this was run with, in the case of a post module. In exploit modules, this field will
54
+ # remain null.
55
+ # @return [Datetime]
56
+
57
+ # @!attribute [rw] status
58
+ # The result of running the module
59
+ # @return [String]
60
+
61
+ # @!attribute [rw] username
62
+ # The name of the user running this module
63
+ # @return [String]
64
+
65
+
66
+
67
+ #
68
+ # Associations
69
+ #
70
+
71
+
72
+
73
+ # @!attribute [rw] loots
74
+ # The sweet, sweet loot taken by this module_run
75
+ #
76
+ # @return [ActiveRecord::Relation<Mdm::Loot>]
77
+ has_many :loots,
78
+ class_name: 'Mdm::Loot',
79
+ inverse_of: :module_run
80
+
81
+ # @!attribute [rw] module_detail
82
+ # The cached module information
83
+ #
84
+ # @return [ActiveRecord::Relation<Mdm::Module::Detail>]
85
+ belongs_to :module_detail,
86
+ class_name: 'Mdm::Module::Detail',
87
+ inverse_of: :module_runs,
88
+ foreign_key: :module_fullname,
89
+ primary_key: :fullname
90
+
91
+ # @!attribute [rw] spawned_session
92
+ #
93
+ # The session created by running this module.
94
+ # Note that this is NOT the session that modules are run on.
95
+ #
96
+ # @return [Mdm::Session]
97
+ has_one :spawned_session,
98
+ class_name: 'Mdm::Session',
99
+ inverse_of: :originating_module_run
100
+
101
+
102
+ # @!attribute [rw] target_session
103
+ #
104
+ # The session this module was run on, if any.
105
+ # Note that this is NOT a session created by this module run
106
+ # of exploit modules.
107
+ #
108
+ # @return [Mdm::Session]
109
+ belongs_to :target_session,
110
+ class_name: 'Mdm::Session',
111
+ foreign_key: :session_id,
112
+ inverse_of: :target_module_runs
113
+
114
+
115
+
116
+ # @!attribute [rw] trackable
117
+ #
118
+ # A polymorphic association that is tracked as being related to this module run.
119
+ # {Mdm::Host} and {Mdm::Vuln} can each have {ModuleRun} objects.
120
+ #
121
+ # @return [Mdm::Host, Mdm::Vuln]
122
+ belongs_to :trackable, polymorphic: true
123
+
124
+
125
+ # @!attribute [rw] user
126
+ #
127
+ # The user that launched this module
128
+ #
129
+ # @return [Mdm::User]
130
+ belongs_to :user,
131
+ class_name: 'Mdm::User',
132
+ foreign_key: 'user_id',
133
+ inverse_of: :module_runs
134
+
135
+
136
+
137
+ #
138
+ #
139
+ # Validations
140
+ #
141
+ #
142
+
143
+ #
144
+ # Method Validations
145
+ #
146
+
147
+
148
+ # spawned_session is only valid for *exploit modules*
149
+ validate :no_spawned_session_for_non_exploits_except_logins
150
+
151
+ # target_session is only valid for *non-exploit modules*
152
+ validate :no_target_session_for_exploits
153
+
154
+ # Can't save without information on what module has run
155
+ validate :module_information_is_present
156
+
157
+ #
158
+ # Attribute Validations
159
+ #
160
+
161
+ # When the module was run
162
+ validates :attempted_at,
163
+ presence: true
164
+ # Result of running the module
165
+ validates :status,
166
+ inclusion: VALID_STATUSES
167
+
168
+ # Splits strings formatted like Msf::Module#fullname into components
169
+ #
170
+ # @example
171
+ # module_name = "exploit/windows/multi/mah-rad-exploit"
172
+ # module_name_components # => ["exploit","windows","multi","mah-rad-exploit"]
173
+ # @return [Array]
174
+ def module_name_components
175
+ module_fullname.split('/')
176
+ end
177
+
178
+ private
179
+
180
+ # Mark the object as invalid if there is no associated #module_name or {Mdm::ModuleDetail}
181
+ # @return [void]
182
+ def module_information_is_present
183
+ if module_fullname.blank?
184
+ errors.add(:base, "module_fullname cannot be blank")
185
+ end
186
+ end
187
+
188
+ # Mark the object as invalid if there is a spawned_session but the module is *not* an exploit
189
+ # and not an aux module with the word "login" in the final portion of `module_fullname`
190
+ #
191
+ # @return [void]
192
+ def no_spawned_session_for_non_exploits_except_logins
193
+ return true unless spawned_session.present?
194
+ return true if module_name_components.last.include?("login")
195
+
196
+ if module_name_components.first != 'exploit'
197
+ errors.add(:base, 'spawned_session cannot be set for non-exploit modules. Use target_session.')
198
+ end
199
+ end
200
+
201
+ # Mark the object as invalid if there is a target_session but the module is an exploit
202
+ # @return [void]
203
+ def no_target_session_for_exploits
204
+ return true unless target_session.present? # nothing to do unless target_session is set
205
+
206
+ if module_name_components.first == 'exploit'
207
+ return true if module_name_components[2] == 'local'
208
+ errors.add(:base, 'target_session cannot be set for exploit modules. Use spawned_session.')
209
+ end
210
+ end
211
+
212
+
213
+ end
@@ -1,9 +1,9 @@
1
1
  class PasswordIsStrongValidator < ActiveModel::EachValidator
2
2
  COMMON_PASSWORDS = %w{
3
- password pass root admin metasploit
4
- msf 123456 qwerty abc123 letmein monkey link182 demo
5
- changeme test1234 rapid7
6
- }
3
+ password pass root admin metasploit
4
+ msf 123456 qwerty abc123 letmein monkey link182 demo
5
+ changeme test1234 rapid7
6
+ }
7
7
 
8
8
  SPECIAL_CHARS = %q{!@"#$%&'()*+,-./:;<=>?[\\]^_`{|}~ }
9
9
 
@@ -105,4 +105,4 @@ class PasswordIsStrongValidator < ActiveModel::EachValidator
105
105
 
106
106
  false
107
107
  end
108
- end
108
+ end
@@ -0,0 +1,13 @@
1
+ class CreateAutomaticExploitationMatches < ActiveRecord::Migration
2
+ def change
3
+ create_table :automatic_exploitation_matches do |t|
4
+ t.integer :ref_id
5
+ t.string :state
6
+ t.integer :nexpose_data_vulnerability_definition_id
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :automatic_exploitation_matches, :ref_id
12
+ end
13
+ end