Nessus and Powershell is like Chocolate and Peanut Butter!

Published: 2015-12-02
Last Updated: 2015-12-02 15:32:47 UTC
by Rob VandenBrink (Version: 1)
9 comment(s)

In a typical security assessment, you'll do authenticated scans of internal hosts, looking for vulnerabilities due to missed patches or configuration issues.  I often use Nessus for this, but find that for a typical IT manager, the Nessus findings can be overwhelming. While a pentester might look for a specific Java or Flash vulnerability, the IT manager doesn't want to know that "station x has 26 Java vulnerabiities".  They want to know that "station x needs Java updated, and this is how not updating will affect the business.  In a perfect world, that same IT manager might also ask "why exactly do we have Flash and Java installed all over the place?", but maybe that's a story for a different day.

Anyway, on a typical, medium sized network, you can count on hundreds of thousands of findings in an authenticated Nessus scan.  In years past, I would have written some fancy sed / cut scripts to slice and dice this data, or maybe import the lot into a database and start from there on analysis.  Today though, I'm using Powershell - it's free, it's easy, and it's installed everywhere already, so your client can replicate both the findings and the process.

First, let's import the CSV file that we get from Nessus.  From the count, you can see exactly why this process can be so useful:

 

Let's take a look at the data structure:

 

First, let's look for flash Player issues.  We're searching for all non-zero risk findings - Risk=zero just means "we found flash"

Now on to the useful part - which hosts are affected?  Many of these hosts have dozens of discrete flash vulnerabilities, but for the IT manager, the "fix list" is the first important thing, and the second is "how do we prevent this going forward?"

Next we'll tackle Java.  Not the "or" operator (|), and also that the match operator is case insensitive.  Be careful though, because field names are *definitely* case sensitive. It's easy to get a "zero" result if you mess up on case and accidentally end up querying an empty variable.  For Java, in this example we cut the 50,000-ish findings down to a short, useful list of 222.

So, what other issues do you want to hunt for, to whittle that total down?

