Showing posts with label Virtual Machine. Show all posts
Showing posts with label Virtual Machine. Show all posts

Thursday, December 6, 2012

Securing Azure Virtual Machines or I got hacked and how you shouldn’t

I have been working with Azure for over a year now and this is the first time I have had a machine compromised.  I will say that this entire incident has been a good learning experience.  I think that anyone can learn from my mistakes here.

Thinking back this event is interesting from many angles.

  • a default machine provisioning behavior is opening a door that you (as the customer) needs to remember to close or not open in the first place.
  • the machine is really out there, in the wild, innocent, vulnerable.  Not protected in your datacenter behind all the other protections.
  • your IT Security folks might not yet be engaged in how to deal with deploying into public clouds.
  • you are doing test, exploration, or other work on systems that are not going to production.

 

Let’s go back in time to the week of November 26. 

My innocent Virtual Machine was compromised by an attack against the RDP protocol.  The well known RDP port 3389 was the vector.

The attacker succeeded in obtaining access, changing the local administrator password and pwning my box.  I can only image that it was then ‘sold’ on some botnet as later it ended up with a PayPal phishing site.

Then it began the process of being capacity to begin finding other vulnerable folks. This is where I noticed what was happening.

(BTW – the MSFT folks that handle this type of incident were extremely helpful in working out what happened, in what order, and how.)

 

First, lets look at the environment where I put my machine.

It was in Azure.  Placing any machine in Azure is equivalent to placing it in the corporate DMZ.  There is a load balancer between you and the outside world, and public endpoint definition(s) that define the public ingress port(s).

Beyond that, you can actually do bunches of different configurations of Virtual Networks, or Gateways.  You can link Services.  All kinds of stuff.  But remember, all IaaS machine to machine network traffic within a Service is wide open.  There are no private endpoints (as in a PaaS Service).

That said, any IT Pro would immediately say ‘duh’ or ‘you idiot’.  Yep.  Nothing I can comment there.

 

There are some default IaaS behaviors that are enabling this;

  • automatically opening an RDP endpoint for management
  • requiring complex passwords (false sense of security)
  • local administrator is not disabled
  • no real guidance around practices (not that anyone RTFM’s any longer anyway – they simply SearchTFM)

PaaS Roles don’t have these behaviors.  And the RDP connection is secured with a Certificate and a secondary user account.

Some of the Azure MVPs found my original MSDN forum thread and beat my blog post out.  My IT Pro background is leading me to some different ideas, and I felt I needed to tell a bigger story.

And, as I think about this; remember that you are administering these lockdowns at the same time that your machine could be getting probed, or brute force attacked.  So, choose a logical order, define a strong password at the point to machine creation (however you do it).  At least it gives you a fighting chance.

 

So, this is where i mention a bit of guidance.  Here are some options to pick and choose from.

Some initial mitigation suggestions to choose from:

  • Use the PaaS roles of Web or Worker as the front end machines whenever possible.  They are already hardened.
  • Rename the local administrator account.
  • Disable the local administrator account and create some uncommonly named user account for administrative access.
  • Choose strong plus complex passwords, or passphrases.  Not simply one or the other.  The OS can enforce complexity but not strength. 
    • A dictionary attack is likely to hit “P@ssw0rd” but it is unlikely to hit “Just a city boy, born and raised in South Detroit”.
    • My favorite example of password strength: http://xkcd.com/936/ 
  • Denying user access after X failed logon attempts (lock the account).  This is a Local security policy if not domain joined, or a Domain policy if joined.  Consider an automatic (timed) unlock as well, or you could have no recourse but to destroy your machine.
  • Do not allow the creation of the default RDP public endpoint.  This is only possible through the API / PowerShell.  Or delete the auto created endpoint after creating the machine in the Portal.
  • Only create the RDP endpoint when remote administration is necessary, and removing it after.  But remember that we are human, and unless you have some interface doing this for you, you will probably forget at some point.
  • Remove the RDP endpoint and use the Virtual Network Gateway feature of the Azure Virtual Network for secured remote administration without public endpoints.  This requires some ground based router, and the VPN is slow, but your ports are closed.
  • Remove RDP endpoint & use Azure Connect.  This is limited to IPv6 TCP traffic only, but that should cover anything required to manage the OS.
  • Avoid 3389 as the public port (I noticed my compromised machine specifically scanning for this port to spread itself) by using a port in the ephemeral range.
  • Use the Windows Advanced Firewall rules and define them appropriately.
  • Use Windows IP Security Policies and tightly define the sources from which RDP traffic can be accepted from.  This is highly effective, but a pain to set up.
  • Monitor the machine.  Azure provides metrics through the portal and API.  Discover a baseline.  Use an agent within the machine.  This only detects the compromise after it happens and is not preventative.
  • Take a snapshot of the clean state.  This is not a point and click thing in Azure today, but you can work this out using the Storage cmdlets through destroying your machine, making the diff disk, and reincarnating the machine.

 

