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.
- checksums.yaml +4 -4
- data/app/models/mdm/host.rb +42 -33
- data/app/models/mdm/loot.rb +9 -0
- data/app/models/mdm/module/detail.rb +28 -7
- data/app/models/mdm/module/ref.rb +4 -4
- data/app/models/mdm/ref.rb +5 -5
- data/app/models/mdm/session.rb +18 -1
- data/app/models/mdm/user.rb +13 -0
- data/app/models/mdm/vuln.rb +16 -7
- data/app/models/mdm/workspace.rb +16 -8
- data/app/models/metasploit_data_models/automatic_exploitation.rb +5 -0
- data/app/models/metasploit_data_models/automatic_exploitation/match.rb +42 -0
- data/app/models/metasploit_data_models/automatic_exploitation/match_result.rb +40 -0
- data/app/models/metasploit_data_models/automatic_exploitation/match_set.rb +30 -0
- data/app/models/metasploit_data_models/automatic_exploitation/run.rb +27 -0
- data/app/models/metasploit_data_models/module_run.rb +213 -0
- data/app/validators/password_is_strong_validator.rb +5 -5
- data/db/migrate/20131002004641_create_automatic_exploitation_matches.rb +13 -0
- data/db/migrate/20131002164449_create_automatic_exploitation_match_sets.rb +12 -0
- data/db/migrate/20131008213344_create_automatic_exploitation_runs.rb +11 -0
- data/db/migrate/20131011184338_module_detail_on_automatic_exploitation_match.rb +10 -0
- data/db/migrate/20131017150735_create_automatic_exploitation_match_results.rb +11 -0
- data/db/migrate/20131021185657_make_match_polymorphic.rb +11 -0
- data/db/migrate/20150219173821_create_module_runs.rb +23 -0
- data/db/migrate/20150219215039_add_module_run_to_session.rb +8 -0
- data/db/migrate/20150226151459_add_module_run_fk_to_loot.rb +8 -0
- data/db/migrate/20150312155312_add_module_full_name_to_match.rb +6 -0
- data/db/migrate/20150326183742_add_missing_ae_indices.rb +13 -0
- data/lib/metasploit_data_models/version.rb +1 -1
- data/spec/app/models/mdm/host_spec.rb +28 -27
- data/spec/app/models/mdm/loot_spec.rb +1 -0
- data/spec/app/models/mdm/module/detail_spec.rb +2 -2
- data/spec/app/models/mdm/session_spec.rb +21 -18
- data/spec/app/models/mdm/vuln_spec.rb +9 -10
- data/spec/app/models/metasploit_data_models/automatic_exploitation/match_result_spec.rb +88 -0
- data/spec/app/models/metasploit_data_models/automatic_exploitation/match_set_spec.rb +48 -0
- data/spec/app/models/metasploit_data_models/automatic_exploitation/match_spec.rb +25 -0
- data/spec/app/models/metasploit_data_models/automatic_exploitation/run_spec.rb +40 -0
- data/spec/app/models/metasploit_data_models/module_run_spec.rb +136 -0
- data/spec/dummy/db/structure.sql +369 -2
- data/spec/factories/mdm/module/details.rb +21 -21
- data/spec/factories/metasploit_data_models/automatic_exploitation/match_results.rb +7 -0
- data/spec/factories/metasploit_data_models/automatic_exploitation/match_sets.rb +8 -0
- data/spec/factories/metasploit_data_models/automatic_exploitation/matches.rb +6 -0
- data/spec/factories/metasploit_data_models/automatic_exploitation/runs.rb +6 -0
- data/spec/factories/module_runs.rb +40 -0
- metadata +30 -172
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateAutomaticExploitationMatchSets < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :automatic_exploitation_match_sets do |t|
|
4
|
+
t.integer :workspace_id
|
5
|
+
t.integer :user_id
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
add_index :automatic_exploitation_match_sets, :user_id
|
10
|
+
add_index :automatic_exploitation_match_sets, :workspace_id
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class ModuleDetailOnAutomaticExploitationMatch < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
rename_column :automatic_exploitation_matches, :ref_id, :module_detail_id
|
4
|
+
add_column :automatic_exploitation_matches, :match_set_id, :integer
|
5
|
+
end
|
6
|
+
|
7
|
+
def down
|
8
|
+
rename_column :automatic_exploitation_matches, :module_detail_id, :ref_id
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class MakeMatchPolymorphic < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
add_column :automatic_exploitation_matches, :matchable_type, :string
|
4
|
+
add_column :automatic_exploitation_matches, :matchable_id, :integer
|
5
|
+
end
|
6
|
+
|
7
|
+
def down
|
8
|
+
remove_column :automatic_exploitation_matches, :matchable_type
|
9
|
+
remove_column :automatic_exploitation_matches, :matchable_id
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CreateModuleRuns < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :module_runs do |t|
|
4
|
+
t.datetime :attempted_at
|
5
|
+
t.text :fail_detail
|
6
|
+
t.string :fail_reason
|
7
|
+
t.text :module_fullname
|
8
|
+
t.integer :port
|
9
|
+
t.string :proto
|
10
|
+
t.integer :session_id
|
11
|
+
t.string :status
|
12
|
+
t.integer :trackable_id
|
13
|
+
t.string :trackable_type
|
14
|
+
t.integer :user_id
|
15
|
+
t.string :username
|
16
|
+
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
add_index :module_runs, :session_id
|
21
|
+
add_index :module_runs, :user_id
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AddMissingAeIndices < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
add_index :automatic_exploitation_match_results, :match_id
|
4
|
+
add_index :automatic_exploitation_match_results, :run_id
|
5
|
+
|
6
|
+
add_index :automatic_exploitation_runs, :match_set_id
|
7
|
+
add_index :automatic_exploitation_runs, :user_id
|
8
|
+
add_index :automatic_exploitation_runs, :workspace_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def down
|
12
|
+
end
|
13
|
+
end
|
@@ -6,7 +6,7 @@ module MetasploitDataModels
|
|
6
6
|
# The minor version number, scoped to the {MAJOR} version number.
|
7
7
|
MINOR = 23
|
8
8
|
# The patch number, scoped to the {MAJOR} and {MINOR} version numbers.
|
9
|
-
PATCH =
|
9
|
+
PATCH = 2
|
10
10
|
|
11
11
|
# The full version string, including the {MAJOR}, {MINOR}, {PATCH}, and optionally, the `PRERELEASE` in the
|
12
12
|
# {http://semver.org/spec/v2.0.0.html semantic versioning v2.0.0} format.
|
@@ -102,7 +102,7 @@ describe Mdm::Host do
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
|
105
|
+
context 'associations' do
|
106
106
|
it { should have_many(:creds).class_name('Mdm::Cred').through(:services) }
|
107
107
|
it { should have_many(:clients).class_name('Mdm::Client').dependent(:destroy) }
|
108
108
|
it { should have_many(:exploit_attempts).class_name('Mdm::ExploitAttempt').dependent(:destroy) }
|
@@ -110,6 +110,7 @@ describe Mdm::Host do
|
|
110
110
|
it { should have_many(:host_details).class_name('Mdm::HostDetail').dependent(:destroy) }
|
111
111
|
it { should have_many(:hosts_tags).class_name('Mdm::HostTag') }
|
112
112
|
it { should have_many(:loots).class_name('Mdm::Loot').dependent(:destroy).order('loots.created_at DESC') }
|
113
|
+
it { should have_many(:module_runs).class_name('MetasploitDataModels::ModuleRun') }
|
113
114
|
it { should have_many(:task_hosts).class_name('Mdm::TaskHost').dependent(:destroy) }
|
114
115
|
it { should have_many(:tasks).class_name('Mdm::Task').through(:task_hosts) }
|
115
116
|
|
@@ -208,9 +209,9 @@ describe Mdm::Host do
|
|
208
209
|
it { should have_many(:vuln_refs).class_name('Mdm::VulnRef') }
|
209
210
|
it { should have_many(:web_sites).class_name('Mdm::WebSite').through(:services) }
|
210
211
|
it { should belong_to(:workspace).class_name('Mdm::Workspace') }
|
211
|
-
|
212
|
+
end
|
212
213
|
|
213
|
-
|
214
|
+
context 'CONSTANTS' do
|
214
215
|
context 'ARCHITECTURES' do
|
215
216
|
subject(:architectures) do
|
216
217
|
described_class::ARCHITECTURES
|
@@ -285,30 +286,30 @@ describe Mdm::Host do
|
|
285
286
|
|
286
287
|
end
|
287
288
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
289
|
+
context 'SEARCH_FIELDS' do
|
290
|
+
subject(:search_fields) do
|
291
|
+
described_class::SEARCH_FIELDS
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should be an Array<String>' do
|
295
|
+
search_fields.should be_an Array
|
296
|
+
|
297
|
+
search_fields.each { |search_field|
|
298
|
+
search_field.should be_a String
|
299
|
+
}
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'should cast address to text' do
|
303
|
+
search_fields.should include('address::text')
|
304
|
+
end
|
305
|
+
|
306
|
+
it { should include('comments') }
|
307
|
+
it { should include('mac') }
|
308
|
+
it { should include('name') }
|
309
|
+
it { should include('os_flavor') }
|
310
|
+
it { should include('os_name') }
|
311
|
+
it { should include('os_sp') }
|
312
|
+
it { should include('purpose') }
|
312
313
|
end
|
313
314
|
|
314
315
|
it 'should define STATES in any order' do
|
@@ -7,6 +7,7 @@ describe Mdm::Loot do
|
|
7
7
|
it { should belong_to(:workspace).class_name('Mdm::Workspace') }
|
8
8
|
it { should belong_to(:service).class_name('Mdm::Service') }
|
9
9
|
it { should belong_to(:host).class_name('Mdm::Host') }
|
10
|
+
it { should belong_to(:module_run).class_name('MetasploitDataModels::ModuleRun') }
|
10
11
|
end
|
11
12
|
|
12
13
|
context 'database' do
|
@@ -25,31 +25,34 @@ describe Mdm::Session do
|
|
25
25
|
context 'database' do
|
26
26
|
|
27
27
|
context 'timestamps'do
|
28
|
-
it {
|
29
|
-
it {
|
30
|
-
it {
|
28
|
+
it { is_expected.to have_db_column(:closed_at).of_type(:datetime) }
|
29
|
+
it { is_expected.to have_db_column(:last_seen).of_type(:datetime) }
|
30
|
+
it { is_expected.to have_db_column(:opened_at).of_type(:datetime).with_options(:null => false) }
|
31
31
|
end
|
32
32
|
|
33
33
|
context 'columns' do
|
34
|
-
it {
|
35
|
-
it {
|
36
|
-
it {
|
37
|
-
it {
|
38
|
-
it {
|
39
|
-
it {
|
40
|
-
it {
|
41
|
-
it {
|
42
|
-
it {
|
34
|
+
it { is_expected.to have_db_column(:datastore).of_type(:text) }
|
35
|
+
it { is_expected.to have_db_column(:desc).of_type(:string) }
|
36
|
+
it { is_expected.to have_db_column(:host_id).of_type(:integer) }
|
37
|
+
it { is_expected.to have_db_column(:local_id).of_type(:integer) }
|
38
|
+
it { is_expected.to have_db_column(:module_run_id).of_type(:integer) }
|
39
|
+
it { is_expected.to have_db_column(:platform).of_type(:string) }
|
40
|
+
it { is_expected.to have_db_column(:port).of_type(:integer) }
|
41
|
+
it { is_expected.to have_db_column(:stype).of_type(:string) }
|
42
|
+
it { is_expected.to have_db_column(:via_exploit).of_type(:string) }
|
43
|
+
it { is_expected.to have_db_column(:via_payload).of_type(:string) }
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
47
|
context 'associations' do
|
47
|
-
it {
|
48
|
-
it {
|
49
|
-
it {
|
50
|
-
it {
|
51
|
-
it {
|
52
|
-
it {
|
48
|
+
it { is_expected.to have_many(:events).class_name('Mdm::SessionEvent').dependent(:delete_all) }
|
49
|
+
it { is_expected.to belong_to(:host).class_name('Mdm::Host') }
|
50
|
+
it { is_expected.to belong_to(:originating_module_run).class_name('MetasploitDataModels::ModuleRun') }
|
51
|
+
it { is_expected.to have_many(:routes).class_name('Mdm::Route').dependent(:delete_all) }
|
52
|
+
it { is_expected.to have_many(:target_module_runs).class_name('MetasploitDataModels::ModuleRun') }
|
53
|
+
it { is_expected.to have_many(:tasks).class_name('Mdm::Task').through(:task_sessions)}
|
54
|
+
it { is_expected.to have_many(:task_sessions).class_name('Mdm::TaskSession').dependent(:destroy) }
|
55
|
+
it { is_expected.to have_one(:workspace).class_name('Mdm::Workspace').through(:host) }
|
53
56
|
end
|
54
57
|
|
55
58
|
context 'scopes' do
|
@@ -33,16 +33,15 @@ describe Mdm::Vuln do
|
|
33
33
|
|
34
34
|
|
35
35
|
context 'associations' do
|
36
|
-
it {
|
37
|
-
it {
|
38
|
-
it {
|
39
|
-
|
40
|
-
it {
|
41
|
-
it {
|
42
|
-
it {
|
43
|
-
|
44
|
-
it {
|
45
|
-
it { should have_many(:notes).class_name('Mdm::Note').dependent(:delete_all).order('notes.created_at') }
|
36
|
+
it { is_expected.to belong_to(:host).class_name('Mdm::Host') }
|
37
|
+
it { is_expected.to belong_to(:service).class_name('Mdm::Service') }
|
38
|
+
it { is_expected.to have_many(:module_refs).class_name('Mdm::Module::Ref').through(:refs) }
|
39
|
+
it { is_expected.to have_many(:module_runs).class_name('MetasploitDataModels::ModuleRun') }
|
40
|
+
it { is_expected.to have_many(:refs).class_name('Mdm::Ref').through(:vulns_refs) }
|
41
|
+
it { is_expected.to have_many(:vuln_attempts).class_name('Mdm::VulnAttempt').dependent(:destroy) }
|
42
|
+
it { is_expected.to have_many(:vuln_details).class_name('Mdm::VulnDetail').dependent(:destroy) }
|
43
|
+
it { is_expected.to have_many(:vulns_refs).class_name('Mdm::VulnRef').dependent(:destroy) }
|
44
|
+
it { is_expected.to have_many(:notes).class_name('Mdm::Note').dependent(:delete_all).order('notes.created_at') }
|
46
45
|
|
47
46
|
context 'module_details' do
|
48
47
|
it { should have_many(:module_details).class_name('Mdm::Module::Detail').through(:module_refs) }
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::AutomaticExploitation::MatchResult do
|
4
|
+
it_should_behave_like 'Metasploit::Concern.run'
|
5
|
+
|
6
|
+
context "database" do
|
7
|
+
it { is_expected.to have_db_column(:match_id).of_type(:integer) }
|
8
|
+
it { is_expected.to have_db_index(:match_id) }
|
9
|
+
it { is_expected.to have_db_column(:run_id).of_type(:integer) }
|
10
|
+
it { is_expected.to have_db_index(:run_id) }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'associations' do
|
14
|
+
it { should belong_to(:match).class_name('MetasploitDataModels::AutomaticExploitation::Match') }
|
15
|
+
it { should belong_to(:run).class_name('MetasploitDataModels::AutomaticExploitation::Run') }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'scopes' do
|
19
|
+
before do
|
20
|
+
match_failed = FactoryGirl.create(:automatic_exploitation_match)
|
21
|
+
match_succeeded = FactoryGirl.create(:automatic_exploitation_match)
|
22
|
+
run = FactoryGirl.create(:automatic_exploitation_run)
|
23
|
+
|
24
|
+
described_class.create do |match_result|
|
25
|
+
match_result.match = match_failed
|
26
|
+
match_result.run = run
|
27
|
+
match_result.state = MetasploitDataModels::AutomaticExploitation::MatchResult::SUCCEEDED
|
28
|
+
end
|
29
|
+
|
30
|
+
described_class.create do |match_result|
|
31
|
+
match_result.match = match_succeeded
|
32
|
+
match_result.run = run
|
33
|
+
match_result.state = MetasploitDataModels::AutomaticExploitation::MatchResult::FAILED
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'succeeded' do
|
38
|
+
subject(:succeeded) do
|
39
|
+
described_class.succeeded
|
40
|
+
end
|
41
|
+
|
42
|
+
specify 'returns only successful results' do
|
43
|
+
expect(succeeded.count).to eq(1)
|
44
|
+
expect(succeeded.first.state).to eq(MetasploitDataModels::AutomaticExploitation::MatchResult::SUCCEEDED)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'failed' do
|
49
|
+
subject(:failed) do
|
50
|
+
described_class.failed
|
51
|
+
end
|
52
|
+
|
53
|
+
specify 'returns only failed results' do
|
54
|
+
expect(failed.count).to eq(1)
|
55
|
+
expect(failed.first.state).to eq(MetasploitDataModels::AutomaticExploitation::MatchResult::FAILED)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'validations' do
|
61
|
+
context 'state' do
|
62
|
+
subject(:match_result) do
|
63
|
+
FactoryGirl.build(:automatic_exploitation_match_result, state: state)
|
64
|
+
end
|
65
|
+
context 'with nil' do
|
66
|
+
let(:state) { nil }
|
67
|
+
specify do
|
68
|
+
expect(match_result).not_to be_valid
|
69
|
+
expect(match_result.errors[:state]).to include("can't be blank")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
context 'with "asdf"' do
|
73
|
+
let(:state) { "asdf" }
|
74
|
+
specify do
|
75
|
+
expect(match_result).not_to be_valid
|
76
|
+
expect(match_result.errors[:state]).to include("is not included in the list")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
context 'with "succeeded"' do
|
80
|
+
let(:state) { MetasploitDataModels::AutomaticExploitation::MatchResult::SUCCEEDED }
|
81
|
+
specify do
|
82
|
+
expect(match_result).to be_valid
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::AutomaticExploitation::MatchSet do
|
4
|
+
describe "database" do
|
5
|
+
describe "foreign_keys" do
|
6
|
+
it { should have_db_column(:workspace_id).of_type(:integer) }
|
7
|
+
it { should have_db_column(:user_id).of_type(:integer) }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "indices" do
|
11
|
+
it { should have_db_index(:user_id) }
|
12
|
+
it { should have_db_index(:workspace_id) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "associations" do
|
17
|
+
it { should have_many(:matches).class_name('MetasploitDataModels::AutomaticExploitation::Match') }
|
18
|
+
it { should have_many(:matches).inverse_of(:match_set) }
|
19
|
+
it { should have_many(:runs).class_name('MetasploitDataModels::AutomaticExploitation::Run') }
|
20
|
+
it { should have_many(:runs).inverse_of(:match_set) }
|
21
|
+
it { should belong_to(:user).class_name('Mdm::User') }
|
22
|
+
it { should belong_to(:user).inverse_of(:automatic_exploitation_match_sets) }
|
23
|
+
it { should belong_to(:workspace).class_name('Mdm::Workspace') }
|
24
|
+
it { should belong_to(:workspace).inverse_of(:automatic_exploitation_match_sets) }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "validations" do
|
28
|
+
subject(:match_set){ FactoryGirl.build(:automatic_exploitation_match_set)}
|
29
|
+
|
30
|
+
describe "missing user" do
|
31
|
+
before(:each) do
|
32
|
+
match_set.user = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it{ is_expected.to be_invalid }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "missing workspace" do
|
39
|
+
before(:each) do
|
40
|
+
match_set.workspace = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it{ is_expected.to be_invalid }
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|