{
	"id": "c57f955c-dcc8-4adc-af9a-38f2d1d94577",
	"created_at": "2026-04-06T00:14:07.842001Z",
	"updated_at": "2026-04-10T13:12:18.445559Z",
	"deleted_at": null,
	"sha1_hash": "0ba0f3c1de495df0f9b75100dfe3c3c97c2dc121",
	"title": "Phishing with OAuth and o365/Azure",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 890279,
	"plain_text": "Phishing with OAuth and o365/Azure\r\nBy Etienne Stalmans\r\nPublished: 2017-08-02 · Archived: 2026-04-05 18:17:37 UTC\r\nTypically phishing has provided a low tech approach to getting access to credentials and services. The mainfocus up until\r\nnow has been on getting username\u0026passwords or tricking users into executing code. Subsequently, user awareness has gone\r\nup and users are better at identifying suspicious pages. Experience has shown that the click-through rate on emails have\r\nremained high, while users have been (slightly) less likely to enter credentials and more likely to report the phishing page.\r\nRecently, while digging into the authentication options available in Office365, I realised that OAuth could allow for a\r\nstealthy phishing mechanism. The benefits that OAuth provide are numerous;\r\n1. Not your average phishing page / something new\r\n2. Hosted by our target (o365) - so no dodgy domains or trikery\r\n3. If users aren’t entering actual credentials, they are less likely to report that they made a mistake\r\nBelow I’ll outline the process for crafting a phishing ‘app’ and using this with Office365.\r\nDisclaimer: I have reported this to MSRC and was told it appears to be a UI/Design issue and not a security issue.\r\nWhat is OAuth\r\nOAuth is designed to allow for third-party application access to Microsoft services, without disclosing user credentials, or\r\nconstantly asking users to reauthenticate. Users log in once, give an application permission to access certain functions\r\n(scopes) and then forget about it.\r\nThe design and implementation of OAuth in Office365/Azure is pretty well laid out in the MS Documentation.\r\nIf you follow the link, you’ll find a good description of the OAuth flow, namely:\r\n1. User navigates to: https://login.microsoft.com/common/oauth2/v2.0/authorize\r\n2. User grants permission to your app and a redirect occurs to: https://your.application.host/authrized\r\n3. Your app requests an OAuth token from MS and then redirects the user, either to MS or any arbitrary site.\r\nThe only link that your phishing target sees in this case is the https://login.microsoft.com/common/oauth2/v2.0/authorize\r\nlink. It meets all the criteria users are trained to check for. It goes to the Microsoft domain, it has HTTPS, it loads Microsoft\r\ncontent and if the user is logged in, will actually greet them with their correct account details.\r\nBuilding the Phish\r\nFor this you’ll require a valid Microsoft ’live’ account, I’m simply using an Outlook account.\r\nThe “application”\r\nFirstly you’ll need to create an app at apps.dev.microsoft.com. Here you’ll simply be registering a valid application with\r\nMicrosoft, giving it a name and defining the call back URLs.\r\nIt’s really easy, just follow the on-screen wizard!\r\n1. Set the application name (use something convincing)\r\n2. And set your Redirect URL\r\nThe Application Name is what will be displayed to the user, and this is what needs to convince them to trust your app or not.\r\nI’ve gone with Account Verification Service, the reasons for this will become clear soon. Oh, it also provides you with a\r\nconvincing reason for users to click through, ie: “Your account needs to be verified…”, “Your account has expired…”,\r\n“Confirm your account details…” etc etc.\r\nhttps://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/\r\nPage 1 of 5\n\nCreating your App\r\nNext, you will need to use add platform to select web. Insert a Redirect URL – In version 1.0 of the OAuth API (and for non-o365 accounts) Microsoft will display the hostname to the user, just below the application name. Choose wisely if you are\r\nplanning on using v1.0. Microsoft also forces HTTPS here, so ensure that you have a valid certificate on your site, otherwise\r\nthe browser is going to be throwing up nasty warnings and the game will be up.\r\nFinally you need to select the permissions you want a user to grant your application. The permissions you choose are up to\r\nyou, but try avoid selecting all permissions, this could result in raising suspicions. A useful permission to have is\r\noffline_access, as it allows is for your application to reauthenticate, without user credentials or user interaction, even once\r\nthe access token has expired. Typically your app is only issued with an authorisation token, which is only valid for set period\r\nof time. When this expires, you’ll need to get a new token, but the user will have to authorise your app to do this. With the\r\noffline_access permission, your app is issued with a refresh token token, which allows reauthentication at any point in time,\r\neven if your actual access token has expired.\r\nSelect your permissions\r\nThe “redirect”\r\nThe last thing to setup is the actual redirect url application; this is where the user is redirected to, once they authorise your\r\napplication, and you can get the code you need to request an access token from Microsoft.\r\nFor this I’ve written a bit of Go (sorry, I thought about re-coding this into Python and then got over it..)\r\nRedirect Application\r\nThere are a few parts to change, namely client_id, scope and redirect_url (I’ve commented these in the code). The\r\napplication will be served over HTTPS and uses your cert.pem and cert.key. These should be valid for your domain and it’s\r\nup to you where you get them.\r\nPhishy Phish\r\nYou’ll now be able to send your phishing email with the link to authorise our application.\r\nThe link should be changed to match your client_id (application id), your redirect_url and scope. If you wish you can also\r\nchange the state but remember that you’ll need to change the state in the Go script as well (this is used as a CSRF token).\r\nhttps://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/\r\nPage 2 of 5\n\nhttps://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=fceae27c-cac4-4bd3-947e-eafc98594409\u0026response_type=code\u0026redirect_uri=https%3A%2F%2Fyour.application.host%2Fpermission\u0026response_mode=query\u0026scope=openid%20offline_\r\nSending this link out, hopefully a user takes the bait and clicks. Once they do this, they should see one of the following:\r\nIf they haven’t logged in yet\r\nIf they are logged in\r\nThe user will either need to login or confirm the account they wish to use. They will then be redirected to the permission\r\npage. If using v1.0 of the API, the user will be shown the domain used in your redirect_url - fortunately for us, v1.0 doesn’t\r\nactually work that well with o365 anymore, and we can default to v2.0. Version 2 has a serious design flaw; your App\r\npublisher website is shown as microsoftaccounts.onmicrosoft.com, winning!\r\nThe permissions page\r\nOnce the user clicks accept they will be redirected to our redirect_url, where the Go script will extract the authorisation\r\ncode, request an OAuth token from Microsoft and redirect the user to https://outlook.office365.com. All of this happens\r\nwithout warning and the user would only “see” a redirect to Outlook.\r\nhttps://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/\r\nPage 3 of 5\n\nRequesting the OAuth token\r\nThis token retrieved includes our refresh_token so save this somewhere for future use.\r\nExploit\r\nNow that you have a valid OAuth token, this can be used to interact with the target user’s account. A detailed list of API\r\ncalls is available through MSDN.\r\nA few quick examples, how about retrieving the messages and listing their subjects? Use:\r\nhttps://outlook.office.com/api/v2.0/me/messages\r\nRequest a short list of emails \u0026 subjects\r\nThe API also allows for search, so you could search for juicy info, such as passwords. Use:\r\nhttps://outlook.office.com/api/v2.0/me/messages?search=\"password\"\r\nShow emails containing the word password\r\nFin\r\nThere are a bunch of attack options available here, with the graph API providing a ton of interesting functionality. How you\r\nchoose to use this is completely up to you. I find it to be a nice means for gaining a foothold, you could even start sending\r\nmail using the compromised account (if you requested the correct permission set).\r\nFix\r\nThis is very similar to the OAuth issue that affected Google Apps not too long ago. That incident, as mentioned in the linked\r\narticle, was particularly successful as it presented users with a valid interface, and no indication that something was amiss.\r\nThe same steps should be taken here to make it clear to users that this is a third-party app requesting access. I guess this is\r\nprobably worm-able as well. For the curious, “Live” accounts get a slightly better dialog. At least it displays the “app\r\npublisher webpage” (in this case an IP address)\r\nhttps://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/\r\nPage 4 of 5\n\nLive dialog\r\nSource: https://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/\r\nhttps://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://staaldraad.github.io/2017/08/02/o356-phishing-with-oauth/"
	],
	"report_names": [
		"o356-phishing-with-oauth"
	],
	"threat_actors": [],
	"ts_created_at": 1775434447,
	"ts_updated_at": 1775826738,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/0ba0f3c1de495df0f9b75100dfe3c3c97c2dc121.pdf",
		"text": "https://archive.orkl.eu/0ba0f3c1de495df0f9b75100dfe3c3c97c2dc121.txt",
		"img": "https://archive.orkl.eu/0ba0f3c1de495df0f9b75100dfe3c3c97c2dc121.jpg"
	}
}