Adding TRR for Authorization Code Phishing#21
Conversation
|
Sorry for the delay. I approved the workflow and looks like there are some linter changes that need addressed. Looks mostly like line-wrapping and a few inline-urls. |
vanvleeta
left a comment
There was a problem hiding this comment.
Excellent first draft! Thank you for the submission!
dumpst3rfir3
left a comment
There was a problem hiding this comment.
I agree with other comments, great work! I'm not sure I had much to add to what's already been said, but I left a couple of comments in there.
|
I think I fixed all of the issues with this new commit. If there are more issues please let me know and I will be happy to fix! Thanks again for the review! |
mjwhitta
left a comment
There was a problem hiding this comment.
Just a couple small things. Ultimately this looks really good!
dumpst3rfir3
left a comment
There was a problem hiding this comment.
LGTM. I had some nit-picky comments/questions, but feel free to ignore.
|
Really sorry for the long delay, btw. |
Co-authored-by: vanvleeta <vanvleet@gmail.com>
Co-authored-by: vanvleeta <vanvleet@gmail.com>
08cfcbb to
32dbedf
Compare
|
Fresh batch of updates. Thanks for the feedback! If you see any other issues, please let me know! |
|
I think this LGTM, but I believe @vanvleeta might have something to say about the DDM. I can't tell if it was made with the same software he typically uses (arrows?). If he approves, then I will also approve. |
vanvleeta
left a comment
There was a problem hiding this comment.
Looking great! Last few suggestions!
| A second variant involves a malicious application impersonating first-party | ||
| software. A trojanized client (for example, a tampered build of Visual Studio | ||
| Code) could use the genuine first-party `client_id` and a registered `localhost` | ||
| reply URL, receive the authorization code on the loopback listener, and then | ||
| forward it to attacker-controlled infrastructure. This variant is not treated as | ||
| a separate procedure here because the social engineering occurs earlier, when | ||
| the victim is convinced to install the malicious software; once that trust is | ||
| established the code collection no longer depends on the `localhost` redirect | ||
| indicator central to this procedure. |
There was a problem hiding this comment.
This variant seems like it's the same essential operations, but with a pre-positioned collected instead of tricking the user to do the collecting? But the essential telemetry (localhost replyurl) would remain the same? I'd recommend moving it into a note and clarifying a little.
| A second variant involves a malicious application impersonating first-party | |
| software. A trojanized client (for example, a tampered build of Visual Studio | |
| Code) could use the genuine first-party `client_id` and a registered `localhost` | |
| reply URL, receive the authorization code on the loopback listener, and then | |
| forward it to attacker-controlled infrastructure. This variant is not treated as | |
| a separate procedure here because the social engineering occurs earlier, when | |
| the victim is convinced to install the malicious software; once that trust is | |
| established the code collection no longer depends on the `localhost` redirect | |
| indicator central to this procedure. | |
| > [!NOTE] | |
| > | |
| > There is a possible variation on this procedure that involves the attacker | |
| > pre-positioning an application (for example, a trojanized version of popular | |
| > software like Visual Studio Code) on the victim's machine, which could then | |
| > listen on `localhost` and collect the authorization code and send it to | |
| > attacker controlled infrastructure without needed to trick the user into | |
| > collecting and submitting the code. This approach retains the same essential | |
| > operations: the user is tricked into consenting and the code is sent to | |
| > localhost. It differs only in how the code is collected and transmitted. We | |
| > will treat it as a variant of Procedure A in this TRR. |
| A related redirect-hijack variant would be materially different if an attacker | ||
| could use the same first-party `client_id` with a registered reply URL that | ||
| delivers the code directly to attacker-controlled infrastructure. That variant | ||
| would not rely on a `localhost` indicator and would require different detection | ||
| logic. This TRR does not define that as a separate procedure because the | ||
| reviewed public research does not confirm an attacker-controlled reply URL for | ||
| the Microsoft first-party applications discussed here. If future research | ||
| identifies a first-party app with an exploitable open redirect, wildcard reply | ||
| URL, or other misconfigured reply URL that allows direct attacker collection, | ||
| that path should be added as a distinct procedure. |
There was a problem hiding this comment.
Would recommend rephrasing for clarity and moving it into the scope statement for the TRR.
| A related redirect-hijack variant would be materially different if an attacker | |
| could use the same first-party `client_id` with a registered reply URL that | |
| delivers the code directly to attacker-controlled infrastructure. That variant | |
| would not rely on a `localhost` indicator and would require different detection | |
| logic. This TRR does not define that as a separate procedure because the | |
| reviewed public research does not confirm an attacker-controlled reply URL for | |
| the Microsoft first-party applications discussed here. If future research | |
| identifies a first-party app with an exploitable open redirect, wildcard reply | |
| URL, or other misconfigured reply URL that allows direct attacker collection, | |
| that path should be added as a distinct procedure. |
| token endpoint to obtain an access token representing the victim's identity, | ||
| allowing access to APIs and services such as Microsoft Graph or Azure Resource | ||
| Manager depending on the granted permissions. | ||
|
|
There was a problem hiding this comment.
Moving this from procedure dialogue to scope statement.
| This TRR does not cover a situation where an attacker is able to gain control | |
| over a sudomain for a legitimate registered reply url for a Microsoft | |
| first-party application. In that situation, the attacker could provide the | |
| malicious subdomain as the reply url in the consent request and the | |
| authorization code would be sent directly to them. This TRR will not address | |
| this possiblity because responsiblity for securing first-party applications, | |
| including their reply URLs, is held by Microsoft and out of the control of | |
| individual tenant owners. | |
| adding a new reply URL or registering a new application. They are selecting a | ||
| valid reply URL already present on a Microsoft first-party application, such as | ||
| a `localhost` reply URL used by command-line or development-oriented clients. | ||
|
|
There was a problem hiding this comment.
Let's give folks the ability to see what this looks like in their environment.
| > [NOTE!] | |
| > | |
| > You can list the registered reply URLs for applications in your tenant with | |
| > the following Powershell script: | |
| > | |
| > ```powershell | |
| > Connect-MgGraph -scope "Directory.Read.All" | |
| > Get-MgServicePrincipal -All | Where-Object { | |
| > $_.ReplyUrls -like "*localhost*" | |
| > } | |
| > ``` |
Hello,
This pull request adds a Technique Research Report (TRR) covering OAuth Authorization Code Phishing, including documentation of the ConsentFix procedure within Microsoft Entra ID environments. The report outlines the mechanics of the authorization code flow and describes how attackers can abuse redirect behavior to obtain authorization codes and redeem them for access tokens.
This is my first contribution to the repository, so please let me know if there are any formatting issues or changes that would improve the submission. I appreciate any feedback from the maintainers.