Important note about SSL VPN compatibility for 20.0 MR1 with EoL SFOS versions and UTM9 OS. Learn more in the release notes.

Sophos Firewall: Understanding PCI Compliance scan results

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.


    Table of Contents

    Overview

    This recommended read talked about the recent rise in reports of failed PCI scans of Sophos Firewalls.

    Reports

    These reports generally list a whole slew of old CVE vulnerabilities as the most serious issue 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 aren’t very accurate. They don't actually test the vulnerabilities against the firewall to see if they are effective. They’re simply making assertions based on assumptions about the apparent version of the different software components. The assertion that Sophos Firewall is running Linux 3.0 is a particularly bad example, based most likely on a flawed test, which I will explain below.

    Sophos 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 Sophos 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:

    XG125_XN03_SFOS 19.5.3 MR-3-Build652# uname -a
    Linux localhost 4.14.277 #2 SMP Wed Jul 5 20:13:45 CEST 2023 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 Sophos Firewall, 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, a 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 Sophos 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 door handles and a windshield. Based on that, we conclude it’s 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 hasn’t been maintained for several years. The latest version of p0f was released in 2016. Creating new signatures for p0f is possible, but none have been officially published.

    Let's look at the signatures themselves to understand why this is important.

    The raw_sig line in the output above is p0f's way of summarizing the data it captures from the handshake. It’s compared to a list of signatures included with p0f's source code. The signatures are compared in order, and the first to match is considered the best result. So, more precise signatures are at the top of the list, and more generic signatures are left to the end in case a specific signature isn’t 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 contains quite a few wildcards. The 'olayout' section is common to all Linux versions and matches 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 assumptions 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 in the system. When it works, it can give you a rough idea of the operating system, assuming it’s distinctive enough and has not been customized or modified in any way. But to provide useful output, it needs to be updated regularly to account for new operating system versions. Finally, there’s 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 will only 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, I suggest you ask the vendor to justify their confidence in it.




    Revamped RR
    [edited by: Erick Jan at 1:58 PM (GMT -7) on 17 Sep 2024]