Parsing Nessus CSV Reports with PowerShell

Recently in the Pauldotcom Podcast Paul was mentioning how he uses Awk, cut and other bash tools to process a Nessus CSV report file and format the host output so he could use it in another tool. I saw his command and thought I would do it in PowerShell for kicks since PowerShell turns each row in to an object I can manipulate. Lets take a look at the Import-Csv cmandlet and what are the members of the object it returns:

Import-Csv C:\Users\carlos\Desktop\nessus.csv | Get-Member
   TypeName: System.Management.Automation.PSCustomObject
Name          MemberType   Definition                                                              
----          ----------   ----------                                                              
Equals        Method       bool Equals(System.Object obj)                                          
GetHashCode   Method       int GetHashCode()                                                       
GetType       Method       type GetType()                                                          
ToString      Method       string ToString()                                                       
CVE           NoteProperty System.String CVE=N/A                                                   
CVSS          NoteProperty System.String CVSS=                                                     
Description   NoteProperty System.String Description=One of several ports that were previously o...
Host          NoteProperty System.String Host=                                        
Name          NoteProperty System.String Name=Open Port Re-check                                   
Plugin ID     NoteProperty System.String Plugin ID=10919                                           
Plugin Output NoteProperty System.String Plugin Output=Port 49156 was detected as being open but...
Port          NoteProperty System.String Port=0                                                    
Protocol      NoteProperty System.String Protocol=tcp                                              
Risk          NoteProperty System.String Risk=None                                                 
Solution      NoteProperty System.String Solution=- increase checks_read_timeout and/or reduce m...
Synopsis      NoteProperty System.String Synopsis=Previously open ports are now closed. 

We can see that the Nessus data for each plugin that ran is represented as NoteProperty for the object as a string. Lets see if I have some vulnerabilities found that it reports as being High for this we will use the Where-Object cmdlet to filter the objects:

 Import-Csv C:\Users\carlos\Desktop\nessus.csv | where {$_.risk -eq "high"}
Plugin ID     : 53382
CVE           : CVE-2010-3190
CVSS          : 9.3
Risk          : High
Host          :
Protocol      : tcp
Port          : 445
Name          : MS11-025: Vulnerability in Microsoft Foundation Class (MFC) Library Could Allow 
                Remote Code Execution (2500212)
Synopsis      : Arbitrary code can be executed on the remote host through the Microsoft Foundation 
                Class library.
Description   : The remote Windows host contains a version of the Microsoft Foundation Class (MFC) 
                library affected by an insecure library loading vulnerability.  The path used for 
                loading external libraries is not securely restricted. 
                An attacker can exploit this by tricking a user into opening an MFC application in 
                a directory that contains a malicious DLL, resulting in arbitrary code execution.
Solution      : Microsoft has released a set of patches for Visual Studio .NET 2003, 2005, and 
                2008, as well as Visual C++ 2005, 2008, and 2010 :
Plugin Output : 
                The following Visual C++ Redistributable Package has not
                been patched : 
                  Product           : Visual C++ 2008 SP1 Redistributable Package
                  Installed version : 9.0.30729.4148
                  Fixed version     : 9.0.30729.6161
Great we found several. One advantage is that PowerShell is not case sensitive in it's operators unless you implicitly specify it, this allows me to specify the risk and “hight” and the value being capitalized . Now lets say I want to know what hosts have high vulnerabilities and only want their IP returned, for this we will use the Select-Object cmdlet and only get unique entries:
Import-Csv C:\Users\carlos\Desktop\nessus.csv | where {$_.risk -eq "high"} | select host -Unique

We could also filter by plugin if we are performing a pentest and what to come up with list of targets to feed to a tool piping it to the cmdlet out-file and giving it a file to save the IP’s to.

If we like doing all of the matching and sorting in a GUI interface we can take a look of the results in a grid view. Lets look at high, medium and low vulnerabilities and we will look at the Plugin ID, CVE, CVSS, Risk, Host, Protocol, Port and Name:

Import-Csv C:\Users\carlos\Desktop\nessus.csv | where {"high","medium","low" -contains $_.risk} | select "Plugin ID", CVE, CVSS, Risk, Host, Protocol, Port, Name | Out-GridView

This would bring up the following screen for us to filter and sort the information in a graphical manner:


Now what if we want to turn the data in to an HTML Report, well PowerShell also allows us to do it using the ConvertTo-Html cmdlet and turn it in to an HTML report in list format:

Import-Csv C:\Users\carlos\Desktop\nessus.csv | where {"high","medium","low" -contains $_.risk} | select "Plugin ID", CVE, CVSS, Risk, Host, Protocol, Port, Name | ConvertTo-Html -As List > report.html

This will create a report that looks like this:


One could go even fancier with pre-made CSS and HTML templates, but I will leave that for you to explore.