Windows Server in Azure: a surprise cautionary tale in cipher suites

https://learn.microsoft.com/en-us/azure/cloud-services/applications-dont-support-tls-1-2

https://learn.microsoft.com/en-us/windows-server/get-started/editions-comparison?pivots=windows-server-2019

https://learn.microsoft.com/en-us/windows-server/get-started/azure-edition

https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-server-2022

This post isn't intended to be a reference document or a set of instructions. Rather, I'm going to share my experience with a particularly pesky difference between Windows Server 2019, 2022, and 2025 using the usual ISO image versus one provided in/by Azure. The necessary information does exist but I could find no single source of information that clearly defines the issue - so I'm writing it here.

We run a 3rd party backup platform on-prem. I won't name the vendor for privacy/security reasons. It has integrations into our backup storage provider via a storage protocol and an API. It also has integrations into our storage area network providers via API. It also has integrations into our hypervisor(s/platform). And finally, it has integration into Azure Storage, among a variety of others. The backup platform is meant to be able to operate behind the scenes very quietly, while also providing great snapshot-based recovery capability where it makes sense - and generally speaking, it does well.

We decided to move the control plane of this platform to Azure so that in the event of a major incident on-prem, we're live and immediately able to commence recovery exercises. Should the incident be more sinister and involved distributed data destruction, the control plane of backup services would be backed up by Recovery Services Vault, which is both (configured) immutable and requires next to no configuration to commence recovery activities. Therefore, the move gives us quite a lot more backup platform protection, which is a good thing.

We planned for months; virtual networks, WAN considerations, local VLANs and tags, subnets, IPs, TCP ports - everything was mapped. We recently kicked off the migration effort, which was more of a new build with a very heavy duty import to recapture years of stored backups. Toward the end of the exercise, the various integrations mentioned above were started. Of about 8 needing configured, 1 failed and did so in the most benign way. Thus beginning the cautionary tale.


So many things to consider, especially in our relatively complex environment.
  • Is the certificate valid and signed?
  • Is the backup software not trusting our internal CA?
  • Is the TLS inspection service unintentionally capturing this API call?
  • Am I dealing with a certificate subject alternative name (SAN) issue? Is this the right hostname in the certificate?
  • Can I reproduce this issue manually?
That last bullet sent us on quite a bunny chase.
  • Powershell invoke-webrequest: same general error, albeit phrased differently.
  • Curl: same general error, albeit once again phrased differently
    • No amount of command line switches made any difference - and with curl, there are alot of them.
  • MS Edge: no issue, works great (?!)
I learned something new about Edge, though in the back of my head I suspected this. Modern Edge does not use Windows Schannel for TLS behaviors. This is because ultimately, Edge is Chromium. And Google manages their own TLS support (perhaps to some degree more advanced than the host OS. Given that Chromium can run on some pretty old OSes, it's best that they can insert better TLS support in spite of the OS not necessarily having it.) 

We got hung up on this for a while - why were the manual methods breaking while the app was not? Why was on-prem working while this cloud node was not? We started checking ciphers but only confused ourselves more. We follow CIS baselines (and NIST800-52) but took a while before we got to an older Windows Server machine and realized that even with the industry standards, you can potentially have quite a lot of cipher suites. This is an example of a near bog-standard Windows Server 2022 VM on Azure.
get-tlsciphersuite | ft name
When you get a moment, try this on a few of your machines - perhaps on Server 2016, 2019, 2022, and the same in Azure. You may be surprised to see some incredible differences between them, even if you're doing your best to follow industry standards in eliminating "risky" ciphers. The breakthrough came a little later. Using Edge F12 DevTools and exposing the hidden Security tab, you can actually see the TLS cipher used.



TLS_RSA_WITH_AES_128_GCM_SHA256

On first blink, that might not look too interesting... but it is. First, RSA is frowned upon. Second, AES 128 is straight up unacceptable. That's what the API to one of our integrations was offering. Again, I can't name a vendor or product right now, I have some meetings with this vendor about this product very shortly.

So, the solution was a bit funky. We thought we'd be wise and use Powershell enable-tlsciphersuite. What we found is that you can literally enter anything - "peterpiper" is accepted as a valid TLS cipher suite by this cmdlet. It also doesn't do anything no matter what you enter. I'm not sure if this is a placation cmdlet, something deprecated, or what - but nothing. As far as we can tell, you're going to need to go to the registry to change this. 

In the first link above to "Cloud Services" (yes, that old stuff), Microsoft does two useful things. 

  • They admit that "The Windows Server 2019 cloud server image is configured with TLS 1.0 and TLS 1.1 disabled at the registry level. This means applications deployed to this version of Windows AND using the Windows stack for TLS negotiation won't allow TLS 1.0 and TLS 1.1 communication. ... The server also comes with a limited set of cipher suites."
  • They provide a sweeping Powershell script example that will reenable all of the eliminated cipher suites.
We decided that disabling unneeded suites that Microsoft decided were too insecure was probably unnecessary, so we set about just re-enabling the one in question. The Powershell script referenced above does 2 meaningful things - first, it ensures that all of the suites are not literally disabled. Second, it inserts the referenced cipher suite into the list of available ciphers. In our experience, the first step was unnecessary. We inserted the suite mentioned above into the list at this SSL key:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002


A reboot later and our cryptographic exchange was successful. So there were two genuine issues here:
  • Microsoft needs to be more forthright in defining differences in Windows Server "Azure Edition". Windows Server 2019 didn't eventhave an "Azure Edition", yet the image was different. I'm glad its different, I think it's excellent that this change was made - but I think it should be clearly defined and, honestly, just injected as a "feature" that can be enabled/disabled on any version of Windows. In my opinion, this is quite contradictory to standardizations and config management.
  • My unnamed, undefined network technology vendor with a relatively insecure API needs to get their act together pronto.
    • As a follow-up item, we need to red team this and other critical severity infrastructure APIs with tools like o-soft and TestSSL (either bundled or readily available on Kali) to test for other lurking vulnerabilities.
TL;DR - Windows Server in Azure has many cipher suites disabled by default (controlled by the image) in the registry. Edge on Windows doesn't use Windows SChannel and may be unable to reproduce OS-level issues with TLS ciphers. Some network infrastructure APIs may be managed independently from their UI https endpoints and as such could suffer from poor design/neglect.

For further reading, check out: https://www.ietf.org/archive/id/draft-ietf-tls-deprecate-obsolete-kex-05.html



 





Comments