metasploit_data_models 0.23.1 → 0.23.2

Sign up to get free protection for your applications and to get access to all the features.
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