Check if your Perl stack is vulnerable to the OpenSSL « heartbleed » bug.
curl -s https://gist.githubusercontent.com/dolmen/10096474/raw/ssl-heartbleed-check.pl | perl
Check if your Perl stack is vulnerable to the OpenSSL « heartbleed » bug.
curl -s https://gist.githubusercontent.com/dolmen/10096474/raw/ssl-heartbleed-check.pl | perl
| #!/usr/bin/env perl | |
| use strict; | |
| use warnings; | |
| sub print_color (*$$) | |
| { | |
| my ($fh, $color, $text) = @_; | |
| print $fh | |
| -t $fh | |
| ? "\e[${color}m$text\e[m\n" | |
| : "$text\n" | |
| } | |
| use Net::SSLeay (); | |
| my $ssl_ver = Net::SSLeay::SSLeay(); | |
| my $ssl_ver_text = Net::SSLeay::SSLeay_version(0); | |
| my $ssl_cflags = Net::SSLeay::SSLeay_version(2); | |
| my $ssl_built_on = Net::SSLeay::SSLeay_version(3); | |
| print "$ssl_ver_text\n"; | |
| printf "SSL version 0x%x %d.%d.%d%s\nCFLAGS=%s\nBUILT_ON=%s\n", | |
| $ssl_ver, | |
| ($ssl_ver >> 28) & 0xff, | |
| ($ssl_ver >> 20) & 0xff, | |
| ($ssl_ver >> 12) & 0xff, | |
| do { my $minor = ($ssl_ver >> 4) & 0xff; $minor ? chr(96+$minor) : '' }, | |
| $ssl_cflags, | |
| $ssl_built_on; | |
| # TODO : openssl may be dynamically linked, so the version reported by | |
| # Net::SSLeay may not match the real version installed | |
| if ( ($ssl_ver_text =~ /^OpenSSL 1\.0\.(?:1[a-f]?|2-beta1)(?:-fips)? / | |
| || ($ssl_ver >= 0x10001000 && $ssl_ver <= 0x1000106f) || $ssl_ver == 0x10002001) | |
| && $ssl_cflags !~ / -DOPENSSL_NO_HEARTBEATS /) { | |
| (my $build_time = $ssl_built_on) =~ s/^[^:]*: *//; | |
| my $recently_built = eval { | |
| eval { | |
| require POSIX; | |
| POSIX::setlocale(POSIX::LC_TIME(), "C"); | |
| } or warn $@; | |
| require Time::Piece; | |
| my $t = Time::Piece->strptime($build_time, '%a %b %d %T UTC %Y'); | |
| #print $t->strftime("%Y-%m-%d"), "\n"; | |
| $t->epoch > 1396828800 # 2014-04-07 00:00:00 | |
| } or warn $@; | |
| if ($recently_built) { | |
| print_color \*STDERR, "1;33", "Version number indicates vulnerable, but your build is recent so may be patched."; | |
| } else { | |
| print_color \*STDERR, "1;31", "Vulnerable to heartbleed!"; | |
| } | |
| exit 1; | |
| } else { | |
| #print_color \*STDOUT, "1;32", "Not vulnerable to heartbleed."; | |
| print_color \*STDOUT, "1;33", "Maybe not vulnerable to heartbleed."; | |
| } |
Time::Piece->strptime($build_time, '%a %b %d %T UTC %Y') fails if $build_time contains a time zone string other than UTC. Changing the format string to '%a %b %d %T %Z %Y' doesn't work either, whether the time string has UTC in it or not. Any ideas?
A friend (@alnewkirk) showed me a workaround by using Time::ParseDate to parse the time string.
I just improved the check with an heuristic to detect patched versions.