CVE-2016-2183 SWEET32 Birthday attacks

Lately, vulnerability scanners have been flagging servers that are susceptible to CVE-2016-2183. In a nutshell, you need to disable any TLS ciphers using 3DES. More detailed information about this vulnerability and why it exists can be found at the links below:
https://access.redhat.com/articles/2548661
https://sweet32.info

Mitigating this vulnerability within Apache is pretty straight forward. Below are the steps to confirm if you are actually affected by this vulnerability and how to remediate it.

First, confirm your Apache web server is actually vulnerable to this by seeing if the 3DES ciphers are returned in this nmap test:

[[email protected] ~]# nmap --script ssl-enum-ciphers -p 443 SERVER_IP_ADDRESS_HERE
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-30 17:57 EST
Nmap scan report for xxxxxxxx (xxx.xxx.xxx.xxx)
Host is up (0.018s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.2
|     Ciphers (14)
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_RSA_WITH_AES_128_CBC_SHA
|       TLS_RSA_WITH_AES_128_CBC_SHA256
|       TLS_RSA_WITH_AES_128_GCM_SHA256
|       TLS_RSA_WITH_AES_256_CBC_SHA
|       TLS_RSA_WITH_AES_256_CBC_SHA256
|       TLS_RSA_WITH_AES_256_GCM_SHA384
|     Compressors (1)
|_      uncompressed

As you can see in the output above, this server is affected by this vulnerability as its allowing for the following 3DES ciphers:

TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA

Disabling this in Apache is pretty easy. Simply navigate to where ever you have your SSLCipherSuite configuration defined and disable 3DES. Typically this should be in /etc/httpd/conf.d/ssl.conf, however some may also have this defined in each individual Apache vhost. If you are unsure where its configured, you should be able to locate it on your server by running:

# CentOS / Red Hat
[[email protected] ~]# egrep -R SSLCipherSuite /etc/httpd/*

# Ubuntu / Debian
[[email protected] ~]# egrep -R SSLCipherSuite /etc/apache2/*

Once you locate the config(s) that contain this directive, you simple add !3DES to the end of the SSLCipherSuite line as shown below:

[[email protected] ~]# vim /etc/httpd/conf.d/ssl.conf
...
SSLCipherSuite EECDH+AESGCM:EECDH+AES256:EECDH+AES128:EDH+AES:RSA+AESGCM:RSA+AES:!ECDSA:!NULL:!MD5:!DSS:!3DES
...

Once that is done, restart Apache by:

# CentOS / Red Hat
[[email protected] ~]# service httpd restart

# Ubuntu / Debian
[[email protected] ~]# service apache2 restart

Finally, retest using nmap to confirm no ciphers using 3DES show up:

[[email protected] ~]# nmap --script ssl-enum-ciphers -p 443 SERVER_IP_ADDRESS_HERE
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-30 18:03 EST
Nmap scan report for xxxxxxxx (xxx.xxx.xxx.xxx)
Host is up (0.017s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.2
|     Ciphers (12)
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|       TLS_RSA_WITH_AES_128_CBC_SHA
|       TLS_RSA_WITH_AES_128_CBC_SHA256
|       TLS_RSA_WITH_AES_128_GCM_SHA256
|       TLS_RSA_WITH_AES_256_CBC_SHA
|       TLS_RSA_WITH_AES_256_CBC_SHA256
|       TLS_RSA_WITH_AES_256_GCM_SHA384
|     Compressors (1)
|_      uncompressed

If no 3DES ciphers are returned like in the listing above, you should be good to rerun your vulnerability scan!

Quick programming language test scripts

This article simply contains how to test a few languages with a hello world script and a way to test mail functionality.

PHP

PHP script that will output hello world:

[[email protected] ~]# vim hello_world.php
#!/usr/bin/php
<?php
print "Hello World!\n";
?>

[[email protected] ~]# php hello_world.php 
Hello World!

PHP script to test mail functionality:

[[email protected] ~]# vim email_test.php
#!/usr/bin/php
<?php
$hostname = shell_exec('hostname');
$to = "[email protected]";
$subject = "Test mail";
$message = "Hello! This is a simple email message.";
$from = "[email protected]" . $hostname;
$headers = "From:" . $from;
$parameters = "-f " . $from;
mail($to,$subject,$message,$headers,$parameters);
echo "Mail Sent.\n";
?>

[[email protected] ~]# php email_test.php
Mail Sent.

PHP script to test MySQL access:

[[email protected] ~]# db_test.php
<?php
# Fill our vars and run on cli
$dbname = 'DATABASE_NAME';
$dbuser = 'DATABASE_USER';
$dbpass = 'DATABASE_PASS';
$dbhost = 'DATABASE_HOST';
$link = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
mysqli_select_db($link, $dbname) or die("Could not open the db '$dbname'");
$test_query = "SHOW TABLES FROM $dbname";
$result = mysqli_query($link, $test_query);
$tblCnt = 0;
while($tbl = mysqli_fetch_array($result)) {
$tblCnt++;
}
if (!$tblCnt) {
echo "There are no tables<br />\n";
} else {
echo "There are $tblCnt tables<br />\n";
}

[[email protected] ~]# php db_test.php
There are no tables

Perl

Perl script that will output hello world:

[[email protected] ~]# vim hello_world.pl
#!/usr/bin/perl
print "Hello World!\n";

[[email protected] ~]# perl hello_world.pl
Hello World!

Perl script to test mail functionality:

[[email protected] ~]# vim email_test.pl
#!/usr/bin/perl
use Sys::Hostname;
$hostname = hostname;
$to = '[email protected]';
$subject = 'Test mail';
$message = 'Hello! This is a simple email message.';
$from = '[email protected]' . $hostname;
open (MAIL,'|/usr/sbin/sendmail -t');
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n\n";
print MAIL $message;
close (MAIL);
print "Mail Sent.\n";

[[email protected] ~]# perl email_test.pl
Mail Sent.

Python
Python script that will output hello world:

[[email protected] ~]# vim hello_world.py
#!/usr/bin/python
print "Hello World!";

[[email protected] ~]# python hello_world.py
Hello World!

Python script to test mail functionality:

[[email protected] ~]# vim email_test.py
#!/usr/bin/python
import smtplib
import socket
hostname = socket.getfqdn()
mailfrom = '[email protected]' + hostname
to = '[email protected]'
subject = 'Test mail'
message = 'Hello! This is a simple email message.'
smtpserver = smtplib.SMTP("127.0.0.1",25)
header = 'To:' + to + '\n' + 'From: ' + mailfrom + '\n' + 'Subject:' + subject + '\n\n'
smtpserver.sendmail(mailfrom, to, header + message)
print 'Mail Sent.'
smtpserver.close()

[[email protected] ~]# python email_test.py
Mail Sent.

Ruby

Ruby script that will output hello world:

[[email protected] ~]# vim hello_world.rb
#!/usr/bin/ruby
puts 'Hello World!'

[[email protected] ~]# ruby hello_world.rb
Hello World!

Ruby script to test mail functionality:

[[email protected] ~]# vim email_test.rb
#!/usr/bin/ruby
require 'net/smtp'
require 'socket'
hostname = Socket.gethostname
from = '[email protected]' + hostname
to = '[email protected]'
subject = 'Test mail'
message = 'Hello! This is a simple email message.'
msg = <<EOF
From: #{from}
To: #{to}
Subject: #{subject}
#{message}
EOF
Net::SMTP.start('localhost').send_message msg, from, to
puts 'Mail Sent.'

[[email protected] ~]# ruby email_test.rb
Mail Sent.