Heartbleed: how to reliably and portably check the OpenSSL version?

Solution 1:

Based on the date displayed by your version of OpenSSL, it seems you are seeing the full version displayed there.

Open SSL 1.0.1 was released on March 14th, 2012. 1.0.1a was released on April 19th of 2012.

So, I'm going to go ahead and assert that openssl version -a is the proper, cross-distro way to display the full version of OpenSSL that's installed on the system. It seems to work for all the Linux distros I have access to, and is the method suggested in the help.ubuntu.com OpenSSL documentation, as well. Ubuntu LTS 12.04 shipped with vanilla OpenSSL v1.0.1, which is the version that looks like an abbreviated version, on account of not having a letter following it.

Having said that, it appears that there is a major bug in Ubuntu (or how they package OpenSSL), in that openssl version -a continues to return the original 1.0.1 version from March 14, 2012, regardless of whether or not OpenSSL has been upgraded to any of the newer versions. And, as with most things when it rains, it pours.

Ubuntu is not the only major distro in the habit of backporting updates into OpenSSL (or other packages), rater than relying on the upstream updates and version numbering that everyone recognizes. In the case of OpenSSL, where the letter version numbers represent only bug fix and security updates, this seems nearly incomprehensible, but I have been informed that this may be because of the FIPS-validated plugin major Linux distros ship packaged with OpenSSL. Because of requirements around revalidation that trigger due to any change, even changes that plug security holes, it is version-locked.

For example, on Debian, the fixed version displays a version number of 1.0.1e-2+deb7u5 instead of the upstream version of 1.0.1g.

As a result, at this time, there is no reliable, portable way to check SSL versions across Linux distributions, because they all use their own backported patches and updates with different version numbering schemes. You will have to look up the fixed version number for each different distribution of Linux you run, and check the installed OpenSSL version against that distribution's specific version numbering to determine if your servers are running a vulnerable version or not.

Solution 2:

If you want something truly cross-platform, check for the vulnerability itself rather than relying on version numbers.

You might have code that reports a version number that is known to be vulnerable, but the actual code is not vulnerable. And the reverse -- silently vulnerable code -- could be even worse!

Many vendors who bundle open-source products like OpenSSL and OpenSSH will selectively retrofit urgent fixes to an older version of code, in order to maintain API stability and predictability. This is especially true for "long-term release" and appliance platforms.

But vendors who do this silently (without adding their own version string suffix) run the risk of triggering false positives in vulnerability scanners (and confusing users). So to make this transparent and verifiable, some vendors append their own strings to the major package version. Both Debian (OpenSSL) and FreeBSD (in OpenSSH, via the VersionAddendum sshd_config directive) sometimes do this.

Vendors who don't do this are probably doing so to minimize the chance of breakage due to the many direct and indirect ways that other programs check version numbers.

So it can look like this:

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS"

$ openssl version
OpenSSL 1.0.1 14 Mar 2012

... even though it's been patched:

$ dpkg -l openssl | grep openssl
ii  openssl  1.0.1-4ubuntu5.12  [truncated]

$ ls -la `which openssl`
-rwxr-xr-x 1 root root 513208 Apr  7 12:37 /usr/bin/openssl

$ md5sum /usr/bin/openssl
ea2a858ab594905beb8088c7c2b84748  /usr/bin/openssl

With things like this in play, you're better off if you don't trust the version number.


Solution 3:

Unfortunately, I'm not sure there is a cross-platform way of doing this. As I discuss in a blog posting, the version of OpenSSL displayed on Ubuntu 12.04 REMAINS 1.0.1 after upgrading to a fixed version.

For Ubuntu 12.04 ONLY, you can tell if you've been updated if all of the below are true:

  1. dpkg -s openssl | grep Version shows version 1.0.1-4ubuntu5.12 or later.
  2. dpkg -s libssl1.0.0 | grep Version shows version 1.0.1-4ubuntu5.12 or later.
  3. openssl version -a shows a "built on" date of April 7, 2014 or later.

Thanks to @danny for the additional info.


