Disclaimer: This information is provided as-is for the benefit of the Community. Please contact Sophos Professional Services if you require assistance with your specific environment.
We have recently seen a rise in the number of reports of failed PCI scans of XG Firewalls.
These reports generally list, as the most serious issue, a whole slew of old CVE vulnerabilities based on an incorrect assessment that the firewall is running an unpatched Linux 3.0 kernel. The list of vulnerabilities is simply a dump of all the most serious vulnerabilities ever reported against this old variant of Linux.
Response
Overall these scans are not very accurate. They don't actually test the vulnerabilities against the firewall to see if they are effective. They are simply making assertions based on assumptions about the apparent version of the different software components. The assertion that XG Firewall is running Linux 3.0 is a particularly bad example, based most likely on a flawed test which I will explain below.
XG Firewall runs a much more up-to-date kernel based on Linux 4.x. As of version 18.0 MR3, this is version 4.14.38. If you have an XG firewall handy, you can demonstrate this for yourself by logging in to the console and going to the Advanced Shell. Enter the following command and you should see a similar response:
XG135_XN03_SFOS 18.0.3 MR-3# uname -a
Linux localhost 4.14.38 #2 SMP Thu Oct 8 13:48:20 UTC 2020 x86_64 GNU/Linux
Details
Why does the assessment get it wrong? The most likely explanation is that they are basing their assessment on TCP/IP fingerprinting, not on any actual testing of vulnerabilities or examination of the system software.
A common way to do this is using an open-source tool called p0f. This tool sniffs network traffic generated by a device and makes guesses about its operating system, based on the characteristics of the network packets it creates. It has a database of 'fingerprints' that encode characteristic ways in which different operating systems create TCP handshake packets.
For example, TCP option headers can be added to a handshake in any order: different operating systems will always add them in the same order, but that order may vary between operating systems.
Running the p0f tool directly on network traffic to an XG Firewall, it provides this output:
.-[ 10.46.149.2/42920 -> 10.46.149.254/4444 (syn) ]-
|
| client = 10.46.149.2/42920
| os = Linux 2.2.x-3.x
| dist = 0
| params = generic
| raw_sig = 4:64+0:0:1460:mss*44,7:mss,sok,ts,nop,ws:df,id+:0
|
`----
The raw_sig is a list of the handshake characteristics of the packet.
For comparison handshake from a generic Linux installation with kernel 4.15.0 gets this result:
.-[ 10.46.62.167/40340 -> 10.46.149.2/443 (syn) ]-
|
| client = 10.46.62.167/40340
| os = Linux 3.11 and newer
| dist = 1
| params = none
| raw_sig = 4:63+1:0:1460:mss*20,7:mss,sok,ts,nop,ws:df,id+:0
|
`----
Note that even a 4.x kernel is being identified as 3 dot something.
Running it against a newer Linux system running kernel 5.4.0 leaves p0f completely stumped:
.-[ 10.46.62.167/40340 -> 10.46.149.2/443 (syn+ack) ]-
|
| server = 10.46.149.2/443
| os = ???
| dist = 0
| params = none
| raw_sig = 4:64+0:0:1460:mss*45,7:mss,sok,ts,nop,ws:df:0
|
`----
So we can see from the above that, like the PCI scan, p0f on its own is misidentifying the XG Firewall's Linux kernel version as a very early version. It's not conclusive evidence, but it is a strong suggestion that p0f is being used to make their assessment.
But its assessment is a bit like saying "Your vehicle has doorhandles and a windshield. Based on that we conclude it is a Model T Ford."
What we can also see from the above is that its identifications are very imprecise for newer versions of Linux. The fact is, p0f has not actually been maintained for several years. The latest version of p0f was released in 2016. It's possible to create new signatures for p0f, but none have been officially published.
To understand why this is important, let's take a closer look at the signatures themselves.
The raw_sig line in the output above is p0f's way of summarizing the data it captures from the handshake. It is compared to a list of signatures included with p0f's source code. The signatures are compared in order and the first one to match is considered the best result. So signatures that are more precise are at the top of the list, and more generic signatures are left to the end in case a specific signature is not matched.
The format is described as follows:
ver:ittl:olen:mss:wsize,scale:olayout:quirks:pclass
Data | Description |
ver |
IP version - 4 or 6 |
ittl |
TTL value in the IP header |
olen |
length of the IP options or extensions header |
mss |
maximum segment size |
mss |
TCP window size |
wsize |
TCP window size |
scale |
TCP window scaling factor |
olayout |
The order in which TCP options are included in the header, which can vary from OS to OS |
quirks |
A range of additional properties of the IP and TCP headers which may have unusual or distinct values |
Signatures provide matching values for each field, or use * as a wildcard to indicate matching any value.
The signature for Linux 2.2.x-3.x, the one that matches XG Firewall, is included in the 'Catch-all rules' part of the p0f fingerprint file:
label = g:unix:Linux:2.2.x-3.x
sig = *:64:0:*:*,*:mss,sok,ts,nop,ws:df,id+:0
As you can see, as a fallback signature it actually contains quite a few wildcards. The 'olayout' section is common to all Linux versions, and matches even the newest version 5 kernel example above.
In fact, the latest p0f source code contains no signatures for any Linux version newer than version 3.11. The signature for v3.11 looks like this, and will always match before the 2.2.x-3.x catch-all rule.
label = s:unix:Linux:3.11 and newer
sig = *:64:0:*:mss*20,10:mss,sok,ts,nop,ws:df,id+:0
sig = *:64:0:*:mss*20,7:mss,sok,ts,nop,ws:df,id+:0
The version 3.11 signature is identical to the 2.2.x-3.x signature except for the window size, which must be 20*mss to match.
So we can see that this PCI scan is reporting a huge list of vulnerabilities based on assumption driven by an outdated non-result from a test that has nothing directly to do with the vulnerabilities in question.
In conclusion, TCP fingerprinting tells you nothing directly about vulnerabilities on the system. When it works, it can give you a rough idea of the operating system assuming the operating system is distinctive enough and has not been customized or modified in any way. But in order for it to provide useful output it needs to be updated regularly to account for new operating system versions. And finally, there is not a lot of variability in the data on which the signatures are based, so as the number of operating systems increases, the ability of p0f to tell one from another is only going to get worse.
Giving a system a failing grade for a PCI compliance scan based on such a flawed test is unhelpful. If you get a PCI scan report with this kind of data in it, I suggest you ask the vendor to justify their confidence in it.
Updated Disclaimer
[edited by: Erick Jan at 2:10 PM (GMT -7) on 17 Apr 2023]