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:

[user@workstation ~]# 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
[root@web01 ~]# egrep -R SSLCipherSuite /etc/httpd/*

# Ubuntu / Debian
[root@web01 ~]# 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:

[root@web01 ~]# 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
[root@web01 ~]# service httpd restart

# Ubuntu / Debian
[root@web01 ~]# service apache2 restart

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

[user@workstation ~]# 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:

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

[root@web01 ~]# php hello_world.php 
Hello World!

PHP script to test mail functionality:

[root@web01 ~]# 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 = "root@" . $hostname;
$headers = "From:" . $from;
$parameters = "-f " . $from;
mail($to,$subject,$message,$headers,$parameters);
echo "Mail Sent.\n";
?>

[root@web01 ~]# php email_test.php
Mail Sent.

PHP script to test MySQL access:

[root@web01 ~]# 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";
}

[root@web01 ~]# php db_test.php
There are no tables

Perl

Perl script that will output hello world:

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

[root@web01 ~]# perl hello_world.pl
Hello World!

Perl script to test mail functionality:

[root@web01 ~]# 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 = 'root@' . $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";

[root@web01 ~]# perl email_test.pl
Mail Sent.

Python
Python script that will output hello world:

[root@web01 ~]# vim hello_world.py
#!/usr/bin/python
print "Hello World!";

[root@web01 ~]# python hello_world.py
Hello World!

Python script to test mail functionality:

[root@web01 ~]# vim email_test.py
#!/usr/bin/python
import smtplib
import socket
hostname = socket.getfqdn()
mailfrom = 'root@' + 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()

[root@web01 ~]# python email_test.py
Mail Sent.

Ruby

Ruby script that will output hello world:

[root@web01 ~]# vim hello_world.rb
#!/usr/bin/ruby
puts 'Hello World!'

[root@web01 ~]# ruby hello_world.rb
Hello World!

Ruby script to test mail functionality:

[root@web01 ~]# vim email_test.rb
#!/usr/bin/ruby
require 'net/smtp'
require 'socket'
hostname = Socket.gethostname
from = 'root@' + 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.'

[root@web01 ~]# ruby email_test.rb
Mail Sent.