metasploit_data_models 0.16.4-java → 0.16.5-java
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
@@ -2,7 +2,7 @@
|
|
2
2
|
name: metasploit_data_models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.16.
|
5
|
+
version: 0.16.5
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Samuel Huckins
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-07-
|
15
|
+
date: 2013-07-16 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rake
|