I have no idea what time this will be played, but thanks for coming to my virtual talk for this edition of DEF CON SAFE MODE, and I figured a great way to start it off, since this is technically my first DEF CON talk, would be to take a shot. So we've got some 1712 bourbon, so let's get it started. Don't fuck it up! So, other than that, this is normally where I try and get some crowd engagement in the talk. So, whenever you're watching this, and I will hopefully be in the Discord at least during the talk, if not around the same time, let me know if you are aware of XSS or if you're not. Hopefully most of you are, with this being the Red Team Village, but for those of you that aren't, hopefully you'll at least learn a little bit about cross-site scripting, as well as sort of why it's more of a severe attack than you may initially realize. So, I realized that I need to move this webcam out of the way. Let's try the top right corner. So, I'm Ray Doyle. You can find me on Twitter, at DoylerSec, or my blog, Doyler.net. I'm currently a Senior Staff Adversarial Engineer at Avalara. We're a tax, software, and compliance company. We're always hiring, but not necessarily for security, so definitely reach out to me if you're looking for work. I love CTFs. I've actually been on two DEF CON Black Badge winning CTF teams, for the Wireless CTF, as well as the IoT CTF. I love them, if you want to talk CTFs, as well as being a member of Team Eversec, who actually runs some CTFs, mostly in North Carolina-based conferences, but a few other regional ones. So, definitely reach out to me about conferences or CTFs, things like that. And I also love collecting certifications. I got my OSCE last year, my OSCP a few years back. I'm always looking for new ideas for certs to take or training, so definitely let me know if you're aware of any. And also, if you couldn't tell from the Avalara orange on the slides and the last one, clearly it's our company color. I figured I might as well go with the theme. So, a few caveats before we get into this. I'm not an expert in cross-site scripting, I'm not a bug bounty hunter, I'm definitely not a JavaScript expert, but I am a penetration tester who has used cross-site scripting in the past, so hopefully I'll be able to at least teach you a few tricks. This is going to be a very example-heavy and focused talk, so definitely feel free to go back over the slides, re-watch the videos. I'm going to include a lot of links in the presenter-slash-comments section of each slide, so if I don't post them soon enough, reach out to me on Twitter and I'll get you a copy sooner rather than later. It's definitely going to be a lot to digest. Like I said before, I don't participate in bug bounties, but some of these payloads should help you to demonstrate the severity of the vulnerabilities you find and maybe get them increased to a P1 or something like that. A lot of this information is going to be from my personal blog. I've already used a lot of these exploits and payloads before, so I will include links to that to a little more in-depth post as well as some more screenshots and things like that. I'm going to cover a ton of information, so please feel free to ask questions afterwards, before, or on Twitter at any point. And I'm not going to cover really how to find cross-site scripting or what really protects against it, so this is really going to be heavily focused on exploiting it once you've found it. Also, another caveat, this is obviously a COVID recording of a presentation that won't be given live, so any technical issues I apologize for, I'm going to do my best. We'll see how it goes. So, I know that this isn't live, but definitely feel free to use the weaponized XSS hashtag on Twitter. I'll definitely be checking it during the conference as well as any time afterwards. If you want to talk about my technical issues, if you want to share some really cool payloads with the community, really anything, just to have some sort of viewer interaction during this weird virtual conference. So, here's a quick introduction to cross-site scripting. This is from OWASP directly. I'm not going to just re-read it back to you, but the gist of it is that cross-site scripting is an injection-based attack in which an attacker is able to inject usually JavaScript, but can also sort of cover HTML as well as CSS. It's frequently used for loading malicious scripts and executing them on the target's client-side browser. So, these aren't going to be attacking your servers as much as the people who are connecting to your websites, things like that. So, the most basic example of going beyond Alert 1 is Alert 2. Now, while this is fairly tongue-in-cheek, I do want to quickly point out the fact that there are going to be systems, and I may move this window from time to time, I apologize in advance. So, there may be systems that are alerting or filtering for very specific payloads, and something like Alert 2 could even bypass a deny list that was protecting against Alert 1, things like that. So, when you're working on these weaponized payloads, be sure to try different variations or different ways to get them into these systems. So, the first example I wanted to cover is loading external scripts. This is the most basic example, but it's fairly important to try and do. So, anywhere in which you were able to inject that script Alert 1, generally speaking, you could also load an external JavaScript file. So, in this case, I'm loading doiler.net slash evil.js. Now, what this allows you to do is have bigger payloads, not worry as much about things like encoding, stuff like that. So, if at all possible, you should definitely try and go with an external-based payload instead of keeping it inline if you're able to. So, another example of this is using staged cross-site scripting. So, if you find yourself injecting into an already existing script tag, you obviously cannot set the source of it. Or, if you find yourself in an HTML event handler, you aren't going to be able to load an external JavaScript file. In this case, what you could do is have inline JavaScript that will create a new script element inside of the document, then set the source of that script element to be your external JavaScript payload. So, for this quick example, it's bit.ly slash example. And this is a payload that was created by someone. I've included a link to the GitHub in the comments. Definitely check it out. It's come in really handy when I've been stuck in sort of an HTML event handler, especially. If you are in an existing script tag, you could write longer JavaScript, but you may run across payload length limits, things of that nature. So, the most common payload that you'll see or hear of when discussing or attacking using cross-site scripting is going to be cookie stealing. So, in this example, our XSS payload writes a new image tag to the document, only this image tag has a cookie parameter that sends the document.cookie from your local application to the attacker-controlled server. So, in this case, any cookies we had on our target web application would have been sent to doload.net through the HTML get parameters. Now, there are things that are going to protect against this, like HTTP-only cookies, things like that. But if you are able to successfully grab one of these cookies, you could use it for session hijacking, any existing sessions, and basically logging in as that user to the application without knowing their credentials. So, definitely keep this one in mind. This is the one I've used most often in my career, and it's super simple and straightforward to do. So, another... a different way that XSS injection, or technically any injection, could be used is to rewrite the HTML of the page. So, the example on the left sort of shows this, but it creates a new div that takes up 100% of the page, puts it on top, and allows you to write arbitrary HTML into that div. What that means is you basically get to overwrite the content that your target sees for an entire website. So, that image on the right looks like a standard Drupal login page, but it's actually a cross-site scripting vulnerability that was found in a Drupal comments section, and an attacker used that post to rewrite the HTML of the page to make it look like an access denied or an authentication page. Sorry about that, my video cut out. But what I was saying was, if a user were to visit this vulnerable post that contained this malicious HTML, they would receive this login page, think that their session had become invalidated or they just hadn't logged in yet, they would enter in their credentials, and then these would be sent off to the attacker controlled host that this form was pointing to, and then they'd be redirected to maybe the actual post or something like that. So, using this cross-site scripting vulnerability, an attacker could be able to basically trick users into entering into HTML forms or really anything. So, in that same vein, we have cross-site scripting phishing. So, this will be an actual video demo. I am going to have to talk over it as this video does not have any audio, so hopefully I'll be able to keep track and let you know what's happening. So, as we can see, there's a basic search.php web page that has a parameter called queue. So, if we enter test, for example, it's reflected back to the user. This indicates that there could potentially be reflected cross-site scripting in this page. So, as you can see, if we put alert1 as our query, it reflects it back to the user. So, in this case, what we could do is we could create a XSS payload that looks like an authentication pop-up. So, we're creating a new div that has a sort of a shaded background that has a pop-up window asking for their username and password and an error saying that there was an error and please log back in. So, if a user were to see this, they may think that their session is invalidated. Try and log back in. The creds would be sent to our attacker-controlled server, saved as creds.text, and then the user would be redirected to the page that they were expecting. In this case, search.php and queue equals test. So, we would send a link to a user like this with our malicious JavaScript payload as the query. And I actually need to clear this out because if you noticed briefly, the phishing page is only set to display once. So, if a user keeps clicking this link again and again, they won't be confused as to why the password authentication prompt keeps popping up again and again. So, if an attacker sent this external script to a user in the payload, they would be prompted with something like this. So, they may re-enter their username and password to try and get back into the system, get to the actual query that they wanted to see. Fairly long password, so they think they're secure. They're not going to say this password end. They're just redirected to your search queries test. But actually, on the attacker side, we see that... well, this is actually the actual server. So, a post was made to login.php. And if we check the attackers creds.txt, we see that the user admin logged in with super secret password 12345 and a bunch of symbols. So, we actually were able to trick the user into typing in their credentials into a fake login page just because we found a reflected cross-site scripting vulnerability. Another less common but still usually used for stuff like hacktivism or things like that is cross-site scripting defacement. This is very similar to the HTML injection, only the JavaScript file in question I mentioned here is Stallone.js. This is a fairly old JavaScript file that actually replaces your website content with a picture of Sylvester Stallone that says you have been Stalloned. It's been used in a few different scenarios, but I'm actually going to cover a case where this happened in real websites, a couple of them. Now, it doesn't have to be this Stallone.js. If you find a cross-site scripting vulnerability, you can deface a website to be whatever you want. So, you can rewrite CNN to show your own news instead of the news you expect to read. Things like that. So, anytime you would want to rewrite the content of a website, you are able to if you find one of these cross-site scripting vulnerabilities. So, here's the actual code from that Stallone.js. I know that this is a lot. I've also included a link to that .js file and you can google it and find it fairly easily. But, as I said, it sets some text to this page has been hacked, it loads a picture of Sylvester Stallone, and similar to that first payload I showed, it overwrites the content of the entire page with a giant div. So, like I said, back to the history lesson. So, there's actually a book called XSS Attacks Cross-Site Scripting Exploits and Defense that contained a reference to this Stallone.js file because it was talking about how cross-site scripting can be used to deface websites and things like that. Well, unfortunately, on Amazon.com, they were vulnerable to a stored cross-site scripting via book previews. So, sort of a high barrier for entry for attackers as you would have to publish a book with a cross-site scripting payload in it. But, if you're writing an XSS book and you manage to upload one of these malicious payloads, you were able to actually exploit cross-site scripting on any Amazon.com user that viewed your book preview. So, for a bit there, Amazon.com, and the example on the right is actually Maruta Sharapova's website that was also vulnerable. But, for a while, Amazon.com's preview of this book would just show the Stallone.js instead of the actual book preview. In addition to Amazon.com, note that this could have been used for things other than defacement. People could have tried to steal Amazon.com cookies. So, the picture on the left shows the Web Application Hacker's Handbook, a very common book for web pen testing, payloads, things like that. This had an example of a cookie stealing payload, alert-document.cookie. This also fired off on Amazon.com. As you can see, an Amazon cookie is being displayed just because a user is previewing the book. So, these attacks have occurred in the real world, and users could have been exploited by, technically, malicious book authors. So, not exactly cross-site scripting-based, but if an attacker is able to perform a man-in-the-middle attack, and this slide is based on a Black Hat USA talk that was given a few years back with that man-in-the-middle talk with a disgusting title, which the first link is for, I highly recommend you checking it out. But not exactly XSS-related, but I wanted to cover it as it is a similar style of attack. So, if a man-in-the-middle attack occurs, a user could arbitrarily rewrite the HTML of a page that their target is viewing. So, in this case, this guy overwrote a target's Facebook.com with a picture of himself and a prompt that says, will you go out with me? That would not be bypassed until the target clicked yes or no. So, not exactly XSS-related, but you're still able to inject HTML or JavaScript into a page that the user is viewing. So, in that same vein, while this is more relevant with actual cross-site scripting and HTML injection, I wanted to cover a sort of a scarier, worst-case scenario. So, if you were able to inject HTML, either via man-in-the-middle or cross-site scripting, into Internet Explorer, now this is not Edge, this is only Internet Explorer, you could inject a file URI to, say, an image to an attacker-controlled server. Now, what this would do is, if it's loaded in IE, it would actually send a UNC request for that images-slash-file.jpg. Now, for those of you that are familiar with Responder, this would actually send a net-ntlm response to this attacker-controlled server after it responded with a challenge. So, an attacker could actually use this XSS or HTML injection to get a net-ntlmn hash for your local or domain user that's currently logged or into that system that the browser is running under. So, just by finding this vulnerability, an attacker could have credentials for either a local machine or your entire domain, assuming that they're able to capture and crack these hashes. So, while it's easier with a man-in-the-middle attack, it is still possible with something like a cross-site scripting attack and Internet Explorer. So, back to another video demo, here I want to cover an example of password stealing using cross-site scripting. So, not phishing like the last one, but actually stealing saved credentials within a browser. So, as you can see, we have a basic login page with a username, a password, and a login button, as well as a prompt at the bottom that says your current language. So, since our very well-developed web application supports multiple languages, we can set our language to EN or SP and it will display at the bottom. It doesn't change the language since I'm not that great of a developer, but it's just for demo purposes. So, as expected, it reflects the query parameter into the page. So, if we put alert 1, it shows that this page is vulnerable to cross-site scripting. So, let's say our admin user had actually logged into this application. They're going to save their password because they don't want to have to remember that pretty secure password. It takes a lot of work. So, when they log in, they're redirected to a comments page. And when they go back to the login page, their credentials are obviously saved. So, nice and convenient. Nothing too scary since we haven't phished their credentials. Instead, what we can do is we can create a second body tag, which this will still work in most browsers, but is not technically valid HTML. And in this second body tag, we will call the steel creds method that we write that will create a new form with the password or the username and password fields with the same ID and name as the existing fields, make it invisible, and then set this username and password to be the values from the previously saved or entered username and password. Once it grabs those, it sends them in a get request to our attacker-controlled server, and the user is none the wiser that just because they saved their credentials in a login page, we were able to grab them. Now, note that this payload does require cross-site scripting on the login page. It won't work if there was a cross-site scripting vulnerability, say, in that comments page. So, we convert this to URL encoding just to make our lives a bit easier, and we send this to our target in the language parameter. So, as we can see, nothing happened. Their credentials are still saved. User is none the wiser. But on our attacker-controlled server, we actually get a get request for the username, admin, and that same and b-size password. And if we take a look at the HTML of this new page, our original form is there, as well as our second body tag with that steal creds method. And we see an error that is not valid HTML, like I said. But just because a user saved their credentials on a vulnerable login page, we were actually able to steal them with this cross-site scripting payload. So, again, I know this is very demo and example heavy. Please feel free to reach out to me for these slides or go back over everything. So, another example that is particularly useful on login pages, that's where I've used it most myself, but really anywhere that you might want a keylogger is a cross-site scripting keylogger. So, the top picture shows our JavaScript payload. But what it does is every time any key is pressed, it creates a new event handler that will send an XML HTTP request to our attacker-controlled server with a post data of whatever key was pressed. And if we take a look at our keylog.php file in the bottom left corner, we see that if there is post data, it will open the file data.txt and append whatever was in that post data. So, every time a user hits a key on a page after loading this malicious JavaScript file, the attacker will get their keystrokes. So, in the bottom right, we see that they enter pentest as their name in the stored cross-site scripting vulnerability page. And in our data.txt on the attacker-controlled server, we got all of those keystrokes back. So, obviously on a login page, this would be great because you could grab their username and password without them having saved it. But really anywhere where you might want to obtain a user's keystrokes, so if they're entering credit card information, even just stuff like addresses or other PII, this would be a useful payload for a malicious attacker to use. So, another thing that you could do with a cross-site scripting payload is steal sensitive information. And again, I know that there's a ton of code on this page, but what this does is sends a POST request to the attacker-controlled server containing all of the source code from the application. So, say you find a cross-site scripting vulnerability in a sensitive page, so maybe an administrative console, banking application, password manager, or really any sort of private pages that you want to see someone else's content. You could use the code on the left to grab the source code, or the example on the right to grab a screenshot of the page, and you send that off to your attacker-controlled server. So, maybe you want to, if you find a cross-site scripting vulnerability in your bank, if you were to target someone with a payload, you could maybe see their bank account number, their balances, things like that, as well as maybe admin settings on a firewall or router, things like that. So, if there's sensitive information on an application that stealing would be valuable, this is another use for a cross-site scripting payload. So, a really fun cross-site scripting payload use that I have done personally quite a fair bit is defeating CSERV. So, if you're not familiar with what CSERV is, I'm just going to briefly cover it. It's cross-site request forgery. At its core, it's sending a request from Site A to Site B. So, a very common example would be if Amazon was vulnerable to CSERV, if a user visited my malicious website while they had an Amazon session still active, my malicious website could send a request to Amazon that would make them purchase an item and ship it to me, for an example. Now, Amazon is not vulnerable to CSERV, so this attack isn't valid, but that's just a common example of it. Now, there are CSERV protections like tokens or nonces, things like that, that are an ideally unique value on every form that prevents an attacker from sending these malicious requests to a different server. Now, a cross-site scripting vulnerability, since it can read the HTML of a page, the payload could read the HTML of your page, grab that CSERV token, and then use that to send your malicious CSERV request. So, a very simple read body looks for a CSERV token parameter, gets it, and returns it to a different method. So, this is an example that I got to use in a real engagement in which there was a reflected cross-site scripting vulnerability that I used to grab a CSERV token and then actually exploit a stored cross-site scripting vulnerability. So, as you can see, we have a very similar login page to all those other examples I've shown. Not the most beautiful page. Our search page that reflects back the kube parameter, as well as on an authenticated comment section. So, we want to be able to put our stored cross-site scripting payload into that comment section as an authenticated user. So, when someone logs in under their admin account, they're able to see the comment section of the application, as you can see. So, the search.php is unauthenticated and vulnerable to a reflected cross-site scripting attack. So, as we can see, if we enter a test, it shows test again. If we test for cross-site scripting with alert1, we will get our pop-up and confirm that we have pre-authentication reflected cross-site scripting. So, what we can do is we can use a payload similar to this one. And I know it's quite long. I'm going to share it, as well as give a link to it. But what... or actually, no, sorry, this is the comment section that shows you have to be authenticated. And it uses a SHA-256 hash of the session, salted with the very secret password, to create a CSERF token for the comment section. So, our developer secured their application. The comment section is not vulnerable to cross-site request forgery. We should be good. Unfortunately, since we have that reflected cross-site scripting payload on the search page, we can use that to grab this very secure-looking value for that CSERF token. So, as we see, if we post test, test, it works fine since we're authenticated and we had the CSERF token. So, what we can do next is use the reflected cross-site scripting vulnerability to grab that CSERF token, use that CSERF token to send a POST request to the comment section, and then put error payload on that page. So, that top read body method looks just like the one I showed a few slides ago. Grabs that CSERF token from the body of our target page and returns it to a different method that we want to use it for. And I apologize if some of the audio is slightly off of these videos. As I said, I recorded these videos a while ago and was not able to keep the audio with them. So, once we get this CSERF token... well, first, we have to send... first, this payload will send a GET request for the comment section. So, the authenticated user will send back the comments page, then we'll grab the CSERF token, and then we will use that in our POST request. So, yeah, sorry about that. I did not quite plan the audio right on this one and the screen capture took a little too long, but I will share this code. It is going to be a lot easier for me to share it than talking over it line by line as I originally planned to do. But, once we have this CSERF token... I'm not able to skip, unfortunately. Okay, so, now that we're done looking over that exploit.js file, once we load that externally into this search.php page, which is what I'm doing now, the user will not see the requests in the background, but we're actually able to post to the comment section as that user now. So, if we refresh this comments.php page, we actually see a stored cross-site scripting payload of alert1 written by CSERFTest, which was what that payload does that I was showing before. So, if we quickly search for CSERFTest, as we see, their comment was scriptalert1. And now we upgraded from our slightly less severe reflected cross-site scripting payload to a more severe stored cross-site scripting payload. So, as you can see, it sent a POST request with the name of the comment and the CSERF token. Now, I just want to briefly touch on the difference between reflected and stored cross-site scripting. At its core, reflected cross-site scripting is usually going to require some sort of malicious link or something of that nature that you send to your specific targets, and they're going to need to click it. So, not quite as severe, requires some user interaction usually, stuff like that. Now, stored cross-site scripting is like what we saw in that comment section. So, our cross-site scripting payload will now execute on any user that goes to that comments.php page. So, it's more persistent. It targets more users, and it basically lasts for more than... and it requires zero user interaction outside of them visiting our vulnerable pages. So, in addition to generic payloads, you can also use cross-site scripting attacks for application-specific payloads. So, this one is a quick example of the damVulnerableWebApp using cross-site scripting to sign the guestbook under a different user. So, a similar idea to the Csurf cross-site scripting example from a previous application, but this can be done... anything that a user could do within your application, an attacker could do if they found a cross-site scripting vulnerability. So, for instance, changing your wireless password. If an attacker found a cross-site scripting vulnerability in your router firmware, they can use that to change your WPA passphrase. Things like that. So, this is a great repository from HackLuke, but it contains a number of application-specific payloads. As you can see, there's a Drupal one, MyBulletinBoard, and a few for WordPress. So, if you are able to find cross-site scripting in a WordPress post or a WordPress plugin, you could do something like send a malicious cross-site scripting payload to an administrative user and use that payload to add a new user into the WordPress application. And there's a great blog by TrustedSec about weaponizing XSS in this manner that goes through all the steps they would use to create the new user, grab any WordPress-specific things like that. And the second link, for those of you not familiar with WordPress, is a list of all of the CVEs that have been found in the past. While I personally love WordPress, it has been known to be vulnerable in the past, especially the plugins that people use. So, this is not an uncommon attack vector. One thing I do want to note is if a user is able to exploit a cross-site scripting vulnerability and create a new user, if that user has high enough privileges, they could then use that to privilege escalate even one more step to a system-level shell. Because WordPress posts contain PHP, if you want, so they could write a PHP command shell, use that to escalate to a system-level shell, and now they turned a potentially reflected cross-site scripting vulnerability into a shell access on your web server. A very common framework when talking about cross-site scripting, and one that I at least wanted to touch on a little bit, is BEEF, the Browser Exploitation Framework. This is a cross-site scripting framework of payloads and exploits. It's an open-source piece of software designed for penetration testers to exploit browser-based vulnerabilities. So, BEEF can be used to effectively have a botnet of browsers that you can control and monitor in the top left image. You're able to execute any JavaScript on these client-side devices, so the middle image shows grabbing the IP of the host that you've hit with your exploit. Any browser information, so the bottom left shows what is enabled, what's installed, any user agents, window sizes, things like that. So, effectively any HTML or JavaScript that could have been executed by this web browser could be executed by BEEF on the back end. Now, the most value I've found from BEEF is actually upgrading from a browser-based exploit to a system-level exploit. So, there's over 500 Metasploit modules, so if a user is running an old or an out-of-date browser, you could just use BEEF to exploit a Metasploit payload and escalate to a reverse shell from that user, for example. So, here's a bunch of Firefox examples, but there's a ton in BEEF and it's great for escalating from cross-site scripting to command access. As I said, there's a ton of payloads. I'm not going to cover them all. Here's a few examples. Note that anything BEEF can do, you could also do with your own cross-site scripting payloads if you wanted to be a little quieter or learn JavaScript or just get a more controlled feel for it. That said, it does make your life a lot easier as it's just a matter of right-clicking the browser and then clicking on Keylogger. Stuff like that. But as I said, a ton of awesome payloads. I highly recommend you at least check it out. It is going to be for if you find cross-site scripting during your penetration tests, things like that, to quickly exploit it as opposed to needing to weaponize it for bug bounties, things like that. That said, if you can load any external .js file, you could load a BEEF hook and get all of this quickly and easily. So, I briefly want to touch on blind cross-site scripting, mention what it is, and include a few references. It is easily a topic that could be at least one talk on its own. But at its core, blind cross-site scripting is the cross-site scripting JavaScript script payload executes somewhere that you cannot see it, hence the name blind. So, for example, if a login page was vulnerable to cross-site scripting but only administrative users could see your payload, or if it was on a web forum that you didn't have access to, maybe an administrative panel has logs, a chat application that's different for the help desk technician than it is for the end user, firewall logs that you never get to see as an attacker but that execute malicious JavaScript payloads, things like that. So, testing for blind cross-site scripting requires a bit more work as you are going to not be able to quickly test it easily and see the results in your browser. I highly recommend checking out stuff like XSS Hunter or Sleepy Puppy from Netflix. These are really fun tools for finding blind cross-site scripting and especially for your bug bounty hunters. These are going to be vulnerabilities that aren't going to be found right away, especially by tools like Burp or things like that. So, I highly recommend taking a look at blind XSS, learning what it is, and trying to find it, potentially during your engagements, but especially during stuff like bug bounty hunting and things of that nature. So, now that I've covered a ton of different payloads, let's take a quick trip down memory lane for some