<# alan dot kaplan at va dot gov 10/15/2014, 11/7/2014 .Synopsis Imports a Nessus v2 Report file and combines the host data and vulnerablity data into a single object. .DESCRIPTION The Convert-Nessus cmdlet creates objects from Nessus v2 files that are generated by the Nessus 4.x or 5.x scanner. .NOTES 10/19/2014 version strips whitespace, excludes "0" severity from choices. This is because I couldn't figure out how to avoid broken output string with some of the plugin text 11/7/2014 adds Select Properties #> $scriptVer = "4.0" #Requires -version 3 Function Bail () { "Done." sleep 2 Exit } Function Select-PropertiesForm { #Initial code generated by #SAPIEN Technologies PrimalForms (Community Edition) v1.0.10.0 [CmdletBinding()] [OutputType([psObject])] Param ( # InputObject help description [Parameter(Mandatory=$True, Position=0)] $InputObject, # FormTitle help description [Parameter(Mandatory=$False, Position=1)] [string]$FormTitle="Select in order the properties to report, then accept list" ) $inputObject = ($InputObject| gm -MemberType *property).Name | sort #Region Import Assemblies Add-Type -assemblyname System.Windows.Forms Add-Type -assemblyname System.Drawing #EndRegion Import Assemblies #Region Clear Variables $Script:NewList ="" #EndRegion Clear Variables #region Form Objects $SelectForm = New-Object System.Windows.Forms.Form $CancelBtn = New-Object System.Windows.Forms.Button $AcceptBtn = New-Object System.Windows.Forms.Button $MoveLftBtn = New-Object System.Windows.Forms.Button $MoveRtBtn = New-Object System.Windows.Forms.Button $lb_NewList = New-Object System.Windows.Forms.ListBox $lb_OrigList = New-Object System.Windows.Forms.ListBox $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState #EndRegion Form Objects #---------------------------------------------- #Event Script Blocks #---------------------------------------------- $On_AcceptBtn_Click= { $Script:NewList = @() foreach ($item in $lb_NewList.Items){$Script:NewList += $item} $SelectForm.Close() } # Don't need this, because Cancel action is set in form definition, below # $On_CancelBtn_Click= # Begin by loading data passed to function $On_SelectForm_Load= { foreach($item in $InputObject) {$lb_OrigList.items.add($item)} } #Click the move left button removes from New list and puts back item to the original list $On_MoveLftBtn_Click= { $movelist = @() foreach ($item in $lb_NewList.SelectedItems){$movelist += $item} foreach($item in $movelist){ $lb_NewList.items.remove($item) $lb_OrigList.items.add($item) } } #Click the move right button removes from original list and puts item to the new list $On_MoveRtBtn_Click= { $movelist = @() foreach ($item in $lb_OrigList.SelectedItems){$movelist += $item} foreach($item in $movelist){ $lb_OrigList.items.remove($item) $lb_NewList.items.add($item) } } $OnLoadForm_StateCorrection= {#Sapien says this corrects the initial state of the form to prevent the .Net maximized form issue $SelectForm.WindowState = $InitialFormWindowState } #---------------------------------------------- #region Form Code $SelectForm.CancelButton = $CancelBtn $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 378 $SysDrawSize.Width = 632 $SelectForm.ClientSize = $SysDrawSize $SelectForm.DataBindings.DefaultDataSourceUpdateMode = 0 $SelectForm.Name = "SelectForm" $SelectForm.Text = $FormTitle $SelectForm.add_Load($On_SelectForm_Load) #Cancel Button $CancelBtn.DataBindings.DefaultDataSourceUpdateMode = 0 $CancelBtn.DialogResult = 2 $SysDrawPoint = New-Object System.Drawing.Point $SysDrawPoint.X = 255 $SysDrawPoint.Y = 219 $CancelBtn.Location = $SysDrawPoint $CancelBtn.Name = "CancelBtn" $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 26 $SysDrawSize.Width = 75 $CancelBtn.Size = $SysDrawSize $CancelBtn.TabIndex = 5 $CancelBtn.Text = "Cancel" $CancelBtn.UseVisualStyleBackColor = $True $CancelBtn.add_Click($On_CancelBtn_Click) $SelectForm.Controls.Add($CancelBtn) #Accept Button $AcceptBtn.DataBindings.DefaultDataSourceUpdateMode = 0 $SysDrawPoint = New-Object System.Drawing.Point $SysDrawPoint.X = 255 $SysDrawPoint.Y = 177 $AcceptBtn.Location = $SysDrawPoint $AcceptBtn.Name = "AcceptBtn" $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 23 $SysDrawSize.Width = 75 $AcceptBtn.Size = $SysDrawSize $AcceptBtn.TabIndex = 4 $AcceptBtn.Text = "Accept List" $AcceptBtn.UseVisualStyleBackColor = $True $AcceptBtn.add_Click($On_AcceptBtn_Click) $SelectForm.Controls.Add($AcceptBtn) #Move Left Button $MoveLftBtn.DataBindings.DefaultDataSourceUpdateMode = 0 $SysDrawPoint = New-Object System.Drawing.Point $SysDrawPoint.X = 255 $SysDrawPoint.Y = 111 $MoveLftBtn.Location = $SysDrawPoint $MoveLftBtn.Name = "MoveLftBtn" $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 45 $SysDrawSize.Width = 75 $MoveLftBtn.Size = $SysDrawSize $MoveLftBtn.TabIndex = 3 $MoveLftBtn.Text = "<< Move" $MoveLftBtn.UseVisualStyleBackColor = $True $MoveLftBtn.add_Click($On_MoveLftBtn_Click) $SelectForm.Controls.Add($MoveLftBtn) #Move Right Button $MoveRtBtn.DataBindings.DefaultDataSourceUpdateMode = 0 $MoveRtBtn.Enabled = $True $SysDrawPoint = New-Object System.Drawing.Point $SysDrawPoint.X = 255 $SysDrawPoint.Y = 38 $MoveRtBtn.Location = $SysDrawPoint $MoveRtBtn.Name = "MoveRtBtn" $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 45 $SysDrawSize.Width = 75 $MoveRtBtn.Size = $SysDrawSize $MoveRtBtn.TabIndex = 2 $MoveRtBtn.Text = "Move >>" $MoveRtBtn.UseVisualStyleBackColor = $True $MoveRtBtn.add_Click($On_MoveRtBtn_Click) $SelectForm.Controls.Add($MoveRtBtn) #Left Panel original data $lb_OrigList.DataBindings.DefaultDataSourceUpdateMode = 0 $lb_OrigList.FormattingEnabled = $True $SysDrawPoint = New-Object System.Drawing.Point $SysDrawPoint.X = 12 $SysDrawPoint.Y = 2 $lb_OrigList.Location = $SysDrawPoint $lb_OrigList.Name = "listBox1" $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 355 $SysDrawSize.Width = 235 $lb_OrigList.Size = $SysDrawSize $lb_OrigList.TabIndex = 0 $lb_origList.SelectionMode = "multiExtended" $SelectForm.Controls.Add($lb_OrigList) #Right Panel new data $lb_NewList.DataBindings.DefaultDataSourceUpdateMode = 0 $lb_NewList.FormattingEnabled = $True $SysDrawPoint = New-Object System.Drawing.Point $SysDrawPoint.X = 344 $SysDrawPoint.Y = 2 $lb_NewList.Location = $SysDrawPoint $lb_NewList.Name = "listBox2" $SysDrawSize = New-Object System.Drawing.Size $SysDrawSize.Height = 355 $SysDrawSize.Width = 235 $lb_NewList.Size = $SysDrawSize $lb_NewList.TabIndex = 1 $lb_NewList.SelectionMode = "multiExtended" $SelectForm.Controls.Add($lb_NewList) #EndRegion Form Code #Save the initial state of the form $InitialFormWindowState = $SelectForm.WindowState #Init the OnLoad event to correct the initial state of the form $SelectForm.add_Load($OnLoadForm_StateCorrection) #Show the Form $SelectForm.ShowDialog()| Out-Null #Return the value from the function if ($Script:NewList[0].Count -eq 0){ Write-Warning "Nothing selected" Exit }ELSE{ $Script:NewList Return } } Function Get-FileSizeString ($path){ switch ((get-item $path).Length) { {$_ -ge 1TB} { "{0:n2}" -f ($_ / 1TB) + " TB";Break} {$_ -ge 1GB} { "{0:n2}" -f ($_ / 1GB) + " GB";Break} {$_ -ge 1MB} { "{0:n2}" -f ($_ / 1MB) + " MB";Break} Default {"{0:n2}" -f ($size / 1KB) + " KB"} } } Function Get-OpenFile($title, $filter,$initialDirectory) { add-type -assemblyname System.Windows.Forms $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog $OpenFileDialog.initialDirectory = $initialDirectory $OpenFileDialog.filter = $filter $OpenFileDialog.Title = $title $OpenFileDialog.ShowDialog() | Out-Null $OpenFileDialog.filename $OpenFileDialog.ShowHelp = $true } #list of items you want from HostData $props = "host-ip,mac-address,host-fqdn,netbios-name,system-type,operating-system,HOST_START,HOST_END".Split(",") $NessusFile = Get-OpenFile -title "Convert-Nessus $scriptVer. Choose a .nessus file" -filter "Nessus Files (*.nessus)|*.nessus" -initialDirectory "$env:USERPROFILE\desktop" if ($nessusFile -eq ""){Bail} Write-Host "Reading $nessusFile" $fsize = Get-FileSizeString($NessusFile) write-host "File is $fsize" $nessus = [xml] (get-content $NessusFile) #Get Basic vulnerability data $VulData = $Nessus.NessusClientData_v2.Report.ReportHost.reportItem Write-Host "Done. Now processing data ..." $VulData | foreach { #Add the Host Info data $HostInfo = $_.ParentNode.HostProperties.ChildNodes for($j=0; $j -lt $HostInfo.Count; $j++){ $itemName =($HostInfo[$j].name).ToString() if ($itemName -iin $props){ $itemValue = ($HostInfo[$j]."#text").ToString() #remove line breaks and leading whitespace #$itemValue = $itemValue -replace '[\t\r\n]',"" if (($itemValue).contains(":")){ #convert scan date to US date format $regex = "^(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(0[1-9]|[12][0-9]|3[01])\s(\d{2}:\d{2}:\d{2})\s(\d{4})" if ($itemValue.trim() -match $regex){ $y = $Matches[5] $m = $Matches[2] $t = $Matches[4] $d = $Matches[3] $itemvalue = [datetime]"$m $d, $y $t" } } Add-Member -InputObject $_ -membertype NoteProperty -Name $itemName -value $itemValue } } } write-host "Select Report Properties from form" $props = Select-PropertiesForm $Vuldata #exclude information only $sevList = ($VulData | select -expandproperty severity -Unique | where {$_ -gt 0} |sort ) -join ", " [int]$SevVal = Read-Host "Report only items with this"` "Minimum Severity Value (choose a value in `"$sevlist`")" #example output, save as CSV file #use a select statement to choose results in different order $outfile = $NessusFile.Replace(".nessus",".xls") $vuldata | where {$_.severity -ge $SevVal} |select $props | Export-Csv -Path $outfile -NoTypeInformation -Delimiter "`t" write-host "Script complete" Write-host "Report file is $outfile"