Some of these practices are simply security through obscurity but, in this case, I think it’s OK.

  • Changing the name of the administrator account dramatically increases the search space for a username/password pair.
  • Changing the RDP endpoint is going to increase the search space for a TCP port/username/password trio.

I didn’t mention antivirus.  I won’t go into my theories there.  My personal opinion is that if all the tightening measures are done and you still get hacked, most likely your AV would have failed as well.

Always be ready for the possibility of rebuilding a machine.  Never assume you can simply move forward, or even install a backup.  The best you can do is revert to a known clean state.

 

Good luck!

Friday, October 5, 2012

My Azure Public Endpoint switcher

I recently worked through an issue with the Persistent VM beta in Windows Azure around remotely managing my VMs (machines as I will generically call them).

Now, my scenario is that I have multiple machines in Azure behind a single Service (DNS name at cloudapp.net).  You can of course bring your own DNS name and simply mask this, you are not stuck with it.

In order to get a remote session to each one, only one can have the RDP or SSH port at any time for the Service. 

So the setup resembles this:

  • brianEhApp.cloudapp.net:3389 -> VM1:3389
  • brianEhApp.cloudapp.net:56789 -> VM2:3389
  • brianEhApp.cloudapp.net:54321 -> VM3:3389

This is relatively straightforward.  However, I ran into a situation what I was not able to authenticate to the higher ‘ephemeral’ ports that Azure was automatically generating as the administrative endpoint for my +1 machines.

So, I could use the Portal to change one VM then back out to the other and so on.

However, this was taking quite a long time.  And I am impatient.

So, I turned over to the Azure PowerShell cmdlets and whipped out the following script.  It switches the public endpoints for me and launches my administrative RDP session straight away.  Considerably faster than messing with the Portal.


$myVm = Read-Host -Prompt "what is the VM name you want to access via RDP?"
$myService = Read-Host -Prompt "what is the Service name where the VM resides?"
"The assumption is that the endpoint name is RDP"

# Check all the endpoints of all the VMs and move off 3389 to set desired VM to 3389
$deploymentVms = @()
$deploymentVms = Get-AzureVM -ServiceName $myService 

# First all VMs in the Service need to be off 3389 or there will be an error setting the correct one
foreach ($vm in $deploymentVms){
    $vmEnds = @()
    $vmEnds = Get-AzureEndpoint -VM $vm
    Foreach ($end in $vmEnds){
        If ($end.Port -eq 3389 -and $vm.Name -notmatch $myVm){
            $pubPort = Get-Random -Minimum 49152 -Maximum 65500
            Set-AzureEndpoint -Protocol tcp -LocalPort 3389 -PublicPort $pubPort -Name $end.Name -VM $vm | Update-AzureVM
        }
    }

}

# Now, set the desired VM Public endpoint to 3389
Get-AzureVM -ServiceName $myService -Name $myVm | Set-AzureEndpoint -Protocol tcp -LocalPort 3389 -PublicPort 3389 -Name RDP | Update-AzureVM

Get-AzureRemoteDesktopFile -ServiceName $myService -Name $myVm -Launch

Thursday, September 27, 2012

Azure Virtual Machine the PowerShell Basics

Really, I am not going to go into a lot of explanation here.  I am assuming that you have some PowerShell background and need a bit to get started.  That is what I am covering.

You can find the cmdlets here:

https://www.windowsazure.com/en-us/manage/downloads/

Be sure to have your Azure management certificate properly stored in your Personal certificate store prior to connecting to your subscription.

These first commands are pretty much mandatory when you begin a PowerShell session.

Import the module:

​import-module 'C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1'

Import a settings file (this speeds up as it lists all subscriptions you have access to - to create this file perform Export-AzurePublishSettingsFile (Visual Studio also uses this))

Import-AzurePublishSettingsFile 'C:\Users\Public\Documents\BrianEhServices.publishsettings'

Choose the subscription that you will interact with for your session:

Select-AzureSubscription -SubscriptionName "Sample Subscription"

Set the default Storage account that will be used (it must be in the same subscription)

Set-AzureSubscription -SubscriptionName "Sample Subscription" –CurrentStorageAccount SampleStorageAccount

By the way, do the above is handy.  Like me I assume that you all have alt least two Azure subscriptions (yours and the one your company has given you access to).  Using that settings file allows easy switching.  Now that you have that, go exploring.

If you have a Service or have deployed a Virtual Machine from the Gallery using the Portal you can query it, change it, dispose of it.

If you have VHD images you can manipulate those.  Now, disclaimer here, my experience so far is that CSUPLOAD from the Azure SDK is still the best way to get VHDs into Azure storage and it now supports both stateless and persistent VHD images.  It differentiates between the two because it registers them with the VHD repository for you and sets its life in motion.

