Monday, April 4, 2016

SSLv2 Vulnerability DROWN Attack: Test and Fix with example

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:
  1. Go to drownattack test site, and enter the domain name or ip-address of the site that you want to test.
  2. 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.

Additional Reference:

No comments:

Post a Comment