metasploit_data_models 0.16.4 → 0.16.5
Sign up to get free protection for your applications and to get access to all the features.
@@ -3,20 +3,98 @@
|
|
3
3
|
class EnforceAddressUniquenessInWorkspaceInHosts < ActiveRecord::Migration
|
4
4
|
TABLE_NAME = :hosts
|
5
5
|
|
6
|
+
# maps Table -> Association Column for models that "belong to" a Host
|
7
|
+
HOST_ASSOCIATION_MAP = {
|
8
|
+
'clients' => 'host_id',
|
9
|
+
'events' => 'host_id',
|
10
|
+
'exploit_attempts' => 'host_id',
|
11
|
+
'exploited_hosts' => 'host_id',
|
12
|
+
'host_details' => 'host_id',
|
13
|
+
'hosts_tags' => 'host_id',
|
14
|
+
'loots' => 'host_id',
|
15
|
+
'notes' => 'host_id',
|
16
|
+
'sessions' => 'host_id',
|
17
|
+
'services' => 'host_id',
|
18
|
+
'vulns' => 'host_id'
|
19
|
+
}
|
20
|
+
|
21
|
+
# Historically there a few scenarios where a user could end up with Hosts
|
22
|
+
# in the same workspace with the same IP. Primarily, if you run a Nexpose Scan
|
23
|
+
# and a Discover scan simultaneously, AR does not know about these separate
|
24
|
+
# transactions, so the Hosts will be valid when added and the user will end up
|
25
|
+
# (when transaction completes) with two hosts with the same IP in the same workspace.
|
26
|
+
#
|
27
|
+
# Since we are adding a DB uniq constraint here, this migration could fail if the user
|
28
|
+
# has hit aforementioned scenarios. So we try to "merge" any hosts with the same
|
29
|
+
# address in the same workspace before adding the DB constraint, to prevent the
|
30
|
+
# migration from simply failing.
|
31
|
+
#
|
32
|
+
# Note: We can't rely on AR directly here (or in any migration), since we have no
|
33
|
+
# idea what version of the code the user has checked out. So we fall back to SQL :(
|
34
|
+
def find_and_merge_duplicate_hosts!
|
35
|
+
# find all duplicate addresses within the same workspace currently in the db
|
36
|
+
dupe_addresses_and_workspaces = ActiveRecord::Base.connection.execute(%Q{
|
37
|
+
SELECT workspace_id, address, count_addr
|
38
|
+
FROM (
|
39
|
+
SELECT workspace_id, address, COUNT(address) AS count_addr
|
40
|
+
FROM hosts
|
41
|
+
GROUP BY address, workspace_id
|
42
|
+
) X
|
43
|
+
WHERE count_addr > 1
|
44
|
+
})
|
45
|
+
|
46
|
+
if dupe_addresses_and_workspaces.present? and
|
47
|
+
not dupe_addresses_and_workspaces.num_tuples.zero?
|
48
|
+
puts "Duplicate hosts in workspace found. Merging host references."
|
49
|
+
# iterate through the duped IPs
|
50
|
+
dupe_addresses_and_workspaces.each do |result|
|
51
|
+
# so its come to this
|
52
|
+
address = ActiveRecord::Base.connection.quote(result['address'])
|
53
|
+
workspace_id = result['workspace_id'].to_i
|
54
|
+
# look up the duplicate Host table entries to find all IDs of the duped Hosts
|
55
|
+
hosts = ActiveRecord::Base.connection.execute(%Q|
|
56
|
+
SELECT id
|
57
|
+
FROM hosts
|
58
|
+
WHERE address=#{address} AND workspace_id=#{workspace_id}
|
59
|
+
ORDER BY id DESC
|
60
|
+
|)
|
61
|
+
# grab and quote the ID for each result row
|
62
|
+
hosts = hosts.map { |h| h["id"].to_i }
|
63
|
+
# grab every Host entry besides the first one
|
64
|
+
first_host_id = hosts.first
|
65
|
+
dupe_host_ids = hosts[1..-1]
|
66
|
+
# update associations to these duplicate Hosts
|
67
|
+
HOST_ASSOCIATION_MAP.each do |table, column|
|
68
|
+
ActiveRecord::Base.connection.execute(%Q|
|
69
|
+
UPDATE #{table} SET #{column}=#{first_host_id}
|
70
|
+
WHERE #{column} IN (#{dupe_host_ids.join(',')})
|
71
|
+
|)
|
72
|
+
end
|
73
|
+
# destroy the duplicate host rows
|
74
|
+
ActiveRecord::Base.connection.execute(%Q|
|
75
|
+
DELETE FROM hosts WHERE id IN (#{dupe_host_ids.join(',')})
|
76
|
+
|)
|
77
|
+
end
|
78
|
+
|
79
|
+
# At this point all duped hosts in the same workspace should be merged.
|
80
|
+
# You could end up with duplicate services, but hey its better than just
|
81
|
+
# dropping all data about the old Host.
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
6
85
|
# Restores old index on address
|
7
86
|
def down
|
8
87
|
change_table TABLE_NAME do |t|
|
9
88
|
t.remove_index [:workspace_id, :address]
|
10
|
-
|
11
89
|
t.index :address
|
12
90
|
end
|
13
91
|
end
|
14
92
|
|
15
93
|
# Make index on address scope to workspace_id and be unique
|
16
94
|
def up
|
95
|
+
find_and_merge_duplicate_hosts!
|
17
96
|
change_table TABLE_NAME do |t|
|
18
97
|
t.remove_index :address
|
19
|
-
|
20
98
|
t.index [:workspace_id, :address], :unique => true
|
21
99
|
end
|
22
100
|
end
|
@@ -4,5 +4,5 @@ module MetasploitDataModels
|
|
4
4
|
# metasploit-framework/data/sql/migrate to db/migrate in this project, not all models have specs that verify the
|
5
5
|
# migrations (with have_db_column and have_db_index) and certain models may not be shared between metasploit-framework
|
6
6
|
# and pro, so models may be removed in the future. Because of the unstable API the version should remain below 1.0.0
|
7
|
-
VERSION = '0.16.
|
7
|
+
VERSION = '0.16.5'
|
8
8
|
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metasploit_data_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.16.
|
4
|
+
version: 0.16.5
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Samuel Huckins
|
@@ -11,11 +12,12 @@ authors:
|
|
11
12
|
autorequire:
|
12
13
|
bindir: bin
|
13
14
|
cert_chain: []
|
14
|
-
date: 2013-07-
|
15
|
+
date: 2013-07-16 00:00:00.000000000 Z
|
15
16
|
dependencies:
|
16
17
|
- !ruby/object:Gem::Dependency
|
17
18
|
name: rake
|
18
19
|
requirement: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
19
21
|
requirements:
|
20
22
|
- - ! '>='
|
21
23
|
- !ruby/object:Gem::Version
|
@@ -23,6 +25,7 @@ dependencies:
|
|
23
25
|
type: :development
|
24
26
|
prerelease: false
|
25
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
26
29
|
requirements:
|
27
30
|
- - ! '>='
|
28
31
|
- !ruby/object:Gem::Version
|
@@ -30,6 +33,7 @@ dependencies:
|
|
30
33
|
- !ruby/object:Gem::Dependency
|
31
34
|
name: yard
|
32
35
|
requirement: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
33
37
|
requirements:
|
34
38
|
- - ! '>='
|
35
39
|
- !ruby/object:Gem::Version
|
@@ -37,6 +41,7 @@ dependencies:
|
|
37
41
|
type: :development
|
38
42
|
prerelease: false
|
39
43
|
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
40
45
|
requirements:
|
41
46
|
- - ! '>='
|
42
47
|
- !ruby/object:Gem::Version
|
@@ -44,6 +49,7 @@ dependencies:
|
|
44
49
|
- !ruby/object:Gem::Dependency
|
45
50
|
name: pry
|
46
51
|
requirement: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
47
53
|
requirements:
|
48
54
|
- - ! '>='
|
49
55
|
- !ruby/object:Gem::Version
|
@@ -51,6 +57,7 @@ dependencies:
|
|
51
57
|
type: :development
|
52
58
|
prerelease: false
|
53
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
54
61
|
requirements:
|
55
62
|
- - ! '>='
|
56
63
|
- !ruby/object:Gem::Version
|
@@ -58,6 +65,7 @@ dependencies:
|
|
58
65
|
- !ruby/object:Gem::Dependency
|
59
66
|
name: activerecord
|
60
67
|
requirement: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
61
69
|
requirements:
|
62
70
|
- - ! '>='
|
63
71
|
- !ruby/object:Gem::Version
|
@@ -65,6 +73,7 @@ dependencies:
|
|
65
73
|
type: :runtime
|
66
74
|
prerelease: false
|
67
75
|
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
68
77
|
requirements:
|
69
78
|
- - ! '>='
|
70
79
|
- !ruby/object:Gem::Version
|
@@ -72,6 +81,7 @@ dependencies:
|
|
72
81
|
- !ruby/object:Gem::Dependency
|
73
82
|
name: activesupport
|
74
83
|
requirement: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
75
85
|
requirements:
|
76
86
|
- - ! '>='
|
77
87
|
- !ruby/object:Gem::Version
|
@@ -79,6 +89,7 @@ dependencies:
|
|
79
89
|
type: :runtime
|
80
90
|
prerelease: false
|
81
91
|
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
82
93
|
requirements:
|
83
94
|
- - ! '>='
|
84
95
|
- !ruby/object:Gem::Version
|
@@ -86,6 +97,7 @@ dependencies:
|
|
86
97
|
- !ruby/object:Gem::Dependency
|
87
98
|
name: redcarpet
|
88
99
|
requirement: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
89
101
|
requirements:
|
90
102
|
- - ! '>='
|
91
103
|
- !ruby/object:Gem::Version
|
@@ -93,6 +105,7 @@ dependencies:
|
|
93
105
|
type: :development
|
94
106
|
prerelease: false
|
95
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
96
109
|
requirements:
|
97
110
|
- - ! '>='
|
98
111
|
- !ruby/object:Gem::Version
|
@@ -100,6 +113,7 @@ dependencies:
|
|
100
113
|
- !ruby/object:Gem::Dependency
|
101
114
|
name: pg
|
102
115
|
requirement: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
103
117
|
requirements:
|
104
118
|
- - ! '>='
|
105
119
|
- !ruby/object:Gem::Version
|
@@ -107,6 +121,7 @@ dependencies:
|
|
107
121
|
type: :runtime
|
108
122
|
prerelease: false
|
109
123
|
version_requirements: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
110
125
|
requirements:
|
111
126
|
- - ! '>='
|
112
127
|
- !ruby/object:Gem::Version
|
@@ -437,26 +452,33 @@ files:
|
|
437
452
|
- spec/support/shared/examples/mdm/module/detail/supports_stance_with_mtype.rb
|
438
453
|
homepage: ''
|
439
454
|
licenses: []
|
440
|
-
metadata: {}
|
441
455
|
post_install_message:
|
442
456
|
rdoc_options: []
|
443
457
|
require_paths:
|
444
458
|
- lib
|
445
459
|
required_ruby_version: !ruby/object:Gem::Requirement
|
460
|
+
none: false
|
446
461
|
requirements:
|
447
462
|
- - ! '>='
|
448
463
|
- !ruby/object:Gem::Version
|
449
464
|
version: '0'
|
465
|
+
segments:
|
466
|
+
- 0
|
467
|
+
hash: -1502167183498467311
|
450
468
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
469
|
+
none: false
|
451
470
|
requirements:
|
452
471
|
- - ! '>='
|
453
472
|
- !ruby/object:Gem::Version
|
454
473
|
version: '0'
|
474
|
+
segments:
|
475
|
+
- 0
|
476
|
+
hash: -1502167183498467311
|
455
477
|
requirements: []
|
456
478
|
rubyforge_project:
|
457
|
-
rubygems_version:
|
479
|
+
rubygems_version: 1.8.25
|
458
480
|
signing_key:
|
459
|
-
specification_version:
|
481
|
+
specification_version: 3
|
460
482
|
summary: Database code for MSF and Metasploit Pro
|
461
483
|
test_files:
|
462
484
|
- spec/app/models/mdm/client_spec.rb
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
ZDhiOTE4MWQ2Y2YzMDQ4YzYyODE4MWQyNTg0ODNlY2Q1ZTg5NTIyOA==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MTc2ZTEyYjJiYjc4OTFiZWMzZWZmMTZjYjFjMTBhN2QxZjcyNDM1Mg==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MDNiODM5MzVlNzljMTM4NTFmYjk1ZmIyMmZjMWU2NTBmMjI4ZDc1NDU1M2I0
|
10
|
-
MDBmY2I1NDM3ZmQ0NzIxNTIzZmNkMzMxN2MxZmI1MzM5ZDNiZTQwMjIyYmZm
|
11
|
-
YWNiZTA5MTdmNmE4NGU0MDUwOTk3MGQ2MDgwOTY5OWQ5YmUzZDc=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
N2YzNGQxMDM1NTNiNDg4YTg0M2YwZjMxY2VmY2NlOGI1ZDBlM2EwN2U1YzZi
|
14
|
-
NzQ0NGYzMGIzYmRhN2JlOTg1NzA4ODRkMjI3MDU4NDk5OTg0YzI1YjVhYzdl
|
15
|
-
NmMyNjIzNWViOGNkNjA2YWQxZWJhMWYwNzNiNjg1MDA3MzRhYmM=
|