-
Notifications
You must be signed in to change notification settings - Fork 28
/
merge_issues_by_title.js
145 lines (129 loc) · 4.56 KB
/
merge_issues_by_title.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* eslint-disable no-unused-vars */
/* globals Session Hosts Issues Meteor */
function getHostList(Issue){
var hosts = '';
for(var i=0;i<Issue.hosts.length;i++){
hosts += Issue.hosts[i].ipv4 + ',';
}
return hosts + '\n';
}
function mergeIssuesByTitle (issueRegex, newTitle, cvss) {
// Merges all issues identified by a regular expression into a new or existing Issue
// provided by newTitle.
//
// Usage: mergeIssuesByTitle(/^VMSA.*/, 'Multiple VMWare Vulneraiblities', 10.0)
// Created by: Tom Steele
// Requires client-side updates: false
//
// I highly recommend you perform a dry run yourself and see what issues the regex is going
// to match, something like the following should do.
//
/*
var testVulnSearch = function(testRegex) {
// Test your regex search criteria prior
// to using it for vuln merging in Lair.
// Created by: Ryan Dorey
// Usage: testVulnSearch(/^.*SSH/)
// Requires client-side updates: false
var projectId = Session.get('projectId')
var issues = Issues.find({'projectId': projectId, 'title': {'$regex': testRegex}}).fetch()
issues.forEach(function(Issue) {
console.log('Title: ' + Issue.title + ' - CVSS: ' + Issue.cvss)
})
console.log('Total found: ' + issues.length)
}
*/
// Do some light variable checking, you're still pretty much on your own
if (typeof issueRegex !== 'object') {
return console.log('Issue regex can not be a string, must be a object')
}
if (typeof newTitle !== 'string') {
return console.log('Invalid title')
}
if (typeof cvss !== 'number') {
return console.log('Invalid cvss. Variable must be a number')
}
var projectId = Session.get('projectId')
var issues = Issues.find({
'projectId': projectId,
'title': {
'$regex': issueRegex
}
}).fetch()
if (issues.length < 1) {
return console.log('Did not find any issues with the given regex')
}
// If the Issue given in newTitle already exists, then we push it onto the regex list so we can combine them
// Remove the existing Issue first
var existingVenerability = Issues.findOne({
'projectId': projectId,
'title': newTitle
})
if (typeof existingVenerability !== 'undefined') {
issues.push(existingVenerability)
Meteor.call('removeIssue', projectId, existingVenerability._id)
}
console.log('Going to merge ' + issues.length + ' issues')
var newDescription = ''
var newSolution = ''
var newEvidence = ''
var newNotes = []
var cves = []
var hostList = []
// Loop over each Issue and combine the data
issues.forEach(function (Issue) {
issue_hosts = getHostList(Issue);
newDescription += '\n\n' + 'From ' + Issue.title + '\n' + 'Affected Hosts: ' + issue_hosts + Issue.description;
newSolution += '\n\n' + 'From ' + Issue.title + '\n' + 'Affected Hosts: ' + issue_hosts + Issue.solution;
newEvidence += '\n\n' + 'From ' + Issue.title + '\n' + 'Affected Hosts: ' + issue_hosts + Issue.evidence;
newNotes = newNotes.concat(Issue.notes)
cves = cves.concat(Issue.cves)
hostList = hostList.concat(Issue.hosts)
})
var newHostList = unique(hostList)
var newCVEs = unique(cves)
// Create the new Issue
Meteor.call('createIssue', projectId, newTitle, cvss, newDescription, newEvidence, newSolution, function (err, res) {
if (err) {
console.log('Error: could not create new Issue', err.message)
if (existingVenerability) {
console.log('Looks like you lost', existingVenerability.title)
}
} else {
addExistingContentToVenerability(res)
}
})
return console.log('Complete')
// Adds notes, hosts, and cves to new vulnerablity
function addExistingContentToVenerability (IssueId) {
newNotes.forEach(function (note) {
Meteor.call('addIssueNote', projectId, IssueId, note.title, note.content)
})
newHostList.forEach(function (host) {
Meteor.call('addHostToIssue', projectId, IssueId, host.ipv4, host.port, host.protocol)
})
newCVEs.forEach(function (cve) {
Meteor.call('addCVE', projectId, IssueId, cve)
})
removeIssues()
}
// Loop over all issues and remove them
function removeIssues () {
issues.forEach(function (Issue) {
Meteor.call('removeIssue', projectId, Issue._id)
})
}
// I found this off the internet
function unique (arr) {
var hash = {}
var result = []
for (var i = 0, l = arr.length; i < l; ++i) {
var objString = JSON.stringify(arr[i])
if (!hash.hasOwnProperty(objString)) {
hash[objString] = true
result.push(arr[i])
}
}
return result
}
}