-
Notifications
You must be signed in to change notification settings - Fork 0
/
NessusCSVreportPrioritizer.ps1
261 lines (217 loc) · 12.2 KB
/
NessusCSVreportPrioritizer.ps1
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
<# RCAutomate.com
Parse a CSV File exported from Nessus reports, and categorize vulnerabilities by numerous priorities
Sort by highest priority vulnerabilities and by team to help delegate remediation.
Utilizing the following exported reporting values from CSV:
IP_Scope, SystemName, Family, Plugin, Plugin Name, Severity, IP Address, Protocol, Port, Exploit?, Repository, MAC Address, DNS Name, NetBIOS Name, Plugin Output, Exploit Frameworks, Synopsis, Description, Solution, CVSS V2 Base Score, CVSS V3 Base Score, CVE, First Discovered, Last Observed, Short Name, Vuln Publication Date, Patch Publication Date
We transform some of these default values to make them more easily calculable.
Prioritize First Observed since they likely have been exposed too long.
Create Definition file of Server name to Assignment
Report summary per user / machine, Sort by highest count.
Suggest Teams to work together on common matching vulnerabilities
Compare Teams Last vulns with this month's vulns, difference, include serverlist
Create category for imaging team: (workstation, vm, laptop)
Ping Ponging Recent/expired vulns (use full scan to locate duplicates, take the oldest first discovered date of all duplicates.)
Add previous month scan to compare differences
#>
#Modify Todays date for running retroactive reports (or date the report ran) get-date for today
$TodaysDate = Get-Date -Year 2024 -Month 12 -Day 31
#This Months report location
$Report = Import-CSV "C:\temp\12312024.csv"
#Last Months report to compare
#$LastReport = Import-CSV "C:\temp\11302024.csv"
<#Cleanup Report Duplicates - Assuming that Each unique host cannot have duplicate plugin vulnerability
for each unique DNS Name, , Sort by First Discovered, Select Oldest
$RepHostnames = ($Report)."DNS Name" | Sort-Object | Get-Unique
#Select Duplicate Plugin
foreach ($Rephost in $RepHostnames)
{Where ()}
($report | Sort-Object $_."Last Observed" | Get-Unique).plugin.count
$ReportDedupe += @([pscustomobject]@{Plugin=$_.Plugin;"Plugin Name"=$_."Plugin Name"})
#>
#Server Assignments
#Database team
$Team='Database'
$DBAServers=@('preprod01','oracle01','prod01','science01')
foreach ($server in $DBAServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#Solaris group
$Team='Solaris'
$VMWareServers=@('application04','db01')
foreach ($server in $VMWareServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#Programmers team
$Team='Developers'
$DevServers=@('docker01','app05','applauncher01')
foreach ($server in $DevServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#Linux/HPC/Quantum/Redhat
$Team='Linux'
$LinuxServers=@('linux20','linux22','linux23','cactiapp01')
foreach ($server in $LinuxServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#Windows Team
$Team='Windows'
$WindowsServers=@('DC01','DC02','administrator01','app07'`
,'fileserver01','citrixvda01')
foreach ($server in $WindowsServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#Vmware Team
$Team='VMware'
$VMWareServers=@('virtualhost01','virtualhost02','vcenter01')
foreach ($server in $VMWareServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#Shutdown: (machines that are shut down that shouldn't be on the report summary totals)
#manually populate these with machines having a scheduled imminent EOL date.
#This deprioritizes these vulnerabilities in the report.
$Team='Shutdown'
$ShutdownServers=@('Server2012-01','WindowsXP01','CentOSapps')
foreach ($server in $ShutdownServers){
$TeamAssignment += @([pscustomobject]@{Hostname=$server;Team=$Team})
}
#sort report by first discovered
#$sortedreport = $report | Sort-Object $_."First Discovered"
# Doesn't work: $CritSummary | Sort-Object $_.Date
foreach ($vuln in $report)
{
If (($vuln.Severity -eq "Critical") -or ($vuln.Severity -eq "High") -or ($vuln.Severity -eq "Medium"))
{
#strip clocktime from First discovered Date
$Date = (Get-Date ($vuln."First Discovered" -replace (" EDT"), ('') -replace (" EST"), (''))).ToString("s")
$Status = $vuln.Severity
#strip FQDN off DNS name
$Hostname = ($vuln."DNS Name" -replace (".contoso.com"), ('') -replace (".contoso"),(''))
$Plugin = $vuln."Plugin Name"
#Plugin Name Exceptions - These have too many unique variations but have common remediation actions
#Trying to combine them to optimize reporting
if (($Plugin -match "Oracle Database") -or ($Plugin -match "Oracle Java SE Multiple Vulnerabilities") -or ($Plugin -match "Oracle WebLogic") -or ($Plugin -match "Oracle Coherence"))
{
#Remove the Date or detailed info to combine similar vulns
$Plugin = $vuln."Plugin Name".Split('()')[0]
}
$IP = $vuln."IP Address"
$Metasploit = $vuln."Exploit?"
#Manual IP Address Assignments
#This is needed to fill the hostname where DNS entries are missing
#The DNS entries on these should be fixed, but this is a workaround until they do.
If ($IP -eq "192.168.1.136") {$Hostname="AppLaunch06"}
If ($IP -eq "192.168.1.134") {$Hostname="StorageHPC"}
If ($IP -eq "192.168.1.135") {$Hostname="ShutdownEndpoint"} #– cannot ping, maybe this device is no longer used?
#Add the team assignments to each vuln
$Assignment = ($TeamAssignment | Where-Object {$_.Hostname -eq $Hostname}).Team
#Assignment Exceptions
If (($Plugin -match "Oracle Database") -and ($Assignment -ne "Solaris") -and ($Assignment -ne "Database")) {$Assignment="Database"}
$CritSummary += @([pscustomobject]@{Date=$Date;Metasploit=$Metasploit;Status=$Status;Hostname=$Hostname;IP=$IP;Plugin=$Plugin;Team=$Assignment})
#Write-Host "Total Critical:" $CritSummary.status.count
}}
#Report precheck run
$UnassignedServers = ($CritSummary | where-object {$null -eq $_.Team}).Hostname | Sort-Object | Get-Unique
If ($null -ne $UnassignedServers)
{Write-Host "Please Assign the following servers and re-run the report"
$UnassignedServers}
$ServersMissingHostname = ($Report | where-object ({$_."DNS Name" -notmatch ".gov"})).'IP Address' | Sort-Object | Get-Unique
If ($null -ne $ServersMissingHostname)
{Write-Host "The following servers are missing DNS name resolution and will not be included in this summary. They need to be resolved manually in the CSV, or change the code to resolve static IPs."
$ServersMissingHostname}
#Total Critical
#Highest to lowest priority
Write-Host "Total CRITICAL Vulnerabilities:"
($CritSummary | Where-Object {$_.Status -eq 'Critical'}).count
Write-Host "Total High Vulnerabilities:"
($CritSummary | Where-Object {$_.Status -eq 'High'}).count
Write-Host "Total medium Vulnerabilities:"
($CritSummary | Where-Object {$_.Status -eq 'medium'}).count
Write-Host "\
\
"
#Internal application remediation timeline defined by NIST 800-53, or DISA STIG
$ThirtyDays = ($TodaysDate).AddDays(-30) #Critical/High
$SixtyDays = ($TodaysDate).AddDays(-60) #Medium
$NinetyDays = ($TodaysDate).AddDays(-90) #Low
<#Public Facing timeline:
$FifteenDays = (Get-Date).AddDays(-15) #Critical
Critical: 15 Days
High: 30 Days
Medium: 60 Days
Low: 90 Days
#>
#Critical First Observed > 30 days.
Write-Host "EXPIRED CRITICAL Vulnerabilities (Exceeds 30 day limit):"
($CritSummary | Where-Object ({($_.Status -eq 'Critical') -and (($_.Date | Get-Date) -lt $ThirtyDays)})).count
Write-Host "EXPIRED High Vulnerabilities (Exceeds 30 day limit):"
($CritSummary | Where-Object ({($_.Status -eq 'High') -and (($_.Date | Get-Date) -lt $ThirtyDays)})).count
Write-Host "EXPIRED medium Vulnerabilities (Exceeds 60 day limit):"
($CritSummary | Where-Object ({($_.Status -eq 'Medium') -and (($_.Date | Get-Date) -lt $SixtyDays)})).count
Write-Host "\
\
"
Write-Host "Recent CRITICAL Vulnerabilities (Within 30 day limit):"
($CritSummary | Where-Object ({($_.Status -eq 'Critical') -and (($_.Date | Get-Date) -gt $ThirtyDays)})).count
Write-Host "Recent High Vulnerabilities (Within 30 day limit):"
($CritSummary | Where-Object ({($_.Status -eq 'High') -and (($_.Date | Get-Date) -gt $ThirtyDays)})).count
Write-Host "Recent medium Vulnerabilities (Within 60 day limit):"
($CritSummary | Where-Object ({($_.Status -eq 'Medium') -and (($_.Date | Get-Date) -gt $SixtyDays)})).count
Write-Host "\
\
"
#For each team give a summary
$UniqueTeam = $TeamAssignment.Team | Get-Unique
foreach ($item in $UniqueTeam)
{
#Categorize by team (count servers managed) & User (Database, Programmers, Linux, Windows)
Write-Host "$item Team Summary"
Write-Host 'Recent Vulnerabilities 30 days (Crit/High/Med)'
($CritSummary | Where-Object ({($_.Team -eq $item) -and (($_.Date | Get-Date) -gt $ThirtyDays)})).count
Write-Host 'Team Vulnerabilities With Known Exploit (EXPLOITABLE - Crit/High/Med)'
($CritSummary | Where-Object ({($_.Team -eq $item) -and ($_.Metasploit -eq 'Yes')})).count
Write-Host 'EXPIRED Critical Vulnerabilities'
($CritSummary | Where-Object ({($_.Team -eq $item) -and (($_.Date | Get-Date) -lt $ThirtyDays) -and ($_.Status -eq 'Critical')})).count
Write-Host 'EXPIRED High Vulnerabilties'
($CritSummary | Where-Object ({($_.Team -eq $item) -and (($_.Date | Get-Date) -lt $ThirtyDays) -and ($_.Status -eq 'High')})).count
Write-Host 'EXPIRED Medium Vulnerabilties'
($CritSummary | Where-Object ({($_.Team -eq $item) -and (($_.Date | Get-Date) -lt $SixtyDays) -and ($_.Status -eq 'Medium')})).count
#Write-Host "Top 10 Common Vulnerabilities for $item Team"
#($CritSummary | Where-Object ({($_.Team -eq $item)})).Plugin | Group-Object -NoElement | Sort-Object -Property Count -Descending | Select-Object -first 10 | Format-Table -AutoSize
Write-Host "10 Latest Expired Critical Vulnerabiltiies for $item Team"
$CritSummary | Where-Object ({($_.Team -eq $item) -and (($_.Date | Get-Date) -lt $ThirtyDays) -and ($_.Status -eq 'Critical')}) | Select-Object Date,Plugin,Hostname | Sort-Object -Property Date -Descending | Select-Object -first 10 | Format-Table -AutoSize
Write-Host "Top 10 Common EXPLOITABLE Vulnerabilities for $item Team (Crit/High/Med)"
($CritSummary | Where-Object ({($_.Team -eq $item) -and ($_.Metasploit -eq 'Yes')})).plugin | Group-Object -NoElement | Sort-Object -Property Count -Descending | Select-Object -first 10 | Format-Table -AutoSize
Write-Host "Top 10 Common Critical Vulnerabilities for $item Team"
($CritSummary | Where-Object ({($_.Team -eq $item) -and ($_.Status -eq 'Critical')})).Plugin | Group-Object -NoElement | Sort-Object -Property Count -Descending | Select-Object -first 10 | Format-Table -AutoSize
#ADD: Sort Matching Count Critical Vulns by descending Critical Score
Write-Host "Top 5 Common High Vulnerabilities for $item Team"
($CritSummary | Where-Object ({($_.Team -eq $item) -and ($_.Status -eq 'High')})).Plugin | Group-Object -NoElement | Sort-Object -Property Count -Descending | Select-Object -first 5 | Format-Table -AutoSize
Write-Host "Top 5 Common Medium Vulnerabilities for $item Team"
($CritSummary | Where-Object ({($_.Team -eq $item) -and ($_.Status -eq 'Medium')})).Plugin | Group-Object -NoElement | Sort-Object -Property Count -Descending | Select-Object -first 5 | Format-Table -AutoSize
Write-Host "\
\
\
\
"
}
#Audit cleanup
#machines missing hostname ( use IP )
#($Report | where-object ({$_."DNS Name" -notmatch "hostprefix"}))
#machines not assigned to a group
#($CritSummary | where-object {$null -eq $_.Team}).Hostname | Sort-Object | Get-Unique
#Tools
#Loop to Echo machines having a common Vulnerability
do {
$i=1
$lookupTeam = Read-Host "Which Team do you want to look up?"
$lookupVuln = Read-Host "Which Vulnerability? (Full/partial plugin name)"
($CritSummary | Where-Object ({($_.Team -eq $lookupTeam) -and ($_.Plugin -match $lookupVuln)})).Hostname | Sort-Object | Get-Unique
} while ($i=1)
#Vulns on servers that have been shutdown
#Get list of High Expired Vuls
#($CritSummary | Where-Object ({($_.Team -eq $item) -and (($_.Date | Get-Date) -lt $ThirtyDays) -and ($_.Status -eq 'High')}) | Sort-Object -Property Date -Descending)
#Extended Detail By assignment group
#Newly discovered vulnerabilities (within allowed limits)
#Expired vulnerabilities (outside allowed limits)
#Find Exploitable
#($CritSummary | Where-Object ({($_.Metasploit -eq 'yes') -and ($_.Plugin -match $lookupVuln)})).Hostname | Sort-Object | Get-Unique