Yesterday Google published the details of a vulnerability in SSL v3.0, POODLE (Padding Oracle On Downgraded Legacy Encryption). People like Troy Hunt have already taken the time to provide us with a detailed overview of this vulnerability.
In this post I’ll explain how you can protect both your Virtual Machines and Cloud Services running in Azure (but especially your end users) from the POODLE vulnerability by disabling SSL v3 in IIS.
The steps described here are based on what you’ll find in KB245030 which has been around for a few months now.
Disabling SSL v3 in your Web Roles
Let’s start by deploying a Cloud Service with a Web Role which includes an HTTPS endpoint. If we run the test on http://www.poodlescan.com/ we’ll see that our Web Role is vulnerable:
The NWebsec project on CodePlex contains a NuGet package that will do the required SSL configuration for you. But in this example I’ll show you how you can create your own startup task. The first thing you’ll need to do is right click your Web Role under your Cloud Service project and choose Add, New Item:
Give the new file a name (poodlefix.bat) for example and add the following lines to the file. These will make sure SSLv3 and the weak Ciphers are disabled.
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v Enabled /t REG_DWORD /d 0 /f REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" /v Enabled /t REG_DWORD /d 0 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" /v Enabled /t REG_DWORD /d 00000000 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128" /v Enabled /t REG_DWORD /d 00000000 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 56/128" /v Enabled /t REG_DWORD /d 00000000 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 128/128" /v Enabled /t REG_DWORD /d 00000000 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" /v Enabled /t REG_DWORD /d 00000000 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" /v Enabled /t REG_DWORD /d 00000000 /f REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" /v Enabled /t REG_DWORD /d 00000000 /f
The last step is to add this script as an elevated startup task in your ServiceDefinition.csdef:
<?xml version="1.0" encoding="utf-8"?> <ServiceDefinition name="PoodleCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2014-06.2.4"> <WebRole name="PoodleWeb" vmsize="Small"> ... <Startup> <Task commandLine="..\poodlefix.bat" executionContext="elevated" /> </Startup> </WebRole> </ServiceDefinition>
And that’s it. Redeploy your application and try the Poodle Scan again. As you can see, the Cloud Service is no longer vulnerable:
Disabling SSL v3 in your Virtual Machines
Applying this change on your Virtual Machines is pretty easy, just run the bat file and you’re done. But that’s OK if you need to manage a few Virtual Machines. But what if you have 10, 20, 100 VMs? Remote PowerShell you’ll say. And if you’re running Virtual Machines with different credentials for multiple customers? Now a good alternative to Remote PowerShell (or doing this manually) is the Custom Script Extension. This allows you to run some script on your Virtual Machine without requiring a direct connection or even the credentials to the VM, allowing you to easily automate this for a great number of Virtual Machines with different credentials.
The Custom Script Extension only supports PowerShell by default, so we’ll convert the previous script to a PowerShell script (by adding & at the start over every line):
& REG.EXE ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v Enabled /t REG_DWORD /d 0 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" /v Enabled /t REG_DWORD /d 0 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" /v Enabled /t REG_DWORD /d 00000000 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128" /v Enabled /t REG_DWORD /d 00000000 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 56/128" /v Enabled /t REG_DWORD /d 00000000 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 128/128" /v Enabled /t REG_DWORD /d 00000000 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" /v Enabled /t REG_DWORD /d 00000000 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" /v Enabled /t REG_DWORD /d 00000000 /f & REG.EXE ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" /v Enabled /t REG_DWORD /d 00000000 /f
The next step is to upload this file to a Storage Account. I’m using CloudXplorer to quickly upload the file to a container and I change the policy of the container to public read access, which allows me to access the script without providing any credentials. This is useful because I’ll want to run the script for different subscriptions and I don’t want to bother with keys or shared access signatures.
As a last step I’ll use Azure PowerShell to run the script on a Virtual Machine:
$scriptUrl = "http://azurepasseastus.blob.core.windows.net/scripts/poodlefix.ps1" Get-AzureVM -Name poodlevm -ServiceName poodlevm | Set-AzureVMCustomScriptExtension -FileUri $scriptUrl -Run poodlefix.ps1 | Update-AzureVM
It will take a few seconds for the operation to complete, but it can take a little more time before the script is actually executed on the VM. You can track the progress of the extension in the Logs folder on your VM (C:\WindowsAzure\Logs).
Once the script has been executed you’ll see that your Virtual Machine is no longer vulnerable:
You could then write some PowerShell to iterate over all the VMs you want to update and run the script over and over again.
As you can see the Microsoft Azure platform comes with the right tools for both PaaS and IaaS to easily make such changes on many machines at the same time.
Enjoy!