metasploit_data_models 6.0.10 → 6.0.11
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/service.rb +60 -1
- data/app/models/mdm/service_link.rb +52 -0
- data/app/models/mdm/vuln.rb +6 -0
- data/db/migrate/20250716155919_add_resource_to_mdm_vuln.rb +5 -0
- data/db/migrate/20250717170556_add_resource_to_services.rb +5 -0
- data/db/migrate/20250718122714_create_service_links.rb +11 -0
- data/db/migrate/20250720082201_drop_service_uniqueness_index2.rb +5 -0
- data/db/migrate/20250721114306_remove_duplicate_services3.rb +17 -0
- data/lib/mdm.rb +1 -0
- data/lib/metasploit_data_models/version.rb +1 -1
- data/spec/app/models/mdm/service_link_spec.rb +112 -0
- data/spec/app/models/mdm/service_spec.rb +69 -9
- data/spec/app/models/mdm/vuln_spec.rb +1 -0
- data/spec/factories/mdm/service_links.rb +8 -0
- data/spec/factories/mdm/services.rb +5 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d5c3b6ba17aa68aa354fd30e709e371bdc703e48bfab8bf1ab1e01d220c7a136
|
|
4
|
+
data.tar.gz: cf14f60355752907e3d87333cc6d6946295745ff69ee0ca0ebd6e24afd88a77d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c800409a016366908e074694cd8f8bf22bd0112ef77c99e738b6ed97c269f319b15afda791e82969e287dcbc03e318e374b378c92be207a5261d7564ab7ff6ca
|
|
7
|
+
data.tar.gz: 34851f917756daf8fdf85018147d7178052c15a21e3177dad4730e29b199b0d9c64ac7177118e82bdc37fbb00a8bfdbef7ffddb22dd6610caa7d7b8ff1dab7a9
|
data/app/models/mdm/service.rb
CHANGED
|
@@ -96,6 +96,28 @@ class Mdm::Service < ApplicationRecord
|
|
|
96
96
|
dependent: :destroy,
|
|
97
97
|
inverse_of: :service
|
|
98
98
|
|
|
99
|
+
# @!attribute [rw] parent_links
|
|
100
|
+
# Links to parent services of this service.
|
|
101
|
+
#
|
|
102
|
+
# @return [Array<Mdm::ServiceLink>]
|
|
103
|
+
has_many :parent_links,
|
|
104
|
+
class_name: 'Mdm::ServiceLink',
|
|
105
|
+
foreign_key: 'child_id',
|
|
106
|
+
dependent: :destroy,
|
|
107
|
+
inverse_of: :child
|
|
108
|
+
|
|
109
|
+
# @!attribute [rw] parent_links
|
|
110
|
+
# Link to child services of this service.
|
|
111
|
+
#
|
|
112
|
+
# @return [Array<Mdm::ServiceLink>]
|
|
113
|
+
has_many :child_links,
|
|
114
|
+
class_name: 'Mdm::ServiceLink',
|
|
115
|
+
foreign_key: 'parent_id',
|
|
116
|
+
dependent: :destroy,
|
|
117
|
+
inverse_of: :parent
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
99
121
|
#
|
|
100
122
|
# through: :task_services
|
|
101
123
|
#
|
|
@@ -128,6 +150,27 @@ class Mdm::Service < ApplicationRecord
|
|
|
128
150
|
# @return [Array<Mdm::WebVuln>]
|
|
129
151
|
has_many :web_vulns, :through => :web_sites, :class_name => 'Mdm::WebVuln'
|
|
130
152
|
|
|
153
|
+
#
|
|
154
|
+
# through: :parent_links
|
|
155
|
+
#
|
|
156
|
+
|
|
157
|
+
# @!attribute [rw] parents
|
|
158
|
+
# Parent services of this service.
|
|
159
|
+
#
|
|
160
|
+
# @return [Array<Mdm::Service>]
|
|
161
|
+
has_many :parents, through: :parent_links, source: :parent
|
|
162
|
+
|
|
163
|
+
#
|
|
164
|
+
# through: :child_links
|
|
165
|
+
#
|
|
166
|
+
|
|
167
|
+
# @!attribute [rw] children
|
|
168
|
+
# Child services of this service.
|
|
169
|
+
#
|
|
170
|
+
# @return [Array<Mdm::Service>]
|
|
171
|
+
has_many :children, through: :child_links, source: :child
|
|
172
|
+
|
|
173
|
+
|
|
131
174
|
#
|
|
132
175
|
# Attributes
|
|
133
176
|
#
|
|
@@ -157,6 +200,11 @@ class Mdm::Service < ApplicationRecord
|
|
|
157
200
|
#
|
|
158
201
|
# @return [String] element of {STATES}.
|
|
159
202
|
|
|
203
|
+
# @!attribute [rw] resource
|
|
204
|
+
# Additional resource information about the service, such as a URL or path.
|
|
205
|
+
#
|
|
206
|
+
# @return [JSONB]
|
|
207
|
+
|
|
160
208
|
#
|
|
161
209
|
# Callbacks
|
|
162
210
|
#
|
|
@@ -227,7 +275,9 @@ class Mdm::Service < ApplicationRecord
|
|
|
227
275
|
message: 'already exists on this host and protocol',
|
|
228
276
|
scope: [
|
|
229
277
|
:host_id,
|
|
230
|
-
:proto
|
|
278
|
+
:proto,
|
|
279
|
+
:name,
|
|
280
|
+
:resource
|
|
231
281
|
]
|
|
232
282
|
}
|
|
233
283
|
validates :proto,
|
|
@@ -263,5 +313,14 @@ class Mdm::Service < ApplicationRecord
|
|
|
263
313
|
end
|
|
264
314
|
end
|
|
265
315
|
|
|
316
|
+
# Destroy this service if it does not have parents {#service_links}
|
|
317
|
+
#
|
|
318
|
+
# @return [void]
|
|
319
|
+
def destroy_if_orphaned
|
|
320
|
+
self.class.transaction do
|
|
321
|
+
destroy if parents.count == 0
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
266
325
|
Metasploit::Concern.run(self)
|
|
267
326
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Join model between {Mdm::Service} and {Mdm::Service} for many-to-many self-referencing relationship
|
|
2
|
+
class Mdm::ServiceLink < ApplicationRecord
|
|
3
|
+
self.table_name = 'service_links'
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# Associations
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
# Parent service
|
|
10
|
+
belongs_to :parent,
|
|
11
|
+
class_name: 'Mdm::Service',
|
|
12
|
+
inverse_of: :child_links
|
|
13
|
+
|
|
14
|
+
# Child service
|
|
15
|
+
belongs_to :child,
|
|
16
|
+
class_name: 'Mdm::Service',
|
|
17
|
+
inverse_of: :parent_links
|
|
18
|
+
|
|
19
|
+
# Destroy orphaned child when destroying a service link
|
|
20
|
+
after_destroy :destroy_orphan_child
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# Attributes
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
# @!attribute created_at
|
|
27
|
+
# When this task service was created.
|
|
28
|
+
#
|
|
29
|
+
# @return [DateTime]
|
|
30
|
+
|
|
31
|
+
# @!attribute updated_at
|
|
32
|
+
# The last time this task service was updated.
|
|
33
|
+
#
|
|
34
|
+
# @return [DateTime]
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Validations
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
validates :parent_id,
|
|
41
|
+
:uniqueness => {
|
|
42
|
+
:scope => :child_id
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
def destroy_orphan_child
|
|
46
|
+
Mdm::Service.where(id: child.id).first&.destroy_if_orphaned
|
|
47
|
+
end
|
|
48
|
+
private :destroy_orphan_child
|
|
49
|
+
|
|
50
|
+
Metasploit::Concern.run(self)
|
|
51
|
+
end
|
|
52
|
+
|
data/app/models/mdm/vuln.rb
CHANGED
|
@@ -160,6 +160,12 @@ class Mdm::Vuln < ApplicationRecord
|
|
|
160
160
|
#
|
|
161
161
|
# @return [Integer]
|
|
162
162
|
|
|
163
|
+
# @!attribute [rw] resource
|
|
164
|
+
# The resource that this vulnerability is associated with.
|
|
165
|
+
# It is stored as a JSONB object.
|
|
166
|
+
#
|
|
167
|
+
# @return [JSONB]
|
|
168
|
+
|
|
163
169
|
#
|
|
164
170
|
# Callbacks
|
|
165
171
|
#
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class CreateServiceLinks < ActiveRecord::Migration[7.0]
|
|
2
|
+
def change
|
|
3
|
+
create_table :service_links do |t|
|
|
4
|
+
t.references :parent, null: false, foreign_key: { to_table: :services }
|
|
5
|
+
t.references :child, null: false, foreign_key: { to_table: :services }
|
|
6
|
+
t.timestamps
|
|
7
|
+
end
|
|
8
|
+
add_index :service_links, [:parent_id, :child_id], unique: true
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class RemoveDuplicateServices3 < ActiveRecord::Migration[7.0]
|
|
2
|
+
def change
|
|
3
|
+
select_mgr = Mdm::Service.arel_table.project(
|
|
4
|
+
Mdm::Service[:host_id],
|
|
5
|
+
Mdm::Service[:proto],
|
|
6
|
+
Mdm::Service[:port].count
|
|
7
|
+
).group(
|
|
8
|
+
'host_id',
|
|
9
|
+
'port',
|
|
10
|
+
'proto'
|
|
11
|
+
).having(Mdm::Service[:port].count.gt(1))
|
|
12
|
+
|
|
13
|
+
Mdm::Service.find_by_sql(select_mgr).each(&:destroy)
|
|
14
|
+
|
|
15
|
+
add_index :services, [:host_id, :port, :proto, :name, :resource], unique: true, name: 'index_services_on_5_columns'
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/mdm.rb
CHANGED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
RSpec.describe Mdm::ServiceLink, type: :model do
|
|
2
|
+
it_should_behave_like 'Metasploit::Concern.run'
|
|
3
|
+
|
|
4
|
+
context 'factory' do
|
|
5
|
+
it 'should be valid' do
|
|
6
|
+
service_link = FactoryBot.build(:mdm_service_link)
|
|
7
|
+
expect(service_link).to be_valid
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context 'database' do
|
|
12
|
+
|
|
13
|
+
context 'timestamps'do
|
|
14
|
+
it { is_expected.to have_db_column(:created_at).of_type(:datetime).with_options(:null => false) }
|
|
15
|
+
it { is_expected.to have_db_column(:updated_at).of_type(:datetime).with_options(:null => false) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'columns' do
|
|
19
|
+
it { is_expected.to have_db_column(:parent_id).of_type(:integer).with_options(:null => false) }
|
|
20
|
+
it { is_expected.to have_db_column(:child_id).of_type(:integer).with_options(:null => false) }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context '#destroy' do
|
|
25
|
+
it 'should successfully destroy one Mdm::ServiceLink' do
|
|
26
|
+
service_link = FactoryBot.create(:mdm_service_link)
|
|
27
|
+
expect { service_link.destroy }.to_not raise_error
|
|
28
|
+
expect { service_link.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with one parent and one child' do
|
|
32
|
+
let(:parent_service1) { FactoryBot.create(:mdm_service, name: 'parent_service1') }
|
|
33
|
+
let(:child_service1) { FactoryBot.create(:mdm_service, name: 'child_service1') }
|
|
34
|
+
let!(:service_link1) { FactoryBot.create(:mdm_service_link, parent: parent_service1, child: child_service1) }
|
|
35
|
+
|
|
36
|
+
it 'should only destroy the child service' do
|
|
37
|
+
expect { service_link1.destroy }.to_not raise_error
|
|
38
|
+
expect { service_link1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
39
|
+
expect { child_service1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
40
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'with multiple children' do
|
|
44
|
+
let(:child_service2) { FactoryBot.create(:mdm_service, name: 'child_service2') }
|
|
45
|
+
let!(:service_link2) { FactoryBot.create(:mdm_service_link, parent: parent_service1, child: child_service2) }
|
|
46
|
+
|
|
47
|
+
it 'should only destroy the child service related to this service link' do
|
|
48
|
+
expect { service_link1.destroy }.to_not raise_error
|
|
49
|
+
expect { service_link1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
50
|
+
expect { service_link2.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
51
|
+
expect { child_service1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
52
|
+
expect { child_service2.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
53
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context 'with multiple nested children' do
|
|
58
|
+
let(:child_service2) { FactoryBot.create(:mdm_service, name: 'child_service2') }
|
|
59
|
+
let!(:service_link2) { FactoryBot.create(:mdm_service_link, parent: child_service1, child: child_service2) }
|
|
60
|
+
|
|
61
|
+
it 'should only destroy the nested child services and service links' do
|
|
62
|
+
expect { service_link1.destroy }.to_not raise_error
|
|
63
|
+
expect { service_link1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
64
|
+
expect { service_link2.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
65
|
+
expect { child_service1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
66
|
+
expect { child_service2.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
67
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'with a child that has another parent' do
|
|
72
|
+
let(:parent_service2) { FactoryBot.create(:mdm_service, name: 'parent_service2') }
|
|
73
|
+
let!(:service_link2) { FactoryBot.create(:mdm_service_link, parent: parent_service2, child: child_service1) }
|
|
74
|
+
|
|
75
|
+
it 'should not destroy the child' do
|
|
76
|
+
expect { service_link1.destroy }.to_not raise_error
|
|
77
|
+
expect { service_link1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
78
|
+
expect { service_link2.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
79
|
+
expect { child_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
80
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
81
|
+
expect { parent_service2.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "Associations" do
|
|
88
|
+
it { is_expected.to belong_to(:parent).class_name('Mdm::Service') }
|
|
89
|
+
it { is_expected.to belong_to(:child).class_name('Mdm::Service') }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context "validations" do
|
|
93
|
+
it "should not allow duplicate associations" do
|
|
94
|
+
parent_service = FactoryBot.build(:mdm_service)
|
|
95
|
+
child_service = FactoryBot.build(:mdm_service)
|
|
96
|
+
FactoryBot.create(:mdm_service_link, :parent => parent_service, :child => child_service)
|
|
97
|
+
service_link2 = FactoryBot.build(:mdm_service_link, :parent => parent_service, :child => child_service)
|
|
98
|
+
expect(service_link2).not_to be_valid
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context 'callbacks' do
|
|
103
|
+
context 'before_destroy' do
|
|
104
|
+
it 'should call #destroy_orphan_child' do
|
|
105
|
+
service_link = FactoryBot.create(:mdm_service_link)
|
|
106
|
+
expect(service_link).to receive(:destroy_orphan_child)
|
|
107
|
+
service_link.destroy
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
@@ -35,6 +35,10 @@ RSpec.describe Mdm::Service, type: :model do
|
|
|
35
35
|
it { is_expected.to have_many(:web_pages).class_name('Mdm::WebPage').through(:web_sites) }
|
|
36
36
|
it { is_expected.to have_many(:web_forms).class_name('Mdm::WebForm').through(:web_sites) }
|
|
37
37
|
it { is_expected.to have_many(:web_vulns).class_name('Mdm::WebVuln').through(:web_sites) }
|
|
38
|
+
it { is_expected.to have_many(:parent_links).class_name('Mdm::ServiceLink').dependent(:destroy) }
|
|
39
|
+
it { is_expected.to have_many(:parents).class_name('Mdm::Service').through(:parent_links) }
|
|
40
|
+
it { is_expected.to have_many(:child_links).class_name('Mdm::ServiceLink').dependent(:destroy) }
|
|
41
|
+
it { is_expected.to have_many(:children).class_name('Mdm::Service').through(:child_links) }
|
|
38
42
|
it { is_expected.to belong_to(:host).class_name('Mdm::Host') }
|
|
39
43
|
end
|
|
40
44
|
|
|
@@ -114,14 +118,70 @@ RSpec.describe Mdm::Service, type: :model do
|
|
|
114
118
|
end
|
|
115
119
|
|
|
116
120
|
context '#destroy' do
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
let(:service) { FactoryBot.create(:mdm_service) }
|
|
122
|
+
|
|
123
|
+
it 'should successfully destroy one Mdm::Service' do
|
|
124
|
+
expect { service.destroy }.to_not raise_error
|
|
125
|
+
expect { service.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context 'with one parent and one child' do
|
|
129
|
+
let(:parent_service1) { FactoryBot.create(:mdm_service, name: 'parent_service1') }
|
|
130
|
+
let(:child_service1) { FactoryBot.create(:mdm_service, name: 'child_service1') }
|
|
131
|
+
|
|
132
|
+
before :example do
|
|
133
|
+
service.parents << parent_service1
|
|
134
|
+
service.children << child_service1
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'should only destroy the child service' do
|
|
138
|
+
expect { service.destroy }.to_not raise_error
|
|
139
|
+
expect { service.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
140
|
+
expect { child_service1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
141
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context 'with multiple children' do
|
|
145
|
+
let(:child_service2) { FactoryBot.create(:mdm_service, name: 'child_service2') }
|
|
146
|
+
|
|
147
|
+
it 'should all the child services' do
|
|
148
|
+
service.children << child_service2
|
|
149
|
+
|
|
150
|
+
expect { service.destroy }.to_not raise_error
|
|
151
|
+
expect { service.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
152
|
+
expect { child_service1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
153
|
+
expect { child_service2.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
154
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context 'with multiple nested children' do
|
|
159
|
+
let(:child_service2) { FactoryBot.create(:mdm_service, name: 'child_service2') }
|
|
160
|
+
|
|
161
|
+
it 'should all the nested child services' do
|
|
162
|
+
child_service1.children << child_service2
|
|
163
|
+
|
|
164
|
+
expect { service.destroy }.to_not raise_error
|
|
165
|
+
expect { service.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
166
|
+
expect { child_service1.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
167
|
+
expect { child_service2.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
168
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
context 'with a child that has another parent' do
|
|
173
|
+
let(:parent_service2) { FactoryBot.create(:mdm_service, name: 'parent_service2') }
|
|
174
|
+
|
|
175
|
+
it 'should not destroy the child' do
|
|
176
|
+
child_service1.parents << parent_service2
|
|
177
|
+
|
|
178
|
+
expect { service.destroy }.to_not raise_error
|
|
179
|
+
expect { service.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
180
|
+
expect { child_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
181
|
+
expect { parent_service1.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
182
|
+
expect { parent_service2.reload }.to_not raise_error(ActiveRecord::RecordNotFound)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
125
185
|
end
|
|
126
186
|
end
|
|
127
187
|
|
|
@@ -222,7 +282,7 @@ RSpec.describe Mdm::Service, type: :model do
|
|
|
222
282
|
|
|
223
283
|
context 'when a duplicate service already exists' do
|
|
224
284
|
let(:service1) { FactoryBot.create(:mdm_service)}
|
|
225
|
-
let(:service2) { FactoryBot.build(:mdm_service, :host => service1.host, :port => service1.port, :proto => service1.proto )}
|
|
285
|
+
let(:service2) { FactoryBot.build(:mdm_service, :host => service1.host, :port => service1.port, :proto => service1.proto, :resource => service1.resource, :name => service1.name) }
|
|
226
286
|
it 'is not valid' do
|
|
227
287
|
expect(service2).to_not be_valid
|
|
228
288
|
end
|
|
@@ -133,6 +133,7 @@ RSpec.describe Mdm::Vuln, type: :model do
|
|
|
133
133
|
it { is_expected.to have_db_column(:origin_id).of_type(:integer) }
|
|
134
134
|
it { is_expected.to have_db_column(:origin_type).of_type(:string) }
|
|
135
135
|
it { is_expected.to have_db_column(:service_id).of_type(:integer) }
|
|
136
|
+
it { is_expected.to have_db_column(:resource).of_type(:jsonb) }
|
|
136
137
|
|
|
137
138
|
context 'counter caches' do
|
|
138
139
|
it { is_expected.to have_db_column(:vuln_attempt_count).of_type(:integer).with_options(:default => 0) }
|
|
@@ -12,6 +12,7 @@ FactoryBot.define do
|
|
|
12
12
|
port { generate :port }
|
|
13
13
|
proto { generate :mdm_service_proto }
|
|
14
14
|
state { 'open' }
|
|
15
|
+
resource { generate :mdm_service_resource }
|
|
15
16
|
|
|
16
17
|
factory :web_service do
|
|
17
18
|
proto { 'tcp' }
|
|
@@ -23,6 +24,10 @@ FactoryBot.define do
|
|
|
23
24
|
"mdm_service_name#{n}"
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
sequence(:mdm_service_resource) { |n|
|
|
28
|
+
{ "mdm_service_resource#{n}".to_sym => "mdm_service_resource_value#{n}" }
|
|
29
|
+
}
|
|
30
|
+
|
|
26
31
|
sequence :mdm_service_proto, Mdm::Service::PROTOS.cycle
|
|
27
32
|
|
|
28
33
|
port_bits = 16
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metasploit_data_models
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0.
|
|
4
|
+
version: 6.0.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Metasploit Hackers
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: metasploit-yard
|
|
@@ -326,6 +326,7 @@ files:
|
|
|
326
326
|
- app/models/mdm/ref.rb
|
|
327
327
|
- app/models/mdm/route.rb
|
|
328
328
|
- app/models/mdm/service.rb
|
|
329
|
+
- app/models/mdm/service_link.rb
|
|
329
330
|
- app/models/mdm/session.rb
|
|
330
331
|
- app/models/mdm/session_event.rb
|
|
331
332
|
- app/models/mdm/tag.rb
|
|
@@ -508,6 +509,11 @@ files:
|
|
|
508
509
|
- db/migrate/20180904120211_create_payloads.rb
|
|
509
510
|
- db/migrate/20190308134512_create_async_callbacks.rb
|
|
510
511
|
- db/migrate/20190507120211_remove_payload_workspaces.rb
|
|
512
|
+
- db/migrate/20250716155919_add_resource_to_mdm_vuln.rb
|
|
513
|
+
- db/migrate/20250717170556_add_resource_to_services.rb
|
|
514
|
+
- db/migrate/20250718122714_create_service_links.rb
|
|
515
|
+
- db/migrate/20250720082201_drop_service_uniqueness_index2.rb
|
|
516
|
+
- db/migrate/20250721114306_remove_duplicate_services3.rb
|
|
511
517
|
- lib/mdm.rb
|
|
512
518
|
- lib/mdm/host/operating_system_normalization.rb
|
|
513
519
|
- lib/mdm/module.rb
|
|
@@ -563,6 +569,7 @@ files:
|
|
|
563
569
|
- spec/app/models/mdm/profile_spec.rb
|
|
564
570
|
- spec/app/models/mdm/ref_spec.rb
|
|
565
571
|
- spec/app/models/mdm/route_spec.rb
|
|
572
|
+
- spec/app/models/mdm/service_link_spec.rb
|
|
566
573
|
- spec/app/models/mdm/service_spec.rb
|
|
567
574
|
- spec/app/models/mdm/session_event_spec.rb
|
|
568
575
|
- spec/app/models/mdm/session_spec.rb
|
|
@@ -681,6 +688,7 @@ files:
|
|
|
681
688
|
- spec/factories/mdm/payloads.rb
|
|
682
689
|
- spec/factories/mdm/refs.rb
|
|
683
690
|
- spec/factories/mdm/routes.rb
|
|
691
|
+
- spec/factories/mdm/service_links.rb
|
|
684
692
|
- spec/factories/mdm/services.rb
|
|
685
693
|
- spec/factories/mdm/session_events.rb
|
|
686
694
|
- spec/factories/mdm/sessions.rb
|