[00:00.000 --> 00:05.920] I have no idea what time this will be played, but thanks for coming to my virtual talk for [00:05.920 --> 00:11.300] this edition of DEF CON SAFE MODE, and I figured a great way to start it off, [00:11.300 --> 00:16.160] since this is technically my first DEF CON talk, would be to take a shot. [00:16.160 --> 00:20.800] So we've got some 1712 bourbon, so let's get it started. [00:20.800 --> 00:22.180] Don't fuck it up! [00:23.900 --> 00:28.680] So, other than that, this is normally where I try and get some [00:29.360 --> 00:33.660] crowd engagement in the talk. So, whenever you're watching this, [00:33.660 --> 00:37.780] and I will hopefully be in the Discord at least during the talk, if not around the same time, [00:38.240 --> 00:44.100] let me know if you are aware of XSS or if you're not. Hopefully most of you are, [00:44.100 --> 00:47.580] with this being the Red Team Village, but for those of you that aren't, [00:47.580 --> 00:50.900] hopefully you'll at least learn a little bit about cross-site scripting, [00:50.900 --> 00:55.680] as well as sort of why it's more of a severe attack than you may initially realize. [00:57.140 --> 01:03.400] So, I realized that I need to move this webcam out of the way. Let's try the top right corner. [01:05.880 --> 01:10.020] So, I'm Ray Doyle. You can find me on Twitter, at DoylerSec, [01:11.480 --> 01:17.640] or my blog, Doyler.net. I'm currently a Senior Staff Adversarial Engineer at Avalara. [01:17.640 --> 01:22.520] We're a tax, software, and compliance company. We're always hiring, but not necessarily for [01:22.520 --> 01:25.060] security, so definitely reach out to me if you're looking for work. [01:25.660 --> 01:31.400] I love CTFs. I've actually been on two DEF CON Black Badge winning CTF teams, [01:31.400 --> 01:37.120] for the Wireless CTF, as well as the IoT CTF. I love them, if you want to talk CTFs, [01:37.120 --> 01:42.040] as well as being a member of Team Eversec, who actually runs some CTFs, mostly in North [01:42.040 --> 01:48.140] Carolina-based conferences, but a few other regional ones. So, definitely reach out to [01:48.140 --> 01:53.400] me about conferences or CTFs, things like that. And I also love collecting certifications. [01:53.400 --> 01:58.900] I got my OSCE last year, my OSCP a few years back. I'm always looking for new ideas for [01:58.900 --> 02:02.460] certs to take or training, so definitely let me know if you're aware of any. [02:04.380 --> 02:10.140] And also, if you couldn't tell from the Avalara orange on the slides and the last one, clearly [02:10.140 --> 02:15.340] it's our company color. I figured I might as well go with the theme. So, a few caveats before we [02:15.340 --> 02:22.160] get into this. I'm not an expert in cross-site scripting, I'm not a bug bounty hunter, [02:22.160 --> 02:27.380] I'm definitely not a JavaScript expert, but I am a penetration tester who has used cross-site [02:27.380 --> 02:31.240] scripting in the past, so hopefully I'll be able to at least teach you a few tricks. [02:31.600 --> 02:37.920] This is going to be a very example-heavy and focused talk, so definitely feel free to go [02:37.920 --> 02:43.440] back over the slides, re-watch the videos. I'm going to include a lot of links in the [02:43.440 --> 02:50.260] presenter-slash-comments section of each slide, so if I don't post them soon enough, [02:50.260 --> 02:53.500] reach out to me on Twitter and I'll get you a copy sooner rather than later. [02:53.780 --> 02:56.600] It's definitely going to be a lot to digest. [02:57.520 --> 03:01.800] Like I said before, I don't participate in bug bounties, but some of these payloads should help [03:01.800 --> 03:06.840] you to demonstrate the severity of the vulnerabilities you find and maybe get them [03:06.840 --> 03:12.060] increased to a P1 or something like that. A lot of this information is going to be from [03:12.060 --> 03:16.280] my personal blog. I've already used a lot of these exploits and payloads before, [03:16.280 --> 03:20.060] so I will include links to that to a little more in-depth post as well as some [03:20.060 --> 03:25.340] more screenshots and things like that. I'm going to cover a ton of information, [03:25.340 --> 03:30.920] so please feel free to ask questions afterwards, before, or on Twitter at any point. [03:31.340 --> 03:36.120] And I'm not going to cover really how to find cross-site scripting or what really protects [03:36.120 --> 03:41.480] against it, so this is really going to be heavily focused on exploiting it once you've found it. [03:42.440 --> 03:49.780] Also, another caveat, this is obviously a COVID recording of a presentation that [03:49.780 --> 03:54.020] won't be given live, so any technical issues I apologize for, I'm going to do my best. [03:54.020 --> 04:00.940] We'll see how it goes. So, I know that this isn't live, but definitely feel free to use [04:00.940 --> 04:06.060] the weaponized XSS hashtag on Twitter. I'll definitely be checking it during the conference [04:06.060 --> 04:10.960] as well as any time afterwards. If you want to talk about my technical issues, [04:10.960 --> 04:14.340] if you want to share some really cool payloads with the community, really anything, [04:14.340 --> 04:20.160] just to have some sort of viewer interaction during this weird virtual conference. [04:21.140 --> 04:26.500] So, here's a quick introduction to cross-site scripting. This is from OWASP directly. [04:26.520 --> 04:32.640] I'm not going to just re-read it back to you, but the gist of it is that cross-site scripting [04:32.640 --> 04:39.260] is an injection-based attack in which an attacker is able to [04:39.260 --> 04:46.820] inject usually JavaScript, but can also sort of cover HTML as well as CSS. It's frequently used [04:46.820 --> 04:53.760] for loading malicious scripts and executing them on the target's client-side browser. So, [04:53.760 --> 04:59.260] these aren't going to be attacking your servers as much as the people who are connecting to your [04:59.260 --> 05:07.640] websites, things like that. So, the most basic example of going beyond Alert 1 is Alert 2. [05:07.920 --> 05:12.260] Now, while this is fairly tongue-in-cheek, I do want to quickly point out the fact [05:12.260 --> 05:17.420] that there are going to be systems, and I may move this window from time to time, [05:17.420 --> 05:24.180] I apologize in advance. So, there may be systems that are alerting or filtering for [05:24.180 --> 05:31.740] very specific payloads, and something like Alert 2 could even bypass a [05:31.740 --> 05:35.780] deny list that was protecting against Alert 1, things like that. So, when you're working [05:35.780 --> 05:40.000] on these weaponized payloads, be sure to try different variations or different ways to get [05:40.000 --> 05:47.860] them into these systems. So, the first example I wanted to cover is loading external scripts. [05:47.860 --> 05:52.920] This is the most basic example, but it's fairly important to try and do. [05:52.920 --> 06:00.420] So, anywhere in which you were able to inject that script Alert 1, generally speaking, [06:00.420 --> 06:05.880] you could also load an external JavaScript file. So, in this case, I'm loading doiler.net [06:05.880 --> 06:12.180] slash evil.js. Now, what this allows you to do is have bigger payloads, not worry as much about [06:12.180 --> 06:17.140] things like encoding, stuff like that. So, if at all possible, you should definitely try and go [06:17.140 --> 06:22.920] with an external-based payload instead of keeping it inline if you're able to. [06:24.320 --> 06:32.500] So, another example of this is using staged cross-site scripting. So, if you find yourself [06:32.500 --> 06:38.140] injecting into an already existing script tag, you obviously cannot set the source of it. Or, [06:38.140 --> 06:43.020] if you find yourself in an HTML event handler, you aren't going to be able to load an external [06:43.020 --> 06:52.600] JavaScript file. In this case, what you could do is have inline JavaScript that will create a new [06:52.600 --> 06:59.540] script element inside of the document, then set the source of that script element to be your [06:59.540 --> 07:05.320] external JavaScript payload. So, for this quick example, it's bit.ly slash example. [07:06.160 --> 07:11.180] And this is a payload that was created by someone. I've included a link to the GitHub [07:11.180 --> 07:16.060] in the comments. Definitely check it out. It's come in really handy when I've been stuck in sort [07:16.060 --> 07:21.060] of an HTML event handler, especially. If you are in an existing script tag, you could write longer [07:21.060 --> 07:25.700] JavaScript, but you may run across payload length limits, things of that nature. [07:28.600 --> 07:38.660] So, the most common payload that you'll see or hear of when discussing or attacking using cross-site [07:38.660 --> 07:46.720] scripting is going to be cookie stealing. So, in this example, our XSS payload writes a new image [07:46.720 --> 07:55.480] tag to the document, only this image tag has a cookie parameter that sends the document.cookie [07:55.480 --> 08:00.460] from your local application to the attacker-controlled server. So, in this case, [08:00.460 --> 08:06.080] any cookies we had on our target web application would have been sent to doload.net through the [08:06.080 --> 08:13.040] HTML get parameters. Now, there are things that are going to protect against this, like HTTP-only [08:13.040 --> 08:17.220] cookies, things like that. But if you are able to successfully grab one of these cookies, [08:17.220 --> 08:22.520] you could use it for session hijacking, any existing sessions, and basically logging in as [08:22.520 --> 08:27.380] that user to the application without knowing their credentials. So, definitely keep this one in mind. [08:27.380 --> 08:33.400] This is the one I've used most often in my career, and it's super simple and straightforward to do. [08:34.880 --> 08:43.620] So, another... a different way that XSS injection, or technically any injection, could be used is to [08:43.620 --> 08:50.880] rewrite the HTML of the page. So, the example on the left sort of shows this, but it creates a new [08:50.880 --> 08:58.580] div that takes up 100% of the page, puts it on top, and allows you to write arbitrary HTML into that [08:58.580 --> 09:06.000] div. What that means is you basically get to overwrite the content that your target sees for [09:06.000 --> 09:13.060] an entire website. So, that image on the right looks like a standard Drupal login page, but it's [09:13.060 --> 09:18.400] actually a cross-site scripting vulnerability that was found in a Drupal comments section, [09:18.400 --> 09:24.940] and an attacker used that post to rewrite the HTML of the page to make it look like an access [09:24.940 --> 09:31.780] denied or an authentication page. Sorry about that, my video cut out. But what I was saying was, [09:31.780 --> 09:38.640] if a user were to visit this vulnerable post that contained this malicious HTML, they would [09:38.640 --> 09:43.440] receive this login page, think that their session had become invalidated or they just hadn't logged [09:43.440 --> 09:47.800] in yet, they would enter in their credentials, and then these would be sent off to the attacker [09:47.800 --> 09:54.480] controlled host that this form was pointing to, and then they'd be redirected to maybe the actual [09:54.480 --> 09:59.280] post or something like that. So, using this cross-site scripting vulnerability, an attacker [09:59.280 --> 10:06.260] could be able to basically trick users into entering into HTML forms or really anything. [10:06.600 --> 10:13.240] So, in that same vein, we have cross-site scripting phishing. So, this will be an actual video demo. [10:13.700 --> 10:17.340] I am going to have to talk over it as this video does not have any audio, [10:17.340 --> 10:20.300] so hopefully I'll be able to keep track and let you know what's happening. [10:21.320 --> 10:29.140] So, as we can see, there's a basic search.php web page that has a parameter called queue. So, if we [10:29.140 --> 10:34.040] enter test, for example, it's reflected back to the user. This indicates that there could [10:34.040 --> 10:39.240] potentially be reflected cross-site scripting in this page. So, as you can see, if we put alert1 [10:39.240 --> 10:46.400] as our query, it reflects it back to the user. So, in this case, what we could do is we could [10:46.400 --> 10:54.820] create a XSS payload that looks like an authentication pop-up. So, we're creating a [10:54.820 --> 11:01.740] new div that has a sort of a shaded background that has a pop-up window asking for their username [11:01.740 --> 11:08.460] and password and an error saying that there was an error and please log back in. So, if a user [11:08.460 --> 11:12.900] were to see this, they may think that their session is invalidated. Try and log back in. [11:12.900 --> 11:18.140] The creds would be sent to our attacker-controlled server, saved as creds.text, [11:18.140 --> 11:22.420] and then the user would be redirected to the page that they were expecting. In this case, [11:22.420 --> 11:30.300] search.php and queue equals test. So, we would send a link to a user like this with our malicious [11:30.300 --> 11:35.440] JavaScript payload as the query. And I actually need to clear this out because if you noticed [11:35.440 --> 11:42.320] briefly, the phishing page is only set to display once. So, if a user keeps clicking this link [11:42.320 --> 11:50.980] again and again, they won't be confused as to why the password authentication prompt keeps popping [11:50.980 --> 11:57.900] up again and again. So, if an attacker sent this external script to a user in the payload, [11:57.900 --> 12:01.960] they would be prompted with something like this. So, they may re-enter their username and password [12:01.960 --> 12:06.420] to try and get back into the system, get to the actual query that they wanted to see. [12:07.420 --> 12:11.300] Fairly long password, so they think they're secure. They're not going to say this password [12:11.300 --> 12:16.840] end. They're just redirected to your search queries test. But actually, on the attacker side, [12:16.840 --> 12:22.720] we see that... well, this is actually the actual server. So, a post was made to login.php. [12:22.720 --> 12:28.260] And if we check the attackers creds.txt, we see that the user admin logged in with super secret [12:28.260 --> 12:33.780] password 12345 and a bunch of symbols. So, we actually were able to trick the user into typing [12:33.780 --> 12:38.600] in their credentials into a fake login page just because we found a reflected cross-site [12:38.600 --> 12:51.330] scripting vulnerability. Another less common but still usually used for stuff like hacktivism [12:51.330 --> 12:56.330] or things like that is cross-site scripting defacement. This is very similar to the HTML [12:56.330 --> 13:05.230] injection, only the JavaScript file in question I mentioned here is Stallone.js. This is a [13:05.230 --> 13:11.430] fairly old JavaScript file that actually replaces your website content with a picture of Sylvester [13:11.430 --> 13:17.190] Stallone that says you have been Stalloned. It's been used in a few different scenarios, [13:17.190 --> 13:24.110] but I'm actually going to cover a case where this happened in real websites, a couple of them. [13:24.830 --> 13:29.610] Now, it doesn't have to be this Stallone.js. If you find a cross-site scripting vulnerability, [13:29.610 --> 13:37.230] you can deface a website to be whatever you want. So, you can rewrite CNN to show your own news [13:37.230 --> 13:44.090] instead of the news you expect to read. Things like that. So, anytime you would want to rewrite [13:44.090 --> 13:49.130] the content of a website, you are able to if you find one of these cross-site scripting vulnerabilities. [13:51.070 --> 13:56.930] So, here's the actual code from that Stallone.js. I know that this is a lot. I've also included a [13:56.930 --> 14:01.810] link to that .js file and you can google it and find it fairly easily. But, as I said, it [14:01.810 --> 14:06.590] sets some text to this page has been hacked, it loads a picture of Sylvester Stallone, [14:06.590 --> 14:12.430] and similar to that first payload I showed, it overwrites the content of the entire page with a [14:12.430 --> 14:20.360] giant div. So, like I said, back to the history lesson. So, there's actually a book called [14:20.690 --> 14:26.810] XSS Attacks Cross-Site Scripting Exploits and Defense that contained a reference to this [14:26.810 --> 14:31.190] Stallone.js file because it was talking about how cross-site scripting can be used to deface [14:31.190 --> 14:39.370] websites and things like that. Well, unfortunately, on Amazon.com, they were vulnerable [14:39.910 --> 14:47.550] to a stored cross-site scripting via book previews. So, sort of a high barrier for entry [14:47.550 --> 14:52.150] for attackers as you would have to publish a book with a cross-site scripting payload in it. But, [14:52.150 --> 14:57.850] if you're writing an XSS book and you manage to upload one of these malicious payloads, [14:57.850 --> 15:03.830] you were able to actually exploit cross-site scripting on any Amazon.com user that viewed [15:03.830 --> 15:09.670] your book preview. So, for a bit there, Amazon.com, and the example on the right is actually Maruta [15:10.470 --> 15:16.070] Sharapova's website that was also vulnerable. But, for a while, Amazon.com's preview of this book [15:16.070 --> 15:24.790] would just show the Stallone.js instead of the actual book preview. In addition to Amazon.com, [15:24.790 --> 15:28.670] note that this could have been used for things other than defacement. People could have tried [15:28.670 --> 15:34.650] to steal Amazon.com cookies. So, the picture on the left shows the Web Application Hacker's Handbook, [15:34.950 --> 15:40.810] a very common book for web pen testing, payloads, things like that. This had an example of a cookie [15:40.810 --> 15:47.430] stealing payload, alert-document.cookie. This also fired off on Amazon.com. As you can see, [15:47.430 --> 15:52.850] an Amazon cookie is being displayed just because a user is previewing the book. So, these attacks [15:52.850 --> 15:58.150] have occurred in the real world, and users could have been exploited by, technically, [15:58.150 --> 16:11.680] malicious book authors. So, not exactly cross-site scripting-based, but if an attacker is able to [16:11.680 --> 16:18.840] perform a man-in-the-middle attack, and this slide is based on a Black Hat USA talk that was [16:18.840 --> 16:23.080] given a few years back with that man-in-the-middle talk with a disgusting title, [16:23.760 --> 16:27.360] which the first link is for, I highly recommend you checking it out. [16:27.620 --> 16:35.640] But not exactly XSS-related, but I wanted to cover it as it is a similar style of attack. So, [16:35.640 --> 16:43.140] if a man-in-the-middle attack occurs, a user could arbitrarily rewrite the HTML of a page [16:43.140 --> 16:49.340] that their target is viewing. So, in this case, this guy overwrote a target's Facebook.com [16:49.340 --> 16:52.900] with a picture of himself and a prompt that says, will you go out with me? [16:52.900 --> 17:00.240] That would not be bypassed until the target clicked yes or no. So, not exactly XSS-related, [17:00.240 --> 17:06.280] but you're still able to inject HTML or JavaScript into a page that the user is viewing. [17:07.800 --> 17:12.920] So, in that same vein, while this is more relevant with actual cross-site scripting [17:12.920 --> 17:18.140] and HTML injection, I wanted to cover a sort of a scarier, worst-case scenario. [17:18.320 --> 17:24.960] So, if you were able to inject HTML, either via man-in-the-middle or cross-site scripting, [17:24.960 --> 17:29.520] into Internet Explorer, now this is not Edge, this is only Internet Explorer, [17:29.520 --> 17:36.510] you could inject a file URI to, say, an image to an attacker-controlled server. [17:36.880 --> 17:40.780] Now, what this would do is, if it's loaded in IE, it would actually send [17:41.160 --> 17:47.420] a UNC request for that images-slash-file.jpg. Now, for those of you that are familiar with [17:47.420 --> 17:55.000] Responder, this would actually send a net-ntlm response to this attacker-controlled server [17:55.000 --> 18:00.540] after it responded with a challenge. So, an attacker could actually use this XSS or HTML [18:00.540 --> 18:06.860] injection to get a net-ntlmn hash for your local or domain user that's currently logged [18:06.860 --> 18:12.340] or into that system that the browser is running under. So, just by finding this vulnerability, [18:12.340 --> 18:16.680] an attacker could have credentials for either a local machine or your entire domain, [18:16.680 --> 18:21.820] assuming that they're able to capture and crack these hashes. So, while it's easier with a [18:21.820 --> 18:27.060] man-in-the-middle attack, it is still possible with something like a cross-site scripting attack [18:27.060 --> 18:34.830] and Internet Explorer. So, back to another video demo, [18:34.830 --> 18:39.270] here I want to cover an example of password stealing using cross-site scripting. So, [18:39.270 --> 18:43.890] not phishing like the last one, but actually stealing saved credentials within a browser. [18:45.450 --> 18:55.330] So, as you can see, we have a basic login page with a username, a password, and a login button, [18:55.950 --> 18:59.530] as well as a prompt at the bottom that says your current language. [18:59.890 --> 19:03.810] So, since our very well-developed web application supports multiple languages, [19:03.810 --> 19:08.790] we can set our language to EN or SP and it will display at the bottom. It doesn't change the [19:08.790 --> 19:14.970] language since I'm not that great of a developer, but it's just for demo purposes. So, as expected, [19:14.970 --> 19:21.270] it reflects the query parameter into the page. So, if we put alert 1, it shows that this page [19:21.270 --> 19:26.290] is vulnerable to cross-site scripting. So, let's say our admin user had actually logged into this [19:26.290 --> 19:32.270] application. They're going to save their password because they don't want to have to remember that [19:32.270 --> 19:37.290] pretty secure password. It takes a lot of work. So, when they log in, they're redirected to a [19:37.290 --> 19:42.210] comments page. And when they go back to the login page, their credentials are obviously saved. [19:42.210 --> 19:48.250] So, nice and convenient. Nothing too scary since we haven't phished their credentials. [19:48.250 --> 19:52.370] Instead, what we can do is we can create a second body tag, which this will still work [19:52.370 --> 19:58.090] in most browsers, but is not technically valid HTML. And in this second body tag, [19:58.090 --> 20:04.070] we will call the steel creds method that we write that will create a new form with the [20:04.070 --> 20:11.010] password or the username and password fields with the same ID and name as the existing fields, [20:11.530 --> 20:18.110] make it invisible, and then set this username and password to be the values from the previously [20:18.110 --> 20:24.230] saved or entered username and password. Once it grabs those, it sends them in a get request to [20:24.230 --> 20:29.170] our attacker-controlled server, and the user is none the wiser that just because they saved their [20:29.170 --> 20:35.950] credentials in a login page, we were able to grab them. Now, note that this payload does require [20:35.950 --> 20:40.670] cross-site scripting on the login page. It won't work if there was a cross-site scripting [20:40.670 --> 20:48.850] vulnerability, say, in that comments page. So, we convert this to URL encoding just to make [20:48.850 --> 20:56.310] our lives a bit easier, and we send this to our target in the language parameter. [20:57.330 --> 21:01.050] So, as we can see, nothing happened. Their credentials are still saved. User is none the [21:01.050 --> 21:06.910] wiser. But on our attacker-controlled server, we actually get a get request for the username, [21:06.910 --> 21:14.430] admin, and that same and b-size password. And if we take a look at the HTML of this new page, [21:14.430 --> 21:21.350] our original form is there, as well as our second body tag with that steal creds method. [21:21.870 --> 21:27.250] And we see an error that is not valid HTML, like I said. But just because a user saved their [21:27.250 --> 21:34.210] credentials on a vulnerable login page, we were actually able to steal them with this [21:34.210 --> 21:45.230] cross-site scripting payload. So, again, I know this is very demo and example heavy. [21:45.230 --> 21:49.630] Please feel free to reach out to me for these slides or go back over everything. [21:52.120 --> 22:00.440] So, another example that is particularly useful on login pages, that's where I've used it most [22:00.440 --> 22:05.580] myself, but really anywhere that you might want a keylogger is a cross-site scripting keylogger. [22:05.580 --> 22:13.680] So, the top picture shows our JavaScript payload. But what it does is every time any key is pressed, [22:13.680 --> 22:20.500] it creates a new event handler that will send an XML HTTP request to our attacker-controlled server [22:20.500 --> 22:28.240] with a post data of whatever key was pressed. And if we take a look at our keylog.php file [22:28.240 --> 22:34.900] in the bottom left corner, we see that if there is post data, it will open the file data.txt and [22:34.900 --> 22:41.020] append whatever was in that post data. So, every time a user hits a key on a page after loading [22:41.020 --> 22:47.300] this malicious JavaScript file, the attacker will get their keystrokes. So, in the bottom right, [22:47.300 --> 22:53.300] we see that they enter pentest as their name in the stored cross-site scripting vulnerability [22:53.300 --> 22:59.500] page. And in our data.txt on the attacker-controlled server, we got all of those keystrokes back. [23:00.200 --> 23:03.660] So, obviously on a login page, this would be great because you could grab their username [23:03.660 --> 23:08.520] and password without them having saved it. But really anywhere where you might want to obtain [23:09.720 --> 23:13.680] a user's keystrokes, so if they're entering credit card information, even just stuff like [23:13.680 --> 23:20.080] addresses or other PII, this would be a useful payload for a malicious attacker to use. [23:23.680 --> 23:31.240] So, another thing that you could do with a cross-site scripting payload is steal sensitive [23:31.240 --> 23:37.140] information. And again, I know that there's a ton of code on this page, but what this does is [23:37.140 --> 23:43.880] sends a POST request to the attacker-controlled server containing all of the source code from [23:43.880 --> 23:52.140] the application. So, say you find a cross-site scripting vulnerability in a sensitive page, [23:52.140 --> 23:59.060] so maybe an administrative console, banking application, password manager, [23:59.060 --> 24:04.840] or really any sort of private pages that you want to see someone else's content. You could use the [24:04.840 --> 24:09.160] code on the left to grab the source code, or the example on the right to grab a screenshot of the [24:09.160 --> 24:14.900] page, and you send that off to your attacker-controlled server. So, maybe you want to, [24:14.900 --> 24:20.100] if you find a cross-site scripting vulnerability in your bank, if you were to target someone with [24:20.240 --> 24:25.720] a payload, you could maybe see their bank account number, their balances, things like that, as well [24:25.720 --> 24:31.200] as maybe admin settings on a firewall or router, things like that. So, if there's sensitive [24:31.200 --> 24:36.960] information on an application that stealing would be valuable, this is another use for a [24:36.960 --> 24:48.050] cross-site scripting payload. So, a really fun cross-site scripting payload use that I have done [24:48.050 --> 24:53.770] personally quite a fair bit is defeating CSERV. So, if you're not familiar with what CSERV is, I'm just [24:53.770 --> 24:59.850] going to briefly cover it. It's cross-site request forgery. At its core, it's sending a request from [24:59.850 --> 25:07.130] Site A to Site B. So, a very common example would be if Amazon was vulnerable to CSERV, [25:07.130 --> 25:14.830] if a user visited my malicious website while they had an Amazon session still active, my malicious [25:14.830 --> 25:19.650] website could send a request to Amazon that would make them purchase an item and ship it to me, for [25:19.650 --> 25:25.530] an example. Now, Amazon is not vulnerable to CSERV, so this attack isn't valid, but that's just a [25:25.530 --> 25:31.850] common example of it. Now, there are CSERV protections like tokens or nonces, things like that, that [25:31.850 --> 25:38.450] are an ideally unique value on every form that prevents an attacker from sending these malicious [25:38.450 --> 25:44.590] requests to a different server. Now, a cross-site scripting vulnerability, since it can read the HTML [25:44.590 --> 25:51.270] of a page, the payload could read the HTML of your page, grab that CSERV token, and then use that [25:51.270 --> 25:59.790] to send your malicious CSERV request. So, a very simple read body looks for a CSERV token parameter, [25:59.790 --> 26:07.070] gets it, and returns it to a different method. So, this is an example that I got to use [26:07.070 --> 26:10.630] in a real engagement in which there was a reflected cross-site scripting vulnerability [26:11.190 --> 26:16.750] that I used to grab a CSERV token and then actually exploit a stored cross-site scripting vulnerability. [26:17.950 --> 26:23.230] So, as you can see, we have a very similar login page to all those other examples I've shown. [26:23.450 --> 26:29.750] Not the most beautiful page. Our search page that reflects back the kube parameter, as well as on [26:29.750 --> 26:36.110] an authenticated comment section. So, we want to be able to put our stored cross-site [26:36.110 --> 26:42.790] scripting payload into that comment section as an authenticated user. So, when someone logs in [26:42.790 --> 26:46.730] under their admin account, they're able to see the comment section of the application, as you can see. [26:48.330 --> 26:55.850] So, the search.php is unauthenticated and vulnerable to a reflected cross-site [26:55.850 --> 27:01.710] scripting attack. So, as we can see, if we enter a test, it shows test again. If we test for cross-site [27:01.710 --> 27:07.350] scripting with alert1, we will get our pop-up and confirm that we have pre-authentication [27:07.350 --> 27:14.610] reflected cross-site scripting. So, what we can do is we can use a payload similar to [27:15.250 --> 27:20.070] this one. And I know it's quite long. I'm going to share it, as well as give a link to it. But [27:20.910 --> 27:24.710] what... or actually, no, sorry, this is the comment section that shows you have to be authenticated. [27:24.710 --> 27:33.110] And it uses a SHA-256 hash of the session, salted with the very secret password, to create a CSERF [27:33.110 --> 27:38.750] token for the comment section. So, our developer secured their application. The comment section [27:38.750 --> 27:44.590] is not vulnerable to cross-site request forgery. We should be good. Unfortunately, since we have [27:44.590 --> 27:50.490] that reflected cross-site scripting payload on the search page, we can use that to grab this [27:50.490 --> 27:59.210] very secure-looking value for that CSERF token. So, as we see, if we post test, test, [27:59.210 --> 28:07.220] it works fine since we're authenticated and we had the CSERF token. So, what we can do next is [28:07.780 --> 28:13.380] use the reflected cross-site scripting vulnerability to grab that CSERF token, [28:13.380 --> 28:18.680] use that CSERF token to send a POST request to the comment section, and then put error payload [28:18.680 --> 28:27.930] on that page. So, that top read body method looks just like the one I showed a few slides ago. [28:28.270 --> 28:34.190] Grabs that CSERF token from the body of our target page and returns it to a different method [28:34.190 --> 28:42.890] that we want to use it for. And I apologize if some of the audio is slightly off of these videos. [28:42.890 --> 28:47.590] As I said, I recorded these videos a while ago and was not able to keep the audio with them. [28:49.670 --> 28:55.370] So, once we get this CSERF token... well, first, we have to send... first, this payload will send [28:55.510 --> 29:01.130] a GET request for the comment section. So, the authenticated user will send back the comments [29:02.010 --> 29:07.170] page, then we'll grab the CSERF token, and then we will use that in our POST request. [29:25.860 --> 29:30.980] So, yeah, sorry about that. I did not quite plan the audio right on this one and the screen [29:30.980 --> 29:35.900] capture took a little too long, but I will share this code. It is going to be a lot easier for me [29:35.900 --> 29:40.520] to share it than talking over it line by line as I originally planned to do. But, [29:40.520 --> 29:45.160] once we have this CSERF token... I'm not able to skip, unfortunately. [29:53.020 --> 29:58.300] Okay, so, now that we're done looking over that exploit.js file, [29:58.300 --> 30:04.980] once we load that externally into this search.php page, which is what I'm doing now, [30:05.560 --> 30:12.400] the user will not see the requests in the background, but we're actually able to [30:12.400 --> 30:17.360] post to the comment section as that user now. So, if we refresh this comments.php page, [30:17.360 --> 30:23.940] we actually see a stored cross-site scripting payload of alert1 written by CSERFTest, which [30:23.940 --> 30:30.100] was what that payload does that I was showing before. So, if we quickly search for CSERFTest, [30:30.100 --> 30:36.100] as we see, their comment was scriptalert1. And now we upgraded from our slightly less [30:36.100 --> 30:42.160] severe reflected cross-site scripting payload to a more severe stored cross-site scripting payload. [30:43.240 --> 30:49.460] So, as you can see, it sent a POST request with the name of the comment and the CSERF token. [30:49.660 --> 30:53.620] Now, I just want to briefly touch on the difference between reflected and stored [30:53.620 --> 30:59.160] cross-site scripting. At its core, reflected cross-site scripting is usually going to require [30:59.160 --> 31:04.660] some sort of malicious link or something of that nature that you send to your specific targets, [31:04.660 --> 31:10.080] and they're going to need to click it. So, not quite as severe, requires some user interaction [31:10.080 --> 31:15.120] usually, stuff like that. Now, stored cross-site scripting is like what we saw in that comment [31:15.120 --> 31:21.500] section. So, our cross-site scripting payload will now execute on any user that goes to that [31:21.500 --> 31:29.360] comments.php page. So, it's more persistent. It targets more users, and it basically lasts [31:29.360 --> 31:33.440] for more than... and it requires zero user interaction outside of them visiting our [31:34.220 --> 31:46.570] vulnerable pages. So, in addition to generic payloads, you can also use cross-site scripting [31:46.570 --> 31:53.310] attacks for application-specific payloads. So, this one is a quick example of the [31:53.310 --> 31:59.490] damVulnerableWebApp using cross-site scripting to sign the guestbook under a different user. [31:59.490 --> 32:05.790] So, a similar idea to the Csurf cross-site scripting example from a previous application, [32:05.790 --> 32:11.390] but this can be done... anything that a user could do within your application, [32:11.390 --> 32:16.970] an attacker could do if they found a cross-site scripting vulnerability. So, for instance, [32:16.970 --> 32:21.930] changing your wireless password. If an attacker found a cross-site scripting vulnerability in [32:21.930 --> 32:27.030] your router firmware, they can use that to change your WPA passphrase. Things like that. [32:29.570 --> 32:37.310] So, this is a great repository from HackLuke, but it contains a number of application-specific [32:37.310 --> 32:42.450] payloads. As you can see, there's a Drupal one, MyBulletinBoard, and a few for WordPress. [32:42.650 --> 32:49.550] So, if you are able to find cross-site scripting in a WordPress post or a WordPress plugin, [32:49.550 --> 32:54.890] you could do something like send a malicious cross-site scripting payload to an [32:54.890 --> 33:00.950] administrative user and use that payload to add a new user into the WordPress application. [33:01.890 --> 33:07.910] And there's a great blog by TrustedSec about weaponizing XSS in this manner that goes [33:07.910 --> 33:13.270] through all the steps they would use to create the new user, grab any WordPress-specific [33:13.270 --> 33:19.270] things like that. And the second link, for those of you not familiar with WordPress, [33:19.270 --> 33:24.390] is a list of all of the CVEs that have been found in the past. While I personally love WordPress, [33:24.390 --> 33:30.950] it has been known to be vulnerable in the past, especially the plugins that people use. [33:30.950 --> 33:38.590] So, this is not an uncommon attack vector. One thing I do want to note is if a user is able to [33:38.590 --> 33:43.090] exploit a cross-site scripting vulnerability and create a new user, [33:43.090 --> 33:49.350] if that user has high enough privileges, they could then use that to privilege escalate even [33:49.350 --> 33:56.750] one more step to a system-level shell. Because WordPress posts contain PHP, if you want, [33:56.750 --> 34:01.150] so they could write a PHP command shell, use that to escalate to a system-level shell, [34:01.150 --> 34:07.030] and now they turned a potentially reflected cross-site scripting vulnerability into a shell [34:07.030 --> 34:19.820] access on your web server. A very common framework when talking about cross-site scripting, and one [34:19.820 --> 34:25.980] that I at least wanted to touch on a little bit, is BEEF, the Browser Exploitation Framework. [34:25.980 --> 34:34.820] This is a cross-site scripting framework of payloads and exploits. It's an open-source [34:34.820 --> 34:39.640] piece of software designed for penetration testers to exploit browser-based vulnerabilities. [34:40.360 --> 34:47.880] So, BEEF can be used to effectively have a botnet of browsers that you can control and monitor [34:47.880 --> 34:54.940] in the top left image. You're able to execute any JavaScript on these client-side devices, so [34:54.940 --> 35:01.800] the middle image shows grabbing the IP of the host that you've hit with your exploit. Any browser [35:01.800 --> 35:08.080] information, so the bottom left shows what is enabled, what's installed, any user agents, window [35:08.080 --> 35:14.640] sizes, things like that. So, effectively any HTML or JavaScript that could have been executed by [35:14.640 --> 35:23.400] this web browser could be executed by BEEF on the back end. Now, the most value I've found from BEEF [35:23.400 --> 35:31.280] is actually upgrading from a browser-based exploit to a system-level exploit. So, there's over 500 [35:31.280 --> 35:36.560] Metasploit modules, so if a user is running an old or an out-of-date browser, you could just [35:36.560 --> 35:47.560] use BEEF to exploit a Metasploit payload and escalate to a reverse shell from that user, [35:47.560 --> 35:52.740] for example. So, here's a bunch of Firefox examples, but there's a ton in BEEF and it's great for [35:53.460 --> 35:56.620] escalating from cross-site scripting to command access. [35:58.100 --> 36:01.940] As I said, there's a ton of payloads. I'm not going to cover them all. [36:01.940 --> 36:08.400] Here's a few examples. Note that anything BEEF can do, you could also do with your own cross-site [36:08.400 --> 36:13.600] scripting payloads if you wanted to be a little quieter or learn JavaScript or just get a more [36:13.600 --> 36:18.800] controlled feel for it. That said, it does make your life a lot easier as it's just a matter of [36:18.800 --> 36:25.040] right-clicking the browser and then clicking on Keylogger. Stuff like that. But as I said, [36:25.160 --> 36:31.200] a ton of awesome payloads. I highly recommend you at least check it out. It is going to be [36:31.200 --> 36:36.020] for if you find cross-site scripting during your penetration tests, things like that, [36:36.020 --> 36:44.200] to quickly exploit it as opposed to needing to weaponize it for bug bounties, things like that. [36:44.380 --> 36:51.000] That said, if you can load any external .js file, you could load a BEEF hook and get all of this [36:51.520 --> 36:58.440] quickly and easily. So, I briefly want to touch on blind cross-site scripting, [36:58.440 --> 37:04.760] mention what it is, and include a few references. It is easily a topic that could be at least one [37:04.760 --> 37:12.080] talk on its own. But at its core, blind cross-site scripting is the cross-site scripting JavaScript [37:12.080 --> 37:19.120] script payload executes somewhere that you cannot see it, hence the name blind. So, for example, [37:19.120 --> 37:25.940] if a login page was vulnerable to cross-site scripting but only administrative users could [37:25.940 --> 37:34.300] see your payload, or if it was on a web forum that you didn't have access to, maybe an administrative [37:34.300 --> 37:41.560] panel has logs, a chat application that's different for the help desk technician than it is for the [37:41.560 --> 37:47.460] end user, firewall logs that you never get to see as an attacker but that execute malicious [37:47.460 --> 37:53.660] JavaScript payloads, things like that. So, testing for blind cross-site scripting requires a bit more [37:53.660 --> 38:00.140] work as you are going to not be able to quickly test it easily and see the results in your browser. [38:00.160 --> 38:05.000] I highly recommend checking out stuff like XSS Hunter or Sleepy Puppy from Netflix. These are [38:05.000 --> 38:09.600] really fun tools for finding blind cross-site scripting and especially for your bug bounty [38:09.600 --> 38:14.480] hunters. These are going to be vulnerabilities that aren't going to be found right away, especially by [38:14.480 --> 38:21.140] tools like Burp or things like that. So, I highly recommend taking a look at blind XSS, learning [38:21.140 --> 38:26.360] what it is, and trying to find it, potentially during your engagements, but especially during [38:26.360 --> 38:37.010] stuff like bug bounty hunting and things of that nature. So, now that I've covered a ton [38:37.010 --> 38:40.730] of different payloads, let's take a quick trip down memory lane for some