Adobe Reader (note that I'm making sure to not double-count Flash issues here)
$adobe = $all | Where-Object {$_.Description -match “Adobe Reader” -And $_.Description -notmatch "Flash" -and $_.Risk -notmatch "None"}  

.NET Framework:
$dotnet = $all | Where-Object {$_.Description -match "Net Framework" -and $_.Risk -notmatch "None" }
Silverlight:
$silverlight = $all | Where-Object {$_.Description -match "Silverlight" -and $_.Description -notmatch ".Net" -and $_.Risk -notmatch "None" }

Office:
$msoffice = $all | Where-Object {$_.Synopsis -match '(Office|Word|Powerpoint|Excel|Outlook)' -and $_.Risk -notmatch "None" }

Microsoft Patches, Security Advisories and Service Packs:
$misc_microsoft = $whatsleft | Where-Object {$_.Name -match '(MS[0-9][0-9]-[0-9][0-9][0-9]|MS KB|MS Security Advisory|Windows Service Pack)' }

Yes, even in 2015, in most shops of any size, you'll always find one or two hosts that have never had a patch or a service pack installed

After all that, what's left?  Note that the query is broken up, mostly so you can read it:

$whatsleft = $all | Where-Object { $_.Description -notmatch '(Flash|Adobe|JRE|JSE|JAVA|Java|jre|jse)'} | Where-Object {$_.Name -notmatch '(Silverlight|Net Framework|Office|Word|Powerpoint|Excel|Outlook|Explorer)'} | Where-Object {$_.Name -notmatch '(MS[0-9][0-9]-[0-9][0-9][0-9]|MS KB|MS Security Advisory|Windows Service Pack)' } | Where-Object {$_.Risk -notmatch "None"}

The final summary of issues is:
$final_summary = $whatsleft2 | select 'Plugin ID', Name | Group-Object 'Plugin ID' | Sort-Object -Descending Count

To view just the issues:
$final_summary | Out-GridView

Back to the IT manager who needs "the list" though, we still need to deal with this host-by-host.

$summary_by_host = $whatsleft2 | select Host,'Plugin ID', Name | Sort-Object Host

Then dump that list to CSV:

$final_summary_by_host | Export-Csv ./final-summary.csv
Import that csv file into Excel, make a pivot table, and you've got a nice, compact "which host has what problem" report!

===============
Rob VandenBrink
Compugen

Keywords: Nessus Powershell
9 comment(s)

Comments

Good tutorial but something I would mention that helps skim a lot of the noise right off the top is making sure in Nessus you disable the "Show missing patches that have been superseded" in the scan policy. Tenable does a fairly good job of monitoring patches and mapping when there are ones that are superseded. This reduce the findings to the top most level, e.g., instead of a system reporting it is missing 4 Java updates, Nessus will only say it is missing the 1 most recent version as that is really the patch/update you will be applying at the end of the day.
This is similar to what I've been doing with Microsoft's LogParser for years. Are you aware of a good tutorial on converting LogParser SQL-type scripts into PowerShell format? I'd rather use a built-in tool, one that is actually supported and getting updates.
Good tutorial. May be a bit off-topic, but my challenge is getting IT Manager to patch the vulnerabilities found. He doesn't want his guys having to go through a big spreadsheet, line by line. He wants to keep track of who did what. That's where I think the vulnerability assessment solutions such as Nessus, Tenable, etc. fall short: the operation side. Does anyone have a process/procedure that has worked to tackle this?
about the operational part of vulnerability management, we had some success with the following process:
- let the reports reach the sysadmins directly, weekly
- instruct them to solve one top vulnerability or one top host per week (or month), that's already better than nothing. Over time, you will see the improvements
- require them to provide feedback for the most critical ones: mitigation planned (but may take some time to install the new release in prod), risk accepted (will do nothing/not relevant in context), and filter future reports accordingly
- provide a graphical view of the improvements over time, as well as the feedback completeness -> monthly KPI for management

This forces the sysadmins to have a look at the weekly reports and critical issues, and devise a plan (even if it takes months...). If you are not happy with the plan, this should go to Risk Management, where management can accept the risk or provide resource to the sysadmins to solve the issue. This is usually seen as positive from the sysadmins (they actually want to solve the issues, but are often under pressure. This brings back the pressure to management).

At the same time, management sees what is done or planned, and if nothing moves has the duty to find out why (no resource, no interest, ...)
import-csv? You can work directly with the .nessus file in PS since it is XML:

[xml]$Nessusfile = gc $PathToNessusFile

From there you can walk through the XML structure and pull out the parts you want to look at. Also, regarding the process to patch vulnerabilities, I typically take what I get from a scan, enter a ticket into our internal ticketing system, and assign the appropriate parties (helpdesk or system admins typically) to patch. This will both make sure the responsible parties are aware of the vulnerabilities and make it easy to report on patching timeframes to fix them.
"I typically take what I get from a scan, enter a ticket into our internal ticketing system, and assign the appropriate parties (helpdesk or system admins typically) to patch. This will both make sure the responsible parties are aware of the vulnerabilities and make it easy to report on patching timeframes to fix them."
Well, that's EXACTLY what our IT Manager doesn't want: a long list of vulnerabilities to go through them one by one! And honestly I can't blame him: his guys have already enough on their plates. Now on top of that, they have A LOT more. In addition, what you usually get from a scan is not well organized & contains lot of unnecessary information.
Sorry I should have been more specific. I don't take raw output from the scan and dump it on other groups to patch copy-and-paste style. I go through the results and pick the highest priority patches that are actually "resolvable" to get done by the other groups. "Resolvable" means the other groups are actually able to apply patches or modify configurations to resolve the vulnerabilities as opposed to reporting a Java vulnerability on a server that is unable to be patched because the software vendor says the new, patched version will break the app. Then once they finish those, take the next set of high priority patches and feed those to the other groups. It is an iterative process.

It is not their job to understand and sort through the long list of patches and figure out what needs to be done. It is yours. You need to understand your org's security vulnerabilities and drive a process to resolve them by working within your IT department. A process that works for one org may not translate to another so I recommend this to get started:

1. YOU need to go through the scan results and understand them inside and out. Why a particular vulnerability exists on a given system and how the scanner determined it was a vulnerability (file version, banner grabbing, etc...). Start with the "Critical" and "High" vulnerabilities first.

2. Look beyond the "Critical" and "High" vulnerabilities at the rest of the results. What does all this "unnecessary" (at first glance) information mean and why is it in the results? Start asking questions..."Huh that's weird there is an "Info" finding for a telnet server on one of my clients. Why is that there?" or "The scanner is reporting one of my clients listening on port 13337. What process is listening on that client and is that uncommon on my network?"

3. Sit down with the relevant people in your IT department and start to develop a process for getting the vulnerabilities and questions you identified above resolved. Don't be discouraged if the process you come up with doesn't work out as planned and be open to adjustments. It may take time to iron out over time as the other groups get used to it.
Hi Rob
This is excellent. Is there a way I can update an add another field and update that field conditionally. Some thing like a add a member called category to the array as undefined based on your conditions update record with the category. So for example records with Adobe will have category as adobe

Thanks in advance
Hi Rob
This is excellent. Is there a way I can update an add another field and update that field conditionally. Some thing like a add a member called category to the array as undefined based on your conditions update record with the category. So for example records with Adobe will have category as adobe

Thanks in advance

Diary Archives