metasploit_data_models 6.0.9 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74538eeddece124d46bfbc8b75ed8cfbdff4e3817d2d043ce378277085a84be4
4
- data.tar.gz: 8bdb64d936ab097ed960eafb3e6a4681d8e456ed87a6aa1c6bde7054754590ca
3
+ metadata.gz: d5c3b6ba17aa68aa354fd30e709e371bdc703e48bfab8bf1ab1e01d220c7a136
4
+ data.tar.gz: cf14f60355752907e3d87333cc6d6946295745ff69ee0ca0ebd6e24afd88a77d
5
5
  SHA512:
6
- metadata.gz: 3155ae51fcf684a115ca902c96987ee867bde52f0017cf790f92e352039e5ab4bceefb300af00c79b068871542527e153ded49699b93493d3ca92d23e8f725c1
7
- data.tar.gz: '0678de3dff2f00feb24b6b3a0be2adeaa89e716bdcad744a62efb6bca4a521e16767058fc4e14e7b5851c60c5eedf50e6410887d672ed93234d20149a15de7f9'
6
+ metadata.gz: c800409a016366908e074694cd8f8bf22bd0112ef77c99e738b6ed97c269f319b15afda791e82969e287dcbc03e318e374b378c92be207a5261d7564ab7ff6ca
7
+ data.tar.gz: 34851f917756daf8fdf85018147d7178052c15a21e3177dad4730e29b199b0d9c64ac7177118e82bdc37fbb00a8bfdbef7ffddb22dd6610caa7d7b8ff1dab7a9
@@ -25,71 +25,14 @@ on:
25
25
  - '*'
26
26
 
27
27
  jobs:
28
- test:
29
- runs-on: ${{ matrix.os }}
30
- timeout-minutes: 40
31
-
32
- services:
33
- postgres:
34
- image: postgres:9.6
35
- ports: ["5432:5432"]
36
- env:
37
- POSTGRES_USER: postgres
38
- POSTGRES_PASSWORD: postgres
39
- options: >-
40
- --health-cmd pg_isready
41
- --health-interval 10s
42
- --health-timeout 5s
43
- --health-retries 5
44
-
45
- strategy:
46
- fail-fast: true
47
- matrix:
48
- ruby:
49
- - '2.7'
50
- - '3.0'
51
- - '3.1'
52
- - '3.2'
53
- rails:
54
- - '~> 7.0.0'
55
- - '~> 7.1.0'
56
- os:
57
- - ubuntu-22.04
58
- - ubuntu-latest
59
- exclude:
60
- - { os: ubuntu-latest, ruby: '2.7' }
61
- - { os: ubuntu-latest, ruby: '3.0' }
62
-
63
- env:
64
- RAILS_ENV: test
65
-
66
- name: ${{ matrix.os }} - Ruby ${{ matrix.ruby }} - Rails ${{ matrix.rails }}
67
- steps:
68
- - name: Install system dependencies
69
- run: sudo apt-get install libpcap-dev graphviz
70
-
71
- - name: Checkout code
72
- uses: actions/checkout@v4
73
-
74
- - name: Setup Ruby
75
- uses: ruby/setup-ruby@v1
76
- with:
77
- ruby-version: ${{ matrix.ruby }}
78
- bundler-cache: true
79
-
80
- - name: Update Rails version
81
- run: |
82
- ruby -pi.bak -e "gsub(/gem ['\"]rails['\"],\s*['\"].+['\"]?/, \"gem 'rails', '${{ matrix.rails }}'\")" Gemfile
83
- bundle update
84
- bundle install
85
-
86
- - name: Test
87
- run: |
88
- cp spec/dummy/config/database.yml.github_actions spec/dummy/config/database.yml
89
- bundle exec rake --version
90
- bundle exec rake db:create db:migrate
91
-
92
- # Disabling this check because it is proving unreliable
93
- # git diff --exit-code spec/dummy/db/structure.sql
94
- bundle exec rake spec
95
- bundle exec rake yard
28
+ build:
29
+ uses: rapid7/metasploit-framework/.github/workflows/shared_gem_verify_rails.yml@master
30
+ with:
31
+ dependencies: '["libpcap-dev", "graphviz"]'
32
+ test_commands: |
33
+ cp spec/dummy/config/database.yml.github_actions spec/dummy/config/database.yml
34
+ bundle exec rake --version
35
+ bundle exec rake db:create db:migrate
36
+ bundle exec rake spec
37
+ bundle exec rake spec
38
+ bundle exec rake yard
@@ -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
+
@@ -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,5 @@
1
+ class AddResourceToMdmVuln < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :vulns, :resource, :jsonb, null: false, default: {}
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddResourceToServices < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :services, :resource, :jsonb, null: false, default: {}
4
+ end
5
+ end
@@ -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,5 @@
1
+ class DropServiceUniquenessIndex2 < ActiveRecord::Migration[7.0]
2
+ def change
3
+ remove_index(:services, :host_id_and_port_and_proto)
4
+ end
5
+ end
@@ -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
@@ -44,6 +44,7 @@ module Mdm
44
44
  autoload :WmapRequest
