├── NessusCSVScanParser.ps1 └── README.md /NessusCSVScanParser.ps1: -------------------------------------------------------------------------------- 1 | #Powershell script for nessus scans 2 | #Nessus Scans are hard to investigate. Also, csv export can't be imported directly to excel. 3 | #This tool is used for manipulating csv scan files. Excel can directly import new csv scan file. 4 | # 5 | #2016 anilyuk 6 | 7 | 8 | [CmdletBinding(DefaultParameterSetName="ShowHelp")] 9 | param( 10 | [Parameter(Mandatory=$True,ParameterSetName="WriteToSameDirectory",Position=0)] 11 | [Parameter(Mandatory=$True,ParameterSetName="WriteToDifferentDirectory",Position=0)] 12 | [string] 13 | $i, 14 | 15 | ##CSV delimeter 16 | [string] 17 | $d = "#", 18 | 19 | [Parameter(Mandatory=$True,ParameterSetName="WriteToDifferentDirectory",Position=1)] 20 | [string] 21 | $o, 22 | 23 | [Parameter(Mandatory=$True,ParameterSetName="WriteToSameDirectory",Position=1)] 24 | [switch] 25 | $s, 26 | 27 | [Parameter(Mandatory=$True,ParameterSetName="ShowHelp")] 28 | [switch] 29 | $h, 30 | 31 | #host based listing 32 | [switch] 33 | $ho 34 | 35 | ) 36 | 37 | function showHelp{ 38 | 39 | echo "" 40 | echo "Parse Nessus exported csv file and convert to Excel friendly CSV." 41 | echo "Usage: .\NessusCSVScanParser.ps1 -i C:\ScanResult\Scan1.csv -s" 42 | echo "" 43 | echo " -i Full path of scan file(Only .csv file, Full path must be stated!)" 44 | echo " -s Write Output .csv to same directory" 45 | echo " -o Write output to differenf directory (Full path must be stated!)" 46 | echo " -d Csv file delimeter (Default is #)" 47 | echo " -ho Change listing to host based (Default is Plugin Based)" 48 | echo " -Verbose Enable verbose logging" 49 | echo "" 50 | echo "" 51 | 52 | } 53 | 54 | $global:scanFile = "" 55 | $global:outputFile = "" 56 | 57 | function setFiles{ 58 | 59 | $global:scanFile = $i 60 | 61 | $inputFileName = ($scanFile -split "\\")[-1] 62 | $inputFileDir = $scanFile -split "$(($scanFile -split "\\")[-1])" 63 | 64 | if($ho){ 65 | 66 | $outPutFileName = ($inputFileName -split "\.csv")[0] + "_HostBased_Output.csv" 67 | 68 | }else{ 69 | 70 | $outPutFileName = ($inputFileName -split "\.csv")[0] + "_PluginBased_Output.csv" 71 | 72 | } 73 | 74 | 75 | if($s){ 76 | 77 | $global:outputFile = $inputFileDir[0].Trim("\\") + "\" + $outPutFileName 78 | 79 | }else{ 80 | 81 | $outFileDir = $o 82 | $global:outputFile = $outFileDir.Trim("\\") + "\" + $outPutFileName 83 | 84 | } 85 | 86 | 87 | Write-Verbose "Input File: $scanFile" 88 | Write-Verbose "Output Dir: $outputFile" 89 | 90 | } 91 | 92 | function pluginBasedListing{ 93 | 94 | echo "Plugin based listing selected" 95 | 96 | Write-Verbose "Reading plugins (this may take long time...)" 97 | $pluginInformations = $importedCSV | select "Plugin ID", "CVEText", "CVSS", "Risk", "Name", "Synopsis", "Description", "Solution", "HostText" -Unique 98 | echo "$($pluginInformations.length) plugins found." 99 | Write-Verbose "Reading hosts." 100 | $hostCsvList = $importedCSV | select "Plugin ID", "Host", "Port" ,"Protocol" -Unique 101 | Write-Verbose "Reading CVEs." 102 | $cveCsvList = $importedCSV | select "Plugin ID", "CVE" -Unique 103 | 104 | echo "Processing vulnerabilities..." 105 | 106 | foreach($plugin in $pluginInformations){ 107 | 108 | $hostList = $hostCsvList | where {$_."Plugin ID" -eq $plugin."Plugin ID"} | select "Host", "Port" ,"Protocol" -Unique 109 | 110 | $plugin."Solution" = $plugin."Solution" -replace "`n"," " 111 | $plugin."Synopsis" = $plugin."Synopsis" -replace "`n"," " 112 | $plugin."Name" = $plugin."Name" -replace "`n"," " 113 | $plugin."Description" = $plugin."Description" -replace "`n"," " 114 | 115 | 116 | Write-Verbose "Processed $current/$($pluginInformations.length) plugins" 117 | Write-Verbose "------------------------------------------------------------------" 118 | 119 | Write-Verbose "Processing Plugin ID: $($plugin."Plugin ID")" 120 | Write-Verbose "Plugin ID: $($plugin."Plugin ID") affects $($hostList.length) hosts and services" 121 | $hostsText = "" 122 | if(($hostList) -is [system.array]){ 123 | 124 | for($i = 0; $i -lt ($hostList).length; $i++){ 125 | 126 | if($i -lt ($hostList).length -1){ 127 | 128 | $hostsText += "$(($hostList)[$i]."Host") ($(($hostList)[$i]."Protocol")/$(($hostList)[$i]."Port")), " 129 | $plugin."HostText" = $hostsText 130 | 131 | }else{ 132 | 133 | $hostsText += "$(($hostList)[$i]."Host") ($(($hostList)[$i]."Protocol")/$(($hostList)[$i]."Port"))" 134 | $plugin."HostText" = $hostsText 135 | 136 | } 137 | 138 | } 139 | 140 | }else { 141 | 142 | $hostsText += "$(($hostList)."Host") ($(($hostList)."Protocol")/$(($hostList)."Port"))" 143 | $plugin."HostText" = $hostsText 144 | 145 | } 146 | 147 | $cveList = $cveCsvList | where {$_."Plugin ID" -eq $plugin."Plugin ID"} | select "CVE" -Unique 148 | 149 | $cveText = "" 150 | 151 | if(($cveList) -is [system.array]){ 152 | 153 | for($i = 0; $i -lt ($cveList).length; $i++){ 154 | 155 | if($i -lt ($cveList).length -1){ 156 | 157 | $cveText += "$(($cveList)[$i]."CVE"), " 158 | $plugin."CVEText" = $cveText 159 | 160 | }else{ 161 | 162 | $cveText += "$(($cveList)[$i]."CVE")" 163 | $plugin."CVEText" = $cveText 164 | 165 | } 166 | 167 | } 168 | 169 | }else{ 170 | 171 | $cveText = "$($cveList."CVE")" 172 | $plugin."CVEText" = $cveText 173 | 174 | } 175 | 176 | Write-Verbose "------------------------------------------------------------------" 177 | 178 | $current++ 179 | 180 | $text = "$($plugin."Plugin ID")$d $($plugin."CVEText")$d $($plugin."CVSS") $d $($plugin."Risk")$d $($plugin."Name")$d $($plugin."Synopsis")$d $($plugin."Description")$d $($plugin."Solution")$d $($plugin."HostText")" 181 | echo $text >> $outputFile 182 | 183 | } 184 | 185 | } 186 | 187 | function hostBasedListing{ 188 | 189 | echo "Host based listing selected" 190 | 191 | Write-Verbose "Reading plugins (this may take long time...)" 192 | $pluginInformations = $importedCSV | select "Plugin ID", "CVEText", "CVSS", "Risk", "Name", "Synopsis", "Description", "Solution", "Host", "Port", "Protocol" -Unique 193 | echo "$($pluginInformations.length) plugins found." 194 | Write-Verbose "Reading CVEs." 195 | $cveCsvList = $importedCSV | select "Plugin ID", "CVE" -Unique 196 | 197 | echo "Processing vulnerabilities..." 198 | 199 | foreach($plugin in $pluginInformations){ 200 | 201 | $plugin."Solution" = $plugin."Solution" -replace "`n"," " 202 | $plugin."Synopsis" = $plugin."Synopsis" -replace "`n"," " 203 | $plugin."Name" = $plugin."Name" -replace "`n"," " 204 | $plugin."Description" = $plugin."Description" -replace "`n"," " 205 | 206 | Write-Verbose "Processed $current/$($pluginInformations.length) plugins" 207 | Write-Verbose "------------------------------------------------------------------" 208 | 209 | Write-Verbose "Processing Plugin ID: $($plugin."Plugin ID")" 210 | 211 | $hostsText = "$($plugin."Host") ($($plugin."protocol")/$($plugin."port"))" 212 | 213 | $plugin."Host" = $hostsText 214 | 215 | $cveList = $cveCsvList | where {$_."Plugin ID" -eq $plugin."Plugin ID"} | select "CVE" -Unique 216 | 217 | $cveText = "" 218 | 219 | if(($cveList) -is [system.array]){ 220 | 221 | for($i = 0; $i -lt ($cveList).length; $i++){ 222 | 223 | if($i -lt ($cveList).length -1){ 224 | 225 | $cveText += "$(($cveList)[$i]."CVE"), " 226 | $plugin."CVEText" = $cveText 227 | 228 | }else{ 229 | 230 | $cveText += "$(($cveList)[$i]."CVE")" 231 | $plugin."CVEText" = $cveText 232 | 233 | } 234 | 235 | } 236 | 237 | }else{ 238 | 239 | $cveText = "$($cveList."CVE")" 240 | $plugin."CVEText" = $cveText 241 | 242 | 243 | } 244 | 245 | Write-Verbose "------------------------------------------------------------------" 246 | 247 | $current++ 248 | 249 | $text = "$($plugin."Plugin ID")$d $($plugin."CVEText")$d $($plugin."CVSS") $d $($plugin."Risk")$d $($plugin."Name")$d $($plugin."Synopsis")$d $($plugin."Description")$d $($plugin."Solution")$d $($plugin."Host")" 250 | echo $text >> $outputFile 251 | 252 | } 253 | } 254 | 255 | $global:current = 0 256 | $global:importedCSV = "" 257 | 258 | function ProcessVulnerabilities{ 259 | 260 | Try{ 261 | 262 | $importedCSV = Import-Csv $scanFile -ErrorAction Stop 263 | 264 | } 265 | Catch{ 266 | 267 | Write-Verbose "ERROR: Problem with csv file." 268 | 269 | } 270 | Finally{ 271 | 272 | Write-Verbose -Message "Scan file imported." 273 | 274 | } 275 | 276 | echo "Plugin ID$d CVE$d CVSS$d Risk$d Name$d Synopsis$d Description$d Solution$d Hosts" > $outputFile 277 | 278 | if($ho){ 279 | 280 | hostBasedListing 281 | 282 | }else{ 283 | 284 | pluginBasedListing 285 | 286 | } 287 | 288 | } 289 | 290 | 291 | 292 | if($h){ 293 | 294 | showHelp 295 | 296 | }else{ 297 | 298 | setFiles 299 | ProcessVulnerabilities 300 | 301 | } 302 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nessus-CSV-Scan-Parser 2 | 3 | Parse exported CSV file and create Excel friendly CSV. 4 | 5 | Usage: nessusCSVScanParser.ps1 d:\ScanResults\Scan1.csv 6 | 7 | -i [File] Full path of scan file(Only .csv file, Full path) 8 | -s Write Output .csv to same directory 9 | -o [Directory] Write output to differenf directory (Full path) 10 | -d [Delimeter] Csv file delimeter (Default is #) 11 | -ho Change listing to host based (Default is Plugin Based) 12 | -Verbose Enable verbose 13 | --------------------------------------------------------------------------------