But, I assume that you are getting itchy, so lets just begin with making a new Virtual Machine in a new Service.  The very same thing that you would get if you used a Gallery VM image (this is not the Quick VM as that would be New-AzureQuickVM).

First we need to find an image:

List all available images: Get-AzureVMImage

List all available in a table: Get-AzureVMImage | Format-Table

Find images that have been uploaded to your Storage account ('user' images): Get-AzureVMImage | where { ($_.Category -eq "user") }

Now I just want to use the Server 2012 Gallery image and create a VM (we will build on this command).

$svr2012Image = Get-AzureVMImage | where { ($_.Category -eq "Microsoft") -and ($_.Label -match "Server 2012" ) -and ($_.ImageName -match "Datacenter") }

Apply a customization configuration to the image:

$myImage = New-AzureVMConfig -Name MyNewMachine -InstanceSize ExtraSmall -ImageName $svr2012Image.ImageName
Add-AzureProvisioningConfig -VM $myImage -Windows –Password
<complex password>

Create the Service and Provision the VM:

New-AzureVM -ServiceName "MyNewService" –VMs $myImage

Notice after it is finished that Azure automatically created an RDP endpoint to allow remote OS access (if it was a Linux image an SSH endpoint would have been created).

Friday, September 21, 2012

Azure IaaS Virtual Machine concepts

The Azure IaaS Virtual Machine is in Beta and anyone can request access.

For those have worked with Azure VMs in the past (Web, Worker, and VM Role) this is simply an addition, a new option.

There are some interesting contrasts, parallels, and dependencies when we consider both the PaaS and IaaS options (MSFT likes to draw the contrast that way, but fundamentally they are still machines what you can do and need to know is different).

MSFT already has lots of documents out there on the IaaS stuff.  I don’t intend to regurgitate what they have already documented.  They stuff they have not documented is far more interesting.

And there is a gallery of OS images that you can build machine from using the GUI portal.  And you can create and upload your own VHD images (a bit like VM Role).

In my next post I will begin exploring the PowerShell that is available to drive this stuff from the ground, that is a bit more interesting (at least to me).

First of all, what is the Virtual Machine?  If it isn’t a Web, Worker, or VM Role; what is it.

It is a bit like a VM Role, but without any agents to interact with the Azure Fabric, and the storage supports persistence.  Beyond persistence, it is just a machine.  Mind you, the way I state this it does not sound like much, but it took a lot for MSFT to work through extrapolating the PaaS provisioning and storage into supporting this.  There is a lot there.  Just go look up the TechEd talks.

Now, we all know that MSFT al about platforms, so the Virtual Machine by itself is just as uninteresting as it sounds.  Add in Virtual Networks and it gets a bit more interesting.

Virtual Networks allow defining of address allocation spaces.  And those can be divided into subnets.  If you know the SCVMM IP Pool model, it is similar to that with some implementation differences.

A Virtual Network is also a container or a boundary.  All machines within a Virtual Network can freely communicate with each other over the network. No matter the IP that was allocated to the VM, no IP subnet isolation.  A Virtual Network can also span services – provided they are in the same Affinity group and Region.  It all links.

A Virtual Network also supports the Gateway.  The Gateway is a way to ling the Virtual Network defined in Azure with an SSL VPN endpoint on the ground, in your enterprise.  This is just like any point-to-point VPN that you have used to connect branch offices, or to another business.  Before this we only had Azure Connect and its support for IPv6 and that it only acted as a machine to machine forwarder, fundamentally different.

One other concept is the VHD.  There are two types.  Image and OS. 

An Image can be provisioned into multiple VMs and is prepared so that Azure can customize it.  The Windows OS is prepared with sysprep, and the Linux OS is prepared with the Azure Linux Agent deprovision command.  The concept is the same.

When a new VM is created from an image it can and will be customized.  And, the Fabric also automatically creates a management endpoint (SSH or RDP).

An OS can be used by one Virtual Machine.  It is not provisioned, and therefore not customized.  It is just created an powered on.  You have to define everything, but it allows you to bring your own, pre-configured machine into Azure (without building it in space).

In the next few posts we will get a bit more into this and specifically driving it all with PowerShell.

The last concept is the Services.  IaaS Virtual Machines still run within a Service just like PaaS VMs.  But the two shall not mix.

You can create a Service without a deployment, this is androgynous, lacking either PaaS or IaaS gender.  As soon as the deployment is defined the service becomes either IaaS (meaning that it can run Virtual Machines) or PaaS (meaning that it can run VMs (or Roles)).  Thus the entire Service becomes stateless or persistent.

The two can interact over the network, but not through Azure Fabric Services.

I think that in the next post I am going to dive straight into the PowerShell.