DROWN stands for Decrypting RSA with Obsolete and Weakened eNcryption.
This is from Vulnerability Note VU#583776: Network traffic encrypted using RSA-based SSL certificates over SSLv2 may be decrypted by the DROWN attack.
This is also referred as CVE-2016-0800.
To fix the problem, you should simply disable support for SSLv2 on servers that are using RSA-based SSL certificates. SSLv2 has been deprecated since 2011. There is no reason for you to use SSLv2 anymore.
Two Methods to Test DROWN Vulnerability
There are two ways you can test for DROWN vulnerability:
- Go to drownattack test site, and enter the domain name or ip-address of the site that you want to test.
- If you want to test the servers that are running behind your firewall, or if you want to automate testing all your servers from command line, use the python script that was developed by Hubert Kario of RedHat as explained below.
Install Python DROWN Test Script
You don’t need to do this on the server that you want to test. You can install the following python script on any of your server (For example, on a dev server), and test all your other servers from this server where this python script is installed.
For this, you should have Python 2.6 or above.
# python --version Python 2.6.6
You should also have git installed on your system:
# git --version git version 1.7.1
Create a drown directory.
cd ~ mkdir drown cd drown
Get the TLSFuzzer using git clone
# git clone https://github.com/tomato42/tlsfuzzer Initialized empty Git repository in /root/drown/tlsfuzzer/.git/ remote: Counting objects: 480, done. remote: Compressing objects: 100% (10/10), done. remote: Total 480 (delta 5), reused 0 (delta 0), pack-reused 470 Receiving objects: 100% (480/480), 1.30 MiB | 327 KiB/s, done. Resolving deltas: 100% (302/302), done.
Checkout the ssl2 branch
# cd tlsfuzzer # git checkout ssl2 Branch ssl2 set up to track remote branch ssl2 from origin. Switched to a new branch 'ssl2'
At this stage, you should see the following files under ~/drown/tlsfuzzer directory
# ls build-requirements.txt docs LICENSE Makefile README.md requirements.txt scripts setup.py tests tlsfuzzer
Next, get tlslite-ng, which is an open source python library that implements SSL and TLS cryptographic protocols.
# git clone https://github.com/tomato42/tlslite-ng .tlslite-ng Initialized empty Git repository in /root/drown/tlsfuzzer/.tlslite-ng/.git/ remote: Counting objects: 4821, done. remote: Total 4821 (delta 0), reused 0 (delta 0), pack-reused 4821 Receiving objects: 100% (4821/4821), 1.55 MiB | 137 KiB/s, done. Resolving deltas: 100% (3570/3570), done.
Next create the appropriate link for the tlslite that we just downloaded above.
# ln -s .tlslite-ng/tlslite tlslite
Checkout the sslv2 branch.
# cd .tlslite-ng/ # git checkout sslv2 Branch sslv2 set up to track remote branch sslv2 from origin. Switched to a new branch 'sslv2' # cd ~/drown/tlsfuzzer
Get the ECDSA cryptography python script.
# git clone https://github.com/warner/python-ecdsa .python-ecdsa Initialized empty Git repository in /root/drown/tlsfuzzer/.python-ecdsa/.git/ remote: Counting objects: 485, done. remote: Total 485 (delta 0), reused 0 (delta 0), pack-reused 485 Receiving objects: 100% (485/485), 180.60 KiB, done. Resolving deltas: 100% (289/289), done.
Create appropriate link for the python ECSDA script.
# ln -s .python-ecdsa/ecdsa ecdsa
Test DROWN Vulnerability Using Python Script – Not Vulnerable Example
Finally, execute the DROWN python script as shown below. Change the ip-address appropriate to the server that you are testing. You can also use domain name instead of ip-address here.
# PYTHONPATH=. python scripts/test-sslv2-force-export-cipher.py -h 192.168.101.2 -p 443 Connect with TLSv1.0 EXP-RC4-MD5 ...OK Connect with SSLv2 EXP-RC4-MD5 ...OK Connect with SSLv3 EXP-RC4-MD5 ...OK Connect with TLSv1.0 EXP-RC2-CBC-MD5 ...OK Connect with SSLv3 EXP-RC2-CBC-MD5 ...OK Connect with SSLv2 EXP-RC2-CBC-MD5 ...OK Test end successful: 6 failed: 0
Note: You should see 6 OK’s above. You should also see “failed: 0”.
Test DROWN Vulnerability Using Python Script – Vulnerable Example
The following is executed on a server that was vulnerable to DROWN attack. This is what you’ll see when it is vulnerable.
# PYTHONPATH=. python scripts/test-sslv2-force-export-cipher.py -h 192.168.101.3 -p 443 Connect with TLSv1.0 EXP-RC4-MD5 ...OK Connect with SSLv2 EXP-RC4-MD5 ... Error encountered while processing node <tlsfuzzer.expect.ExpectSSL2Alert object at 0x2259810> (child: <tlsfuzzer.expect.ExpectClose object at 0x2259890>) with last message being: <tlslite.messages.Message object at 0x2259c50> Error while processing Traceback (most recent call last): File "scripts/test-sslv2-force-export-cipher.py", line 109, in main runner.run() File "/root/drown/tlsfuzzer/tlsfuzzer/runner.py", line 151, in run RecordHeader2))) AssertionError: Unexpected message from peer: Handshake(58) Connect with SSLv3 EXP-RC4-MD5 ...OK Connect with TLSv1.0 EXP-RC2-CBC-MD5 ...OK Connect with SSLv3 EXP-RC2-CBC-MD5 ...OK Connect with SSLv2 EXP-RC2-CBC-MD5 ...OK Test end successful: 5 failed: 1
Fix the DROWN Attack Issue
In the above DROWN vulnerable scenario, one of the test case failed. To fix this issue, add the following line to the Apache’s httpd.conf, and restart the Apache.
# vi httpd.conf SSLProtocol All -SSLv2 -SSLv3
If you are running NginX, make sure SSLv2 is not listed in the configuration file as shown below.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
In Apache, we should explicitly say “-SSLv2” to disable SSLv2. But in NginX, when you don’t list SSLv2, it is disabled.
After the above fix, the python DROWN test script didn’t report the issue on that particular server anymore.
Apart from Apache and NginX, if you are running Postfix for your email server, you should disable SSLv2 on your email server also.
Also, upgrade your OpenSSL to the latest version. In the new version, OpenSSL team also have disabled the SSLv2 by default at build-time. OpenSSL team has this suggestion: Upgrade 1.0.2 version to 1.0.2g; and upgrade 1.0.1 version to 1.0.1s.