Today I am demonstration how to proactively work with the results from a vulnerability scanner to secure a server. I will set up a vulnerability scanner to scan a server in my test lab in order to discover how it appears to attackers running similar tools. We will touch upon fixing low hanging fruits and then move onto patch auditing.
Let’s get started!
My server is hosted in my personal test lab and the setup consists of:
The CentOS installation is set up to mirror a software configuration I see often in the wild.
Stage 1: Preparation
For this demonstration I downloaded Nessus and registered for a license. I settled for the Home edition because it’s free and allows me to scan up to 16 IP’s pr. registered license. This is great for evaluation and lab purposes.This Nessus instance will be hosted on my Parrot OS VM.
A side note here: there are other vulnerability scanners offered for free with a personal or community license. For instance, Rapid7 offers their Nexpose scanner for free with similar limitations as Nessus. It’s a great product and I urge you to try that one too!
For CentOS I used the minimal installation ISO as installation media. I originally intended this demo to cover Red Hat Enterprise Linux but landed on CentOS instead since it’s free and easy to obtain. Red Hat offers a 30 day evaluation license for free, but you must register to obtain it.
The CentOS installation is then prepped with the following software which forms the LAMPP stack:
Every service is then set up to run at boot time. I will not cover the installation of said software. The following tutorials will push you in the right direction if you chose to tag along:
Stage 2: Creating scan policy
The base methodology is to perform a baseline scan on an installation of a LAMPP enabled CentOS server. I will then analyze the scan results and make some alterations to the software configuration and then re-scan to validate the changes. The scan will be a plain perimeter scan, but I will also touch upon credentialed scan to tackle some cumbersome piece of software.
The first step is to create a custom scanning policy based on the “Advanced Scan” policy already available in Nessus.
Under “General” in “Assessment” I have enabled “Override normal accuracy” and “Show potential false alarms”. Normally we would prefer to remove false alarms since they often bring much noise into our reports. False alarms are also referred to as “false positives“.
To make sure that Nessus touches PHP on my server I have enabled the following settings under “Web Applications”. Don’t worry about the input boxes in black. It’s only Parrot OS being annoying – these are intentionally left as is.
Stage 3: First perimeter scan
The first scan came up with some interesting information. We got vulnerability of every category available and there’s 61 of them! This is an exaggeration. But first let me explain the concept of classification.
Nessus classifies vulnerabilities in the following severity categories:
The general way to handle vulnerabilities is to start resolving vulnerabilities from the highest category, “Critical”, and then move on further down the stack. At the very end we find the “Info” class.
The lowest category contain mainly information about the scan and general information about the target.Typically these are abundant, but stilling counting in the total vulnerability count. This class isn’t exactly where’s the meat is, but don’t discard them totally. There may be evidence there pointing to findings the scanner didn’t pick up.
The following screenshot displays how many vulnerabilities there are in each category:
Drilling down we see that Nessus have had a field day reporting mostly on “unsafe” versions of PHP and OpenSSH.
Stage 3: Removing application banners
Most of the vulnerabilities detected stems from software banners being picked up. Vulnerability scanners picking up such banners is typical behavior and can be combated somewhat easily.
Let’s look at how we can disable the banners:
Handling PHP version leakage
Whenever serving PHP over the web the PHP version is leaked in the “X-Powered-By” HTTP header field. This feature can be turned off by setting the PHP.ini directive “expose_php” to “Off”. Remember to restart the web server for changes to take effect.
Handling Apache version leakage
Apache leak version information on status pages, error pages and in HTTP headers. To combat this change Apache configuration accordingly:
- ServerSignature Off
- ServerTokens Prod
Remember to reload or restart the web server for changes to take effect.
Handling OpenSSH version leakage
So far so good in making CentOS appear less appealing for attackers. Now comes the sad part. Due to Red Hat and CentOS way of handling backporting we’re stuck with broadcasting which version of OpenSSH we’re using. To pour even more gasoline on the bonfire, the OpenSSH FAQ states that we can’t disable this broadcast:
This information is used by clients and servers to enable protocol compatibility tweaks to work around changed, buggy or missing features in the implementation they are talking to. This protocol feature checking is still required at present because versions with incompatibilities are still in wide use
However there’s a directive called “Banner” in the “sshd_config” file you can set to “no”. It is unclear what exactly this directive does. It doesn’t hurt to set it anyways.
Stage 4: Second perimeter scan
With minor changes in the setup the amount of vulnerabilities found has been reduced. Nice!
The PHP vulnerabilities are now seemingly gone from our view. What we’ve done is to minimize the footprint of the server – we have in no way made it more secure. Vulnerabilities do exist, but they will be harder to spot.
Stage 5: Credentialed scan
The scans I have conducted today are all based on scanning the perimeter. Did you know that you can let the scanner log onto the server and do a patch audit? It can. In the policy I created earlier I enable the scanner to log in using SSH. Once again Parrot OS has blacked out the input boxes, but they contain the login credentials. Oh, one more thing! I updated the policy to avoid false alarms.
Last time there were 29 vulnerabilities. Some of them were false alarms. Running the credentialed scan shows we have reduced the amount of vulnerabilities.
Drilling down to the vulnerabilities view shows that we only got two mediums and two lows to tackle! Nessus is pretty smart when doing credentialed scans. It logs onto the server and yank out a list of all installed software and compares it to its plugins database.
By actually looking at what’s installed the vulnerability scanner will do a better job. Did you notice something interesting in the screenshot above? The findings related to OpenSSH are gone. Nessus found out that my server is patched given according to its current plugin database. We still broadcast the OpenSSH version to potential attackers, though.
My demonstration today started out with identifying how my center would appear for attackers running similar tools. We saw that the server leaked some information about the software in use and how to reduce that footprint. We applied some security by obscurity by removing software banners and validated the changes by running a follow-up scan. Since we couldn’t turn of banners for one piece of software, we moved into credentialed scans to actively see if the server was patched correctly.
Looking at the perimeter aspect turning off banners is considered security by obscurity. The reason for this is that there are other ways to determine software versions. Another way is to approach the server holistically by looking at the complete picture. Even small pieces of information may yield big results.
Having a vulnerability scanner at hand and not proactively fix issues is a very bad combo. What is the point having a huge report pinpointing vulnerabilities without trying to fix them? For the best experience using vulnerability scanners you must actively investigate that patches and updates has been installed the vulnerabilities found. Solving low hanging fruits doesn’t hurt either.
If you enjoyed this post please share and contact me on Twitter ( @reedphish )!