All your Azure Clouds are Belong to us

A few people asked me why I was thanked in the March 2016 Security Researchers Acknowledgements For Microsoft Online Services. They probably hoped to get a few free beers celebrating my huge bug bounty.

Alas, no bug bounty, since the reported issues were not really in scope of the Microsoft Online Services Bounty Program.

But still fun to find some unexpected bugs.

The application I tested was the Windows Azure Pack (WAP), a complex Microsoft solution to enable large customers to create their own private clouds or sell this to their corporate customers, using the technology used by Microsoft Azure. The interface, and probably underlying code too, was based on the old Windows Azure interface.

The Windows Azure Pack (WAP) consists of three main components:

  • Management portal for tenants – a self-service portal for provisioning, monitoring, and managing typical cloud services such as databases, storage, virtual machines, ...

  • Management portal for administrators – a portal for administrators to configure and manage resource clouds, user accounts, and tenant offers, quotas, and pricing.

  • Service management API – a REST API that helps enable a range of integration scenarios including custom portal and billing systems.

I detected the following issues:

  • Use of a vulnerable version of the Flash component ZeroClipboard in the management portal for administrators, the management portal for tenants and the federated authentication server, all resulting in a Reflected Cross-Site-Scripting (XSS) issue.

I was a bit surprised by this finding, standard security (upgrade external components or remove unused code/components) in the SDLC should have prevented this. Microsoft fixed this by including a new version of ZeroClipboard in the latest WAP Security Update 9.1 Rollup.

  • An authorization bypass where tenant administrators could upload their API management certificate to other tenants. In order to exploit this, the attacker needed to know the very long customer number (a GUID) of the victim.

I thought this was going to be difficult to exploit but have since learned that this customer number is used in billing and might be discovered by some old fashioned dumpster diving.

Anyway, the issues were fixed rapidly. Here the steps to illustrate the proof-of-concepts. This might be useful if you want to search for more bugs in WAP and need to create a test environment.

Vulnerable Flash Component

Management Certificate Upload

  • Install Windows Server 2012 R2 Datacenter (e.g. on Azure).
  • Download and install the Firefox browser to make it easier to look at requests/responses).
  • Install Java.
  • Download and install OWASP ZAP.
  • Install SQL Server (I used SQL Server Express 2012 from
  • Install Windows Azure Pack.
  • Configure the admin site.
  • Sign on to the management portal for administrators.
  • Go to SQL Servers, add the local instance of SQLExpress.
  • Go to plans, create a new plan, name it SQLSERVER, with access to SQL Servers services.
  • Go to plans, add a subscription with 2 users (named further "tenant1" and "tenant2"), with plan SQLSERVER.
  • Log off, empty the browser cache, close and open the browser.
  • Start OWASP Zap to be able to monitor request and responses.
  • Configure Firefox to use OWASP Zap as a proxy for all requests (also for localhost and
  • Log on as "tenant1". Browse the site. Look at the requests, nearly all contain a "subscriptionId". Make note of this ID. Note log-on is with this URL and then enter the following URL.
  • Log off, empty the browser cache, close and open the browser.
  • Log on as "tenant2". Click on Service Management Portal in the left corner.
  • Choose My Account, upload management certificates.
  • Prepare to upload a certificate. However, configure OWASP ZAP first to block the request.
  • Block and move the request to the Manual Editor. This request looks like:
POST https://[SERVER]:30081/ManagementCertificate/UploadCertificate HTTP/1.1

[some HTTP Headers REMOVED for brevity and clarity]
Connection: keep-alive  
Content-Type: multipart/form-data; boundary=---------------------------152502856522440  
Content-Length: 1888  
Host: herman:30081

Content-Disposition: form-data; name="certificateFileName"; filename="cert2.cer"  
Content-Type: application/octet-stream


Content-Disposition: form-data; name="subscriptionId"


Content-Disposition: form-data; name="x-ms-client-antiforgery-id"


Notice that this request contains the subscriptionId from tenant2. Modify the request to use the subscriptionID from tenant1 (e.g. 3a370f49-dff1-444b-8467-5744[REMOVED]).

  • Execute the request. The response looks like:
HTTP/1.1 200 OK  
Cache-Control: no-cache  
Pragma: no-cache  
Content-Type: text/html; charset=utf-8  
Expires: -1  
Server: Microsoft-IIS/8.5  
x-build-version: 3.29.8196.0 (rd_auxsmp_stable_v2_gdr.151104-1438)  
x-config-version: i0PHt51m  
X-Content-Type-Options: nosniff  
Strict-Transport-Security: max-age=2592000; includeSubDomains  
X-XSS-Protection: 1; mode=block  
X-AspNetMvc-Version: 4.0  
X-AspNet-Version: 4.0.30319  
X-Powered-By: ASP.NET  
Date: Tue, 16 Feb 2016 20:49:50 GMT  
Content-Length: 69

  • Log out. Empty the browser cache, close and open the browser again.
  • Log in as "tenant1". Choose My Account, management certificates. Notice that the uploaded certificate is now visible in the interface, proving that "tenant2" could upload a Management Certificate for "tenant1".

That's it! Have fun chasing some bounties!

Herman Stevens

Just some guy on the internet. Loves technology, diving, travelling, photography and Belgian Trappist beers.