45
45
  autoload :WmapTarget
46
46
  autoload :Workspace
47
+ autoload :ServiceLink
47
48
 
48
49
  # Causes the model_name for all Mdm modules to not include the Mdm:: prefix in their name.
49
50
  #
@@ -1,6 +1,6 @@
1
1
  module MetasploitDataModels
2
2
  # VERSION is managed by GemRelease
3
- VERSION = '6.0.9'
3
+ VERSION = '6.0.11'
4
4
 
5
5
  # @return [String]
6
6
  #
@@ -46,6 +46,15 @@ Gem::Specification.new do |s|
46
46
  # arel-helpers: Useful tools to help construct database queries with ActiveRecord and Arel.
47
47
  s.add_runtime_dependency 'arel-helpers'
48
48
 
49
+ # Standard libraries: https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/
50
+ %w[
51
+ bigdecimal
52
+ drb
53
+ mutex_m
54
+ ].each do |library|
55
+ s.add_runtime_dependency library
56
+ end
57
+
49
58
  if RUBY_PLATFORM =~ /java/
50
59
  # markdown formatting for yard
51
60
  s.add_development_dependency 'kramdown'
@@ -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
- it 'should successfully destroy the object' do
118
- service = FactoryBot.create(:mdm_service)
119
- expect {
120
- service.destroy
121
- }.to_not raise_error
122
- expect {
123
- service.reload
124
- }.to raise_error(ActiveRecord::RecordNotFound)
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) }
@@ -0,0 +1,8 @@
1
+ # Read about factories at https://github.com/thoughtbot/factory_bot
2
+
3
+ FactoryBot.define do
4
+ factory :mdm_service_link, :class => 'Mdm::ServiceLink' do
5
+ association :parent, :factory => :mdm_service
6
+ association :child, :factory => :mdm_service
7
+ end
8
+ end
@@ -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.9
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-04-01 00:00:00.000000000 Z
11
+ date: 2025-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: metasploit-yard
@@ -206,6 +206,48 @@ dependencies:
206
206
  - - ">="
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: bigdecimal
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: drb
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: mutex_m
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
209
251
  - !ruby/object:Gem::Dependency
210
252
  name: redcarpet
211
253
  requirement: !ruby/object:Gem::Requirement
@@ -284,6 +326,7 @@ files:
284
326
  - app/models/mdm/ref.rb
285
327
  - app/models/mdm/route.rb
286
328
  - app/models/mdm/service.rb
329
+ - app/models/mdm/service_link.rb
287
330
  - app/models/mdm/session.rb
288
331
  - app/models/mdm/session_event.rb
289
332
  - app/models/mdm/tag.rb
@@ -466,6 +509,11 @@ files:
466
509
  - db/migrate/20180904120211_create_payloads.rb
467
510
  - db/migrate/20190308134512_create_async_callbacks.rb
468
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
469
517
  - lib/mdm.rb
470
518
  - lib/mdm/host/operating_system_normalization.rb
471
519
  - lib/mdm/module.rb
@@ -521,6 +569,7 @@ files:
521
569
  - spec/app/models/mdm/profile_spec.rb
522
570
  - spec/app/models/mdm/ref_spec.rb
523
571
  - spec/app/models/mdm/route_spec.rb
572
+ - spec/app/models/mdm/service_link_spec.rb
524
573
  - spec/app/models/mdm/service_spec.rb
525
574
  - spec/app/models/mdm/session_event_spec.rb
526
575
  - spec/app/models/mdm/session_spec.rb
@@ -639,6 +688,7 @@ files:
639
688
  - spec/factories/mdm/payloads.rb
640
689
  - spec/factories/mdm/refs.rb
641
690
  - spec/factories/mdm/routes.rb
691
+ - spec/factories/mdm/service_links.rb
642
692
  - spec/factories/mdm/services.rb
643
693
  - spec/factories/mdm/session_events.rb
644
694
  - spec/factories/mdm/sessions.rb