Solution 4:

Give the following a try. It will extract all the strings from the crypto library that ssh is linked against. It produces more than one line of output, but if necessary could be converted to 1 line.

ldd `which ssh` | awk '/\// { print $3 }' | grep crypto | xargs strings  | grep OpenSSL

produces

OpenSSLDie
DSA_OpenSSL
...
MD4 part of OpenSSL 1.0.1f 6 Jan 2014 
MD5 part of OpenSSL 1.0.1f 6 Jan 2014
... 
etc

e.g. on Gentoo before emerge

[ebuild     U  ] dev-libs/openssl-1.0.1f [1.0.1c] USE="bindist (sse2) tls-heartbeat%* zlib -gmp -kerberos -rfc3779 -static-libs {-test} -vanilla" 4,404 kB

the above command results in

...
OpenSSL 1.0.1c 10 May 2012

after

...
OpenSSL 1.0.1f 6 Jan 2014

Ouch, still no g.


Solution 5:

Do any of these scripts test all services, or do they only test HTTPS? AFAIK, PostgreSQL is vulnerable, but that's only a rumor until an in-the-wild attack surfaces.

There is a metasploit script available for use.

https://github.com/rapid7/metasploit-framework/commit/dd69a9e5dd321915e07d8e3dc8fe60d3c54f551a

You can type this (tested with GnuWin32 OpenSSL binary version 1.0.1.6, dated 2014-01-14), or just use the script in the comment below this one. It's more accurate and simpler!

s_client -connect a23-75-248-141.deploy.static.akamaitechnologies.com:443 -debug -state

Once connected type B and you'll see on a vulnerable host and you won't be disconnected:

B

HEARTBEATING
write to 0x801c17160 [0x801cbc003] (66 bytes => 66 (0x42))
0000 - 18 03 03 00 3d 8f 6f 3c-52 11 83 20 9c a2 c0 49   ....=.o 5 (0x5))
0000 - 18 03 03 00 3d                                    ....=
read from 0x801c17160 [0x801cb7008] (61 bytes => 61 (0x3D))
0000 - 05 4d f5 c0 db 96 d1 f5-c7 07 e5 17 1f 3b 48 34   .M...........;H4
0010 - 6e 11 9d ba 10 0c 3a 34-eb 7b a5 7c c4 b6 c0 c0   n.....:4.{.|....
0020 - b0 75 0e fe b7 fa 9e 04-e9 4e 4a 7d 51 d3 11 1f   .u.......NJ}Q...
0030 - e2 23 16 77 cb a6 e1 8e-77 84 2b f8 7f            .#.w....w.+..
read R BLOCK

You will get a heartbeat response that looks similar to this one.

On a patched host, you will see a response similar to below and you'll be disconnected:

Enter B

HEARTBEATING
write to 0x801818160 [0x8019d5803] (101 bytes => 101 (0x65))
0000 - 18 03 03 00 60 9c a3 1e-fc 3b 3f 1f 0e 3a fe 4c   ....`....;?..:.L
0010 - a9 33 08 cc 3d 43 54 75-44 7d 2c 7b f3 47 b9 56   .3..=CTuD},{.G.V
0020 - 89 37 c1 43 1c 80 7b 87-66 ff cb 55 5f 8d 1a 95   .7.C..{.f..U_...
0030 - 1b 4c 65 14 21 a1 95 ac-7a 70 79 fc cc a0 cf 51   .Le.!...zpy....Q
0040 - 0f 7e c5 56 14 c8 37 c1-40 0b b8 cb 43 96 8a e6   [email protected]...
0050 - 21 42 64 58 62 15 fb 51-82 e6 7f ef 21 1b 6f 87   !BdXb..Q....!.o.
0060 - b9 c2 04 c8 47                                    ....G

Source:

  • Blog post How to test if your OpenSSL heartbleeds

There's also these tools:

  • https://github.com/titanous/heartbleeder

  • http://filippo.io/Heartbleed/

  • https://github.com/musalbas/heartbleed-masstest