Exploiting TRACE
TL;DR
The presence of the TRACE method is generally considered to be at best an informational finding (and in isolation, I wouldn’t disagree with that). But before you deploy your meh, if you know what to look for, the TRACE method (and any other mechanism that reflect requests) can be added to a practical attack chain, and will dramatically increase the impact of an exploit.
Background
The TRACE method was originally introduced as a diagnostic tool, to reflect back the request that was received by the server. But as is the way, it didn’t take too long before enterprising individuals realised that it could be combined with any old XSS, to provide a practical way of getting around the HttpOnly cookie flag (which is intended to stop sensitive cookies being accessible to javascript).
At this point, you’ll probably be thinking “yeah, but changes to the XMLHttpRequest and fetch standards mean that you can’t send the TRACE method anymore”, and you’d be right.
But don’t you think it would be cool if you could bypass those restrictions, or there were other ways to achieve the same, reflected request? Well, you’ve come to the right place!
In the Red Corner
From an offensive point of view, this should be interesting as it enables two useful things:
firstly, the diagnostic response itself often contains sensitive information from the app stack, like keys and tokens that have been added by internal systems, along with evidence of hidden issues, like missing encryption on internal connections etc. Scrutinise carefully!
and secondly, it allows you to dramatically increase the impact of other exploits, turning a hum-drum XSS into a full account takeover etc.
Override headers
Although it is true that changes to the XMLHttpRequest and fetch standards have stopped the direct use of the TRACE method, up until last year you could still use the standard override headers (x-http-method-override etc.) to deliver the same attack. And even better, with the right set of CORS misconfigurations, you didn’t even need to chain it to anything else to deliver the attack.
That said, only the most common override headers are blocked by the standard, so it is still possible to find and exploit the less common ones in the wild (like _method, x-method and x-tunneled-method).
GET /path.html HTTP/1.1
Host: yomama.com
_method: TRACE
Query and body parameters
A collection of the common app stacks will accept a method override parameter by default, which functions the same as the TRACE method. You’ll need to deploy your google-fu and tweak your approach to match the target environment (I’ve included a handful of references at the end of this blog to get you started). And once again, check for CORS misconfigurations, as if present, these are fully exploitable all on their own.
GET /path.html?_method=TRACE HTTP/1.1
Host: yomama.com
Weird shit
There are a lot of app instrumentation products around now, which gather user statistics at a low level, by passing the raw request on to an instrumentation stack for analysis. Usually this happens via a collection of client-side javascript plugins, but I’ve seen some really awful implementations that put the raw request into a JSON blob embedded within the main page, which in-turn gets sent on to the instrumentation.
Gaining access to the reflected request obviously works just fine in a chain with XSS, but if you can combine it with something else, like cache deception, this is a really elegant way of gaining access to a user’s session tokens, which can often be leveraged into a full account takeover.
In the Blue Corner
There are two things you can immediately do to defend against these kinds of reflected request attacks.
Firstly, add signatures to your IDS/SIEM that trigger on the main override headers and parameters (this should be as early in your app stack as possible, so it catches headers entering your environment, not those added by any of your internal components). Monitor the output closely, as you may find that you have apps deployed that depend on some of these headers.
Secondly, strip (or reject) any of the headers and parameters that your apps don’t need as early as possible in your app stack.
References
https://www.rfc-editor.org/rfc/rfc2068#section-9.8