For a few days from July 19th to July 23rd 2021, a short, and unwanted, piece of JavaScript became a required part of the flow of every Office 365 setup, impacting over a quarter of a million Office users.
This script had immediate access to the first and last name, as well as the email address, of anyone who started their Office setup during that time â and much more, besides.
Well, if you know anything about me, youâll already have figured out a couple of things:
- The script was deliberately harmless â it didnât keep or use any of the information or power that was available to it
- The script was written and hosted by me
How did we get here?
For the last three and a bit years, Iâve been trying to figure out ways to find, and protect against, subdomain takeovers of various kinds. To the point that I now use the shorthand term âSDTOâ to describe a subdomain takeover. Itâs two less syllables.
In the weeks before pandemic shutdowns struck the US, I took the calculated risk of flying to San Francisco to give a talk at the RSA Security Conference on some of my tried-and-tested methods for detecting and automatically preventing subdomain takeovers. You can see the talk hereâŠ
One of the slides in that deck talked very briefly about other kinds of subdomain takeovers:
I went through all the source code I had access to at work, and didnât find a single 2nd Order SDTO, but I was definitely told by others in the InfoSec community that they exist.
Iâm a little skeptical of things I canât directly see or experience, so I kind of took stories of their existence with a grain of salt.
That was February 2020
It certainly was, and it wasnât until January 2021 that I thought Iâd engage in some personal research, outside of work, to try and find 2nd order SDTOs â thatâs another example of how little I expected Iâd find any.
So howâd January 2021 turn out?
I learned (actually, re-learned) how to create a Chrome extension.
Itâs not hard. Itâs just JavaScript.
I wrote an extension that looks for 2nd Order SDTOs in every page I visit.
What I got â loads of false positives, which are good because they let you know your codeâs running, but which are also irritating, because they interrupt your everyday life.
False positives â until July 2021!
Thatâs exactly right. July 2021, and by the most peculiar of circumstances. Instead of going out looking for sites that might be vulnerable, I was literally checking on whether I had registered enough copies of Office this year for my family.
I went to setup.office.com, logged in, and my plugin popped up.
Itâs ⊠not a pretty plugin (and yes, thatâs a slightly faked-up version of the dialog).
But what itâs saying is that the part of the Office 365 Setup page where you enter your PIN is trying to call a file named âdeveloper.intercept.jsâ, and that the host on which that file sits – uxmicrosoft-uat.azurewebsites.net â doesnât actually exist.
So I naturally got rather excited.
Whatâs exciting about an NXDOMAIN error?
If you watched my RSA talk on SDTOs, youâll know that NXDOMAIN is just the start of the possibility of a useful SDTO.
Many of my false positives had this same NXDOMAIN error, but I couldnât turn them into an SDTO, because their targets were at cloud sites where itâs impossible to retake a name previously used by another owner.
But this one â any idiot could have registered uxmicrosoft-uat.azurewebsites.net â and so I did.
For free.
Then I created the JavaScript file, and added a command to log a simple fixed string to the console log.
And I loaded the page.
As the log says, âWay heyâ! My script executed. And not because thereâs anything special on my account.
What didnât I do with this script?
I totally resisted the temptation to:
- Log the first and last name, and email address, of everyone registering Office that week
- Log the PINs as users entered them, then tell the users the PINs failed, while I went and sold the PINs for valid Office licences on the black market
- Use the fact that Iâm logged in as the user to their Microsoft account to buy stuff and send it to me
- Prompt the users to re-enter their password as confirmation, so that I could get a list of usernames and passwords for Microsoft accounts
- Deface the page with political messages, or porn
- âŠ
Time to write a report
All of this took only a very few short minutes!
Now Iâve got the web site under my belt, and the script is in place, I have all the elements I need to submit a bug report to Microsoft. Theyâve got a bug bounty page, with a list of all the services that are covered.
I fill out the first page of the form, where it asks me for a short description and a proof of concept. To my irritation, I realise there is no 2nd page, and that this is the version of my report that theyâre going to see.
So hereâs my really inadequate report as it stood when I submitted it:
Everythingâs there, that should be enough for anyone on the bug bounty team to recognise and reproduce this bug, evaluate it for badness and close things up.
And you canât edit this â or the metadata.
You canât go in and change the Security Impact or the Reported products (why the plural? you can only select one!)
I can upload some additional files, though, so I upload a screenshot of a page of logs of people from all over the world executing my script, and a video of how you can spot my code executing in your browser.
And I also sent follow-up emails with a more detailed description of what I had done, how I had found the bug, what kinds of behaviours it let me do, and so on.
Did other people see my script?
At this point, Iâve got the code executing in my own browser, but I want to know if other people are fetching it.
So I enable logging, and as I stream the logs, I realise that thereâs a lot of people accessing this page, and fetching my script â presumably executing it, too.
Bear in mind that, since the script is executed with a simple <script> tag in the main document, itâs executing with exactly the same privileges as the Office web site and the Microsoft Account user who has logged in.
Following my report, I watched the number of requests â not a very big flow, but certainly as many as a dozen or score per second. By the time Microsoft seems to have fixed their web site sometime around July 23, Iâve got around 250,000 requests for that script. All told as of time of writing, 271,194 fetches (and presumably, executions) of this script have occurred. Weirdly, they still keep occurring, in dribs and drabs, and from a different referrer â perhaps these are requests from spiders?
Either way, Iâm keeping the page up, just in case. Itâs free, and it keeps this from being exploited by someone else.
Quarter of a million Office users ran my script
Now I feel like some kind of Mr. Big, with dreams of all the malfeasance I could have gotten up to had I wanted to do so.
But no bounty 
Subdomain takeovers are specifically ruled out of scope, even though I was able to use this one to inject code (in scope) into the web site.
setup.office.com is also not in the list of âin-scope domainsâ, and so is specifically out of scope.
Lesson to me: always read the scope document to the end. You might still submit the bug, but at least you arenât getting needlessly excited about the prospect of a non-existent bounty.
In conclusion
If thereâs a way to cause a subdomain takeover â if thereâs a way to abandon a named resource in such a way that someone can create a resource with that name, while receiving traffic â someone will have screwed up, and it might just as well be Microsoft as anyone else, because the cloud providers are building services faster than they can create meaningful threat models.
Instead of a single focus on preventing subdomain takeovers in Azure, Microsoft have put together any number of different approaches, sometimes separately inventing the same solution inside of a company that really needs to spend more time talking internally.
It should be possible for Azure to completely prevent subdomain takeovers using resources in Azure.
Where the platform isnât helping prevent subdomain takeovers, developers will cause the vulnerability to happen.
We are left with training, detection, and trying to be smarter than the hackers.