 Let's give a warm welcome to a Louis Dion Marcel who's going to talk about cash attacks. So hi, welcome to my talk. Thank you for showing up for the very last slide. I hope you're not too tired, I know I am, but let's get to it. So my name is Louis Dion Marcel. I work for Mendient, which is the consulting company under FireEye. So what I do is a lot of web stuff and red teaming stuff for Mendient. So I'm a consultant, so I get to see a lot of different type of setups and also a lot of different technological stacks, some of which is research that we're going to be talking about today. I'm really excited to be talking at Nordsec for my first time as a long-time attendee. It's really exciting to be on stage. So let's talk about the purpose of this talk. First of all, why attack caching, right? It's been a good few years for cash related attacks. Since 2017, we've had at least one consistent big bug per year. We're going to be talking about the three main bugs that have been coming out in the last few years. So this is a very technical talk, and what I mean by that is not that it's overly complicated or that it's unobtainable if you're not a technical person, but it's definitely oriented to people that know what an HTTP transaction looks like. If you've never seen this before, you might find it's kind of hard to follow, but it should still be relatively obtainable for everyone. So this is somewhat of a 101-102 talk about exploiting cash attacks, and I also implemented it. I talk a lot about how to mitigate these two. So if you're a red teamer or a blue teamer, whichever side of the fence you're on, you should get something out of this talk. So yeah, why do we attack caching? Well, since pretty much the dawn of time in regards to the internet, things have scaled up every year faster than they've never scaled before. And the way that people have been fixing this issue of balancing the load is by implementing cache. This is a vector that prior to the 2017 approximately, no one really was looking at exploiting cache, and it turns out it's utterly exploitable, and we're going to be talking about that today because it's very easy to mess up, and this is exactly what we're going to exploit. So right now, the state of cache or understanding of cache is very limited. As you can see, this is a bug report that I reported to some program and bug crowd, and the person doing the triage could not tell the difference between Clyde-side caching and server-side caching. That's pretty weird because those are very different concepts, and if you're doing triage, you should probably know about this. So it tells you a lot about how our industry has very limited understanding of how caching works. So the table of content, we're going to be doing a one-on-one cache introduction. We're going to be talking about three different subjects afterwards, so cache deception, edge-side include, and cache poisoning. So let's talk about caching as a concept. So this is a very typical request where you have your users, so their actual endpoint, you have your cache server, and of course your application server. So in this case, you see that the user is requesting a static file, which is a Logo to SVG, and the cache server is going to tell, it's going to look inside its internal memory, have I seen this file before? And if it did, it's going to serve that file right back. But in this case, it's never seen it before, either because it's a new file or because the time has expired, right? So it needs to go and fetch it upstream, which it does, and then it sends it back to the user. So the next time that the request sends a Logo to SVG request, you can simply send that same version. You don't have to go and fetch it from upstream. So it speeds up everything. It's a lot faster, really, because you skip a whole HTTP transaction. So this is what caching is at a very high level. So let's talk about our first exploitation technique, which is called WebCache Deception. It was published in 2017 by security researcher, Omar Gil. At the time, he demonstrated it on PayPal, and we're going to be talking about what he demonstrated. And his attack was deceptively simple. And the fact that when people looked at it at the very first publication of his white paper, a lot of people didn't really understand the impact. And when you take a step back and you look at what he did, there's ways to kind of exploit this and kind of use other bugs in order to have a very high impact. So what WebCache Deception is, it's simply abusing URL cache. So cache that is going to look only at the URL in order to have very sensitive information cache, which is then obtainable by an attacker by requesting that caching tree. So what I mean by that is you can imagine the following request, where example.com has an endpoint of profile slash security questions. And you can imagine that the answer to these security questions would be in the HTTP response. The application server is going to send back a very specific header saying, please don't store this. Do not cache this. So this is telling the browser and the cache server that this is sensitive information and it should not be cached under any scenario. And so since the URL is not a static file extension like JPEG, the cache server sees this and it respects it because it says, don't cache this. But then what happens if you add A to JPEG or any static extension at the end of the URL? The server is still responding saying, please don't cache this, don't store this. But the cache server sometimes thinks it knows better. It thinks that A to JPEG is a static file, so it's going to go ahead and cache that file. So you end up with the following. You have your user and I'm a very graphical person, so I like to illustrate the attacks in this fashion. So you have your request for A to JPEG because the victim got tricked into visiting this URL. The cache server has obviously never seen A to JPEG because in reality, it doesn't exist, but it's still sent upstream. And when the upstream server answers with the content of the security question, this is going to get cached. And then you can snoop by behind and go and request that file. And you don't have to be authenticated. You're going to get the cached version of the security question. Now, obviously, this is a terrible design because you should never send back the content of the security questions inside the HTTP response. And I think that's what made people kind of underestimate web cache deception in 2017. They thought, what are you going to steal? There's nothing inside the HTTP response that is very dangerous. And if it does, well, it's just another bug. It's not really a cache bug. But when you think about it, inside the HTTP response, you also have CSRF tokens, which, if you've done a web before, you know that these CSRF tokens are secret values that can be used to send legitimate forms. So if you don't have a CSRF tokens, your form is just disregarded. So if you're able to trigger a web cache deception and kind of use the CSRF tokens that got cached, you're able to completely bypass CSRF mitigations. So you're able to change the content of the security questions, potentially send yourself money depending on what the application does. And so you would need an implementation like the following where you have a two-stage attack. So you trick the user into requesting your evil website, your attack or control website. And then you trick that victim's browser into requesting a very simple image. This image obviously doesn't exist on the server, but this is going to trick the web cache deception bug. And then you tell that victim that just got its information cache to reach you again on a different URL by specifying which random identifier was used. And you do that second step just in order to buy some time in order to go and fetch the content of the CSRF tokens that got cached at a specific URL. So you're just buying time essentially. The next step is obviously to do the actual CSRF attack. So you're going to force that victim into visiting a very specifically crafted form with the leaked CSRF tokens. So using this, you can use cache attacks and CSRF in order to completely bypass CSRF tokens which is an integral part of web security. So that's what I mean by having a complete misunderstanding of web cache attacks. So in the same fashion, we're going to see at the impact but with the following graph. So you have your evil.com website that is going to force the user into requesting the file that is going to trigger the web cache reception bug. And then you tell that victim to please send back the random identifier. And then you go and fetch that secret, the CSRF token that is inside the HTTP response that got cached on the server. And then you can send the actual CSRF attack to the user that is going to force the browser into requesting the actual form that you want to do. So changing security questions or things like that. Of course you couldn't do that on your local client because you're not really logged in. You don't have any cookies. You don't have a real, stateful attack. And by looking at public bug bounties, you see stuff like this. You see people reporting legitimate web cache reception attacks. And not only did the triage completely miss it, the company also missed it. The researcher also missed it. So the researcher read the blog post, read the white paper from Overgill, implemented it, found a valid bug, reported it. And then the company is like, I don't know what you could do with this. Let's close this. And the researcher doesn't know any better. So he's like, all right, I also don't know what I'm doing. So these people are just missing out. So this is why I think this talk is kind of pertinent. So why is this bug even possible? What makes it so that the application sends back a 200 okay to, for example, slash a.jpg at the end of your actual endpoint? Well, for example, here you have Django for which is kind of easy to mess up, in my opinion. Django is a Python framework that uses regular expression in order to specify what your URL endpoints are. So here you have your starting caret, saying if it starts here, and then you have your actual endpoint. So profile slash security questions. Every time you get a get request on this, please match it with the views.questions class, which is the handler or the servlet if you're a Java guy or a girl. So the problem here is that you don't have an ending match delimiter, meaning that anything after this is still going to match. So you just need to add your match delimiter and then slash a.jpg is no longer going to match profile slash security questions. It's a very easy fix. Another easy fix is obviously that your cache should not be ignoring cache headers. So what we saw earlier, you had cache control, no store, no anything, but the cache just thinks it knows better, but that's a very hard problem to tackle in an industry which is trusting the developers. You see like Cloudflare were vulnerable to this and they were also disregarding the cache specifications inside the HTTP responses. Cloudflare interestingly came up with a solution. I wish the solution was let's respect the HTTP headers, but instead what they did is that the response content type must match the extension. So you have slash a.jpg, I need the content type, the response content type to be image.jpg. If it's text.html because you're trying to trigger a webcache, a septum bug, it just doesn't get cached. So it's a weird hack, but it still kind of works, I suppose. If you want to automate finding these types of bugs, you can use the webcache reception scanner by Trustwave. I've used it, it's pretty easy to use, but I didn't have much luck finding any, but I still see a lot of bug reports reporting them and being miss closed. So that's it for webcache deception. It's, as I said, very disciplinary simple, but it can be elevated to a very high critical impact bug. The next part of this talk is going to be edge-side-include injection, which is a vulnerability that is close to my heart because it's something that I've worked on at GoSecure when I worked there about one year ago. So what is edge-side-include before talking about injection? Let's talk about the actual specification. It's a specification that came out nearly 18 years ago when the web was very kind of new-ish. People wanted a way to modify the cache at runtime. They wanted a way, other than by using HTTP headers, to actually cache stuff in a somewhat malleable way. So they wanted to be able to control the cache at runtime without having to, for example, restart the cache server or having to just implement new hidden headers. They wanted a way to have stuff inside the HTTP response that would modify how the cache behaved. So using ESI, what you can do is pretty interesting. You can cache dynamic files, which is not something that you see every day. You can also invalidate cache entries, which is pretty interesting as well, and you can take decisions based on the user state at the cache level. These days, this is what we would call cache computing, edge computing, sorry, which is delegating some of the logic to the servers on the edge of your network, which is delegating core components of the business logic behind your application to something else other than your application. So that's really interesting and that's something that we see often these days. So how ESI works. This is a very primitive, effective website, a weather website, and to the end user, this is just a regular HTTP response, but to the actual ESI-enabled cache server, it could be multiple fragments of which could vary based on the time to live, where the content was fetched from or even if a certain cookie was set. So for example, here you can imagine that the actual labels, so Monday, Tuesday, Wednesday, or even the weather website, that's not likely to change any time suit. So you can cache these for a very long time. You could cache it for months on end and that would be fine. The forecast, however, like 12C or 15C, well, that's likely to change within five minutes. So what you could do is you could have this whole HTTP response be cached, but with varying levels of time to live. So the minus 12, the 12C or the 15C could be also cached, but just for a very limited period of time. So that's very interesting and you can also add conditions. So for example, you could say if a certain cookie is true, then contact this API, which is edge computing. So we're going to be talking about two features that allows ESI to do this. The first one is going to be called ESI Includes. ESI Includes is very easy feature to understand, but it's also the most popular feature of ESI. It's just a small XML snippet that you put inside your HTTP response that specifies a URL and that's it. And what this tells is it tells the cache server to go ahead and fetch that URL and put it inside like replace the actual ESI Include tag with the content of this URL. So here our API would simply return 12C. So then when it's requested, this is the HTTP response that a user gets. So to illustrate this once again, you have your user, your cache server, your actual web server and your web API server. So you have your get requests for index at HTML, for example, and you have the whole thing again where it looks, has it been cached before? No. So it needs to go and fetch it from upstream. Then the upstream server is going to have ESI snippets inside this HTTP response, which tells the cache server, oh, I got ESI tags, I should probably parse them and execute them. And this is what it does. It's going to go and fetch menu.html on the API server. This is going to be sent back to the ESI engine and then step five and three can be concatenated together before returning it in a single HTTP response in step six. So that's a very simple ESI Include. And let's talk about the final ESI feature before talking about exploiting it. It's ESI variables, which are much easier to understand. There's simply a large dictionary of variables that you can expand about the current metadata of the HTTP transaction. So for example, here you have HTTP cookie city, meaning please insert here the content of the city cookie and that's it. So what this allows you to do is using other features of ESI like a ESI if statement and you could do, as I said earlier, if the language cookie is French for example, then please go do an ESI Include of the French version of the API. And this would, as I said, delegate some of the logic to the edge server going back to our idea of edge computing. So here the response would just be replaced by Montreal because that's what I had in the cookie. So now we're left with two facts that are going to kind of set the mood for ESI injection. So you know that ESI tags are inside the HTTP response and you know that the ESI engine is going to parse that HTTP response in order to find ESI tags. What this means is that if you control the HTTP response, therefore control the ESI engine like the cache. It's not a like XSS, right, where if you control the HTTP response, you also control the browser through JavaScript and HTML, but now you're controlling a cache server which has effectively a lot more impact because you're controlling everyone's cache. So what can we do with this and how is it possible in the first place to inject ESI? Well, you can imagine the following snippet which is extremely vulnerable. Whatever you put inside the city gap parameter in your URL is going to be a code back. So someone can simply put an ESI variable tag pointing to the PHP session ID and that's going to be returned inside the HTTP response which is weird because if you've done PHP in the past 10, 15 years, you've known that the PHP session ID has a security feature called HTTP only. This feature does one thing and one thing only is it tells the JavaScript engine, please don't make this cookie available to the browser. But we're not exploiting browsers, we're exploiting cache servers and the cache server really truly doesn't care about the HTTP only flag. As a matter of fact, it doesn't even look at it because when ESI was first implemented, security features on cookies were just not a thing. So the specification never says anything about cookies. So here you're able to leak a session ID using ESI injection which is something that you can never have done with JavaScript injection such as cross-site scripting. So that's very interesting because it allows us to potentially do full account takeovers which is extremely interesting. So if you do ESI injection, you're now able to reach very important cookies which is kind of a bypass of JavaScript's typical cross-site scripting. So this is ESI injection. We discovered this in late 2017 during a proactive engagement at GoSecure. We were reviewing the cache configuration for a very large client in Montreal and they wanted us to look at the cache configuration for all of their edge servers. And what we found is a lot of references in the documentation to edge site includes and at the time we had a very strong web team with a strong web background but no one has ever heard of ESI and even less of ESI injection of course. So everything that I did since late 2017 to April 2018 is find every single ESI implementations that I could get my hands on and find bugs in them. We got a few CVEs assigned and a lot of bypasses and even sometimes remote code execution. And this is kind of what we found we could do with ESI injection, right? So your typical ESI injection usually looks like this. You're going to force the browser into visiting your website by loading an image or any HTML tag that sends a GET response. A GET request, sorry. So here the content of the file is going to be a ESI variable that tells the ESI engine to replace it with the content of the cookie. So if your browser receives this after intransited to a ESI enable cache server this is going to be replaced with the content of potentially your PHP session ID and inside my HTTP response, my logs actually I'm going to get your PHP session ID which I can then inject into my own browser and completely take over your account. This is not something that you could have done with JavaScript, which is why ESI injection in my opinion is extremely powerful. So what you could do with ESI? Well, you can do JavaScript less cookie theft. So even if you have no script because you wear a aluminum hat, you're still vulnerable to this. You can even do transpired session by jacking where I could use the ESI include and an ESI variable in order to have the cache server reach my server. So you would never even see it and I would be leaking your session cookie. So that's extremely powerful as well. Of course, using a simple ESI include is kind of a service high request as a service. You can specify any URL and you get the response. It's the best gadget to get a service high request forgery. You can also do the phasing as we're going to talk about in a minute and you can even do remote code execution in some implementations as found by my Dan colleague Benoite Cotejo-Dwey. He found remote code execution in the XSLT parser for a very specific ESI specification which I thought was really cool. Web and remote code execution, just fantastic. So let's look at one ESI implementation which is Oracle WebCache. We picked Oracle WebCache for a few reasons. Of course, because Oracle usually have very large products so they have bonus features, some of which are usually bonus features to the attacker, unfortunately. They implement so many features that of course their attack surface is larger. It's sad but that's just what happens. So reading the documentation, I saw the following. It said, the ESI in line tag marks a fragment as a separately cacheable fragment embedded in the HTTP response of another object. And I truly don't know what that means or at least I didn't when I read that but I saw that the example was kind of straightforward. You have a ESI in line tag, you have a URL and HTML code. So that sounded like a very easy way of the phasing arbitrary URL or arbitrary cache entries. So I deployed one or I did with the help of a colleague because they're very hard to deploy. And I simply injected myself with an ESI in line tag. I said slash ping, I want you to now return Pong. And then I requested ping and I got Pong. So ESI in line tag is pretty much the easiest way to deface a website. It allows you to create or even rewrite caching trees at runtime. If you want, you can simply rewrite index at HTML and put whatever you want in it. And of course we tried it. So we replaced index at HTML with simply an alert of your PHP session ID. That would be extremely confusing to a victim and also terribly useless. But as a proof of concept, this is interesting because it allows us to know that inside of the ESI in line tag you can commit further ESI instructions. So you can use ESI all the way to full account takeovers using the following scenario. What we did is we wanted a way to have a stealth like instead of defacing the website which is terribly immature, we wanted a way to steal accounts, which is terribly evil. So we have any static file. Here we have jQuery.js. And what we do is we're going to backdoor it simply. jQuery.js is static. If you modify its behavior, well, you can potentially backdoor it without modifying its nature. So here what we do is we add just before or after the jQuery file a simple Ajax request. And this Ajax request is simply going to have another ESI tag. And every time that this ESI tag is parsed, the following is gonna happen of course. So you have your web cache that is tricked into having this commit to the cache. And then before sending it to the browser as jQuery.js, the cache sees further ESI variables. It's going to replace it with the content of your PHP session ID. And then the browser is going to receive this as a whole file and do an Ajax request in my server with the PHP session ID as a parameter. So to the end user, this is completely transparent. You don't see anything broken, but your jQuery.js file just got backdoored and I just got your account. So that's very powerful as well. And as I said, kind of transparent. You don't really see anything changing, but you backdoor static files at the cache level. If you go see the file on the disk, nothing's changed. That's cool. To detect ESI injection, you can use the following tools. I've only used the first two simply because I don't own Acunitics or Equalis. But I know that the Burp Active Scan++ and Burp Flow Scanner have very good heuristics and they should find most ESI injections. So when you think about mitigation for ESI injection, the answer is pretty easy, right? You have to escape, just like HTML or cross-site scripting. You want to escape HTML entities so that you can't tell the browser what to do anymore. So if you were to do HTML entities on all HTML entities, you would have the following, which the cache server doesn't know what to do. But you have to be kind of proactive about it because think about it. How often do you escape HTML entities and say JSON responses or even images? I know I don't because the browser already knows not to execute these as HTML. So if you have the following JSON response with the JSON content type, the cache server still sees that there's ESI include pointing to some arbitrary host. And if you look at this inside of a browser, you see that it's a very good gadget to self-exploitation in order to have server-side request forgery from the cache server perspective. And what's interesting about cache servers is that they have access to a whole lot of stuff because they usually sit on the DMZ. So they have access to internal services, internets, you name it, very good way to do server-side request forgery. For a long time, I wanted to have a real-world example of ESI include injection. I gave two version of this talk before where I had no examples and I could see in people's eyes, they didn't believe me that this was possible. So I wanted to find one, and I eventually found one on a public bug bounty program and they kind of chickened out and wouldn't let me name drop them. So I'm not gonna name drop them, but we're gonna talk about it anyways. So I found a header called style and whatever you put inside that header would just be echoed back in the HTTP response. So here you can see a very straightforward vector for cross-site scripting, which is utterly unrealistic because you can force a user to visit a website with a static arbitrary header unless you do Ajax, but then that would not be really a good vector to exploitation. So this was kind of useless, couldn't do anything with it, but I tried my luck. I use this payload. I said foobar and then ESI vars. And the reason why I used foobar is simply because I wanted to mark her. I wanted to know where my injection started because potentially what would come after could disappear if I'm dealing with a real ESI engine. Then I sent this and it went through a cache server which I later found out was Apache Traffic Server. And so the application sent this to the Apache Traffic Server and this is what I had in my HTTP response. I had the actual hostname of the server that was extremely pleased because that meant that I'm dealing with an ESI or at least the first known ESI injection in a public bug bounty program. What I did with it is simply ESI include of arbitrary host internally. And as you can see here inside the HTTP response, I have the beginning of transaction here which means that I have service outer-quest forgery, true ESI injection with very down vulnerability when you think about this. This is kind of a stupid bug, but you can do anything other than ESI injection so I was extremely pleased to find the real first known public bug bounty ESI injection. I think the company is gonna let me name drop them in a few months so follow me on Twitter. Web cache poisoning. This is the last and in my opinion, the most interesting part of web exploitation simply because no one really knows about it. It's still relatively new. I think James Kill released this at Black Hat last year. So yeah, last August. So it's not even one year old yet. And honestly, go see his talk at Black Hat. It's on YouTube obviously. It's 50 minutes of which half Israel world examples like from bug bounty programs. And so you can see like the wide range of attacks that you can do with this. And we're going to be talking about some that I've found in the wild, which also I think were pretty interesting bugs, none of which I'd seen something like that in the past. So what the web cache poisoning is basically is a very simple attack that is going to combine two kind of tricks. It's going to use unsafe or even sometimes unknown HTTP headers used with very aggressive caching. So caching that should probably not be caching. What I mean by that is the following. So you can imagine the following HTTP request of index.php. And if you go back to that kind of cache 101 that we talked about earlier, caching the way that it described it in the past made sense. You had caching that would only look at the file name. So you had, for example, readme.txt, cache this as readme.txt and that's fine. It's going to be the same for everyone. But the web's gotten so much more. It's gotten mature. It's gotten really different. And now people have really weird browsers. They have different encodings. They have different languages. So if you end up caching index.php using only the file name, well, if a French person requested the website and then you have someone in Korea requesting the same page 20 minutes afterwards, they're not going to be very pleased because the server is going to cache a completely different language. So what cache servers implemented a few years ago, or even 10 more years ago, is cache keys. And what I mean by cache key is that it gave us a way to say which kind of transactions should warrant its own HTTP key. So here you have the file name, the encoding, and the language. So what I mean by that is that if you look at keyed versus unkeyed input, someone requesting the file using index.php in English and using the broadly encoding algorithm would have its own cache key, whereas someone requesting with a French browser using only Jzip would also have its own cache key. So these guys would not be interchanging cache and you would not be able to pollute someone else's cache with your own language or your own encoding. Otherwise, they would just be receiving garbage. So in this case, in this server, the cache keys would be the file name except encoding and except language. It's up to the maintainer of the cache system to define which is keyed, which is unkeyed. So in this example, what is keyed is simply the host and the filing. So anything that is index.php on the hostapp.com warrants its own cache key and that's fine. That's how most cache work. Some of them are URL based. Some of them are like this. Most are like this. So during your pen test, you're trying a bunch of stuff. You have no idea what you're doing and you find this following header, X for worded host, some verb scanner found it. You don't know what it is, but you realize it can do just like ESI injection, add stuff inside of the HTTP response. So it completely overwrites the content of the host, but what you realize is that it's unkeyed, meaning that this as a potential of being cached inside this key, meaning that the next person who requests an index.php on app.com might get this inside the HTTP response. It's a very simple attack using an unknown header or a header that should probably warrant its own individual cache, which allows you to poison cache entries of everyone on the website. That's terribly dangerous, right? Because the next time that you request the file, if it got cached without the X for worded host, you see that it's still there. So you can use the cache as your own cross-site scripting delivery mechanism. The cache becomes kind of a weaponized tool for the attacker. So what can you do with this? Well, it can do a lot of thing, but it would be neat to kind of understand what is this infamous header? Like what is X for worded host and why does it allow me to do this? Well, X for worded host is just a way from the origin server to tell the, from the cache server to tell the origin server which host was used by the actual client. So when you go back to that scenario where you had your user, your cache server, and then your upstream server, the client requesting the cache server will specify, for example, company name.com. But internally, the actual upstream server is probably going to be something called dev or prod01.corp or something. So using the X for worded host is a way from the cache server to tell to the upstream server which host was used. And there's servers out there that are going to use X for worded host inside the HTTP response to kind of keep up with the initial host. The problem, what happens really, is that there's no way that all of the developers are going to tell the maintainers of the cache about every single little HTTP headers that they use inside their products. It's simply impossible because developers, they do really crazy things sometimes and they implement headers that they're going to use for debugging once and they leave it there and in the case of the overwriting X for worded host, you'd be surprised on how many websites this works. So for all of the cache servers that don't specify the X for worded host warrants its own individual cache entry, you can do cache poisoning on these websites. So yeah, tons of headers are secret. You're not supposed to know about them. If you're going to GitHub and read the source code, you can find some, but what I like to do is brute forcing them. As I said, style, like I didn't wake up one day and go on that website and try the style header. Like I was brute forcing words of the dictionary and that's what it got me. So before trying this on public websites, need to be safe, so poison safety, funny name. You can see here, I'm requesting index of PHP and then I just add foobar at the end. And what this does is it's going to create its own individual cache entry so that you don't end up poisoning every single user of the website. So this allows you to poison the cache only for yourself. So you can do a proof of concept here. So for example, x-worded host, and then you can see that you poison it and then you remove that x-worded host and it's still here and through all this, you never impacted the actual index of PHP. So you can attack the application without attacking every single user. So that's very interesting and also very important because if you end up poisoning the cache for everyone, whoever you report it to is going to be extremely angry at you rightfully so. So the impact of web cache poisoning, well, as we saw, you can do cross-size scripting. You can potentially do denial of service. You can do way more, right? You can potentially leak administrative panels. You can do a lot of crazy things which we're going to be talking about two of them which I thought was really interesting. To find these bugs, just before closing with demos, you can use this extension which was published by Jameskill once again. It allows you to brute force not only headers but also get parameters and cookies. It allows you to find really hidden stuff that developers are going to be adding to their application, but not telling anyone. So this is a way to brute force them really quickly. I remember James had a very good example of... Like you reported a bug to some framework that was vulnerable to web cache poisoning. And the person saying, like receiving the bug report said, I see that you're telling me that X-forwarded host can poison the cache but I grep through all of my code and I don't see this header used anywhere. Like, am I losing my mind? What is going on? Where is this header coming from? And it was a dependency injection from XAND on which the framework was built up onto that injected this secret or unknown header. So even very mature frameworks, I think this was... I don't remember which one it was, but it was a very big framework. So even really mature frameworks for the really mature code base as well are still vulnerable to finding really weird edge cases using HTTP headers. So let's talk about one neat trick that I found using web cache poisoning. I call it SEO takeover, SEO being search engine optimization. So by brute forcing headers, I found the following X-original host and anything that I put inside of it would be put back inside of the HTTP response and the link rail canonical. I thought that was interesting simply because if I remove the X-original host, it would stay there. I was poisoning the cache with that header. So if I remove it, the response is poisoned. I was kind of sad when I realized that I could not break out of that tag. For example, I couldn't be doing single quote and then put a cross-executing payload. So I would have to be limited to this tag. And the link rail canonical is something that I think most of us have seen before, but no one knows what it does. It's just, you just accept that it's there and you don't know what it does. So I started reading, what is this tag? And I found a few images and it made sense. It's a way for your website to have, it's a way for you to tell Google Yahoo and all those fancy search engines which article should be prioritized. So here you have three different URLs for the same article, for example. So your site.com and then you have some parameter. You probably don't want this to be the main result when you search for that website. Same thing here, you have slash print, probably not the best. Here you even have a partner to have a copy of your article and you're telling these browser, these search engines, please prioritize this one. So if the search engine, if you search for example, company name and then the name of the article, these are all going to be pointed to this one, meaning that Google is going to put this one here at the top. So what this company was doing, it was like a stock website. So you could look for stocks on that website, so it's largely, it's worldwide, right? So you had CA for Canada, India, France, and all of them were telling Google and all these other search engines, this is the one that I want you to prioritize. And once again, they didn't allow me to talk about them publicly, so XXX is gonna have to do. So what I did is I went through all of these websites and I made a proof of concept where the content of the rail canonical would be my malicious domain. So then every time Googlebot would visit these websites, the cash would be poisoned with my malicious domain so that the next time someone would look for a stock like FireEye, they would end up with something like this. I would be on the top. So here, I obviously didn't do this because it's one way to get to jail, but I just modified the HTTP response to the legit search entry. Please click here and put your password. So that would be my potential threat scenario, right? I would be typosquadding the company and I would be saying login or I don't know, like a free discount on whatever, put your credit card here. So this is what it allows you to do, but when you think about it, it's a very simple cash bug. So that's what I mean by adding creativity to your pentest. This is something that at first I was probably gonna give up until I looked at what this tag was doing and I found all of this crazy stuff. What was even more interesting is that one of the cash key was the user agent, meaning that I could be targeting a very specific user agent. For example, I could be targeting Googlebot's user agent and only caching my malicious domain inside that user agent, meaning that when the sysadmin is trader gets a call from the CISO that night and says, what the hell's going on? That sysadmin would go visit their webpage and the cash would not be poisoned. It would only be poisoned for Googlebot. So that's a very easy way to target sysadmin's traders if you know what their user agents are or if you wanna make the loser mine, just target a very popular user agent that is not theirs. So you're never going to see where it comes from. The cash looks legit on their end. The application is not compromised. They would just not know where this bug comes from. So that's even more neat, I think. Final and second example, denial of service. This one is very simple, but I think that the nature of the bug makes it so interesting. Once again, I don't have a public acknowledgement that I can name the company, so welcome to censorship. Here, we're going to be talking about this example here where you have an investor's website. So it's a company that offers a software as a service where you could be hosting your own investor's relations website. So for example, your company is, let's say, FireEye, say, ir.fireeye.com or investors.fireeye.com, you would have the stock information. When's the earning call? What is the blah, blah, blah, money, money? And I realized that if you use the exported proto header, which I brood for us once again, the cash would be trying something like the following in order to fetch the original upstream server. It would be prepending the content of that header here, exported proto, as the protocol for the upstream request. And then the host, I could not modify because it was linked to the host. And if I modified it, well, I'm not going to hit the right cash server. So I could only modify this. But then by putting foobar, this is essentially requesting this, foobar.com slash slash investors and then the company name foobar. Once again, this is just to do poison safety. So using this, obviously, the application would just crash. You would have the little error saying web maintenance message, blah, blah, blah, doesn't work anymore. What was interesting is that this got cached for a very long time, meaning that I could wait for the earning calls for that company, shut down the website, and you would have very angry investors. And all I did was a stupid HTTP request putting exported proto foobar. So since this header was once again on keyed, you could effectively shut down the whole website with a single HTTP response. I found this on a software as a service company, obviously, and they have very large clients. So Fortune 100s, 500s, whatever. So it's hard to demonstrate that they're all vulnerable, so I have different colors, but you're gonna have to trust me. So yeah, so this is kind of like the neatest bug, I think, with the least amount of effort, right? Don't all of service, if you do a don't all of service on the any random website, usually it's very limited, but with earning calls, you don't mess around with that. So that's my time. That's also everything that I have to tell you about cash. There is still a lot of research to be done on cash stuff. If you're interested in this, follow James Kettle. I also post on this from time to time, but yeah, just go around the internet, deploy cash systems and try to break them. It's usually not that hard. It's still very new. So get in on the hype. Yeah, just cash me outside for questions. And follow me on Twitter. Okay. Thank you. Thank you.