Introduction & XSS Post #1: The BasicsPosted on January 23, 2012 by Dave
Hello and welcome to the new Perspective Risk blog! I thought I’d begin with a series of posts on Cross Site Scripting (XSS) as this is an area of web security I’m particularly interested in. We’re going to start with the very basics, by taking a look at what XSS actually is and the three different varieties of it.
Cross Site Scripting (XSS) attacks occur when a website fails to properly prevent attackers from inserting malicious code into an area that takes user provided data, such as form fields on a webpage, HTTP headers, URLs etc. This code is then used to attack other users, rather than the actual website or the server it’s hosted on. This leads many to underestimate the dangers of XSS, despite the fact that an XSS flaw could allow attackers to record what users are typing, redirect users to malicious sites to capture their credentials and change the content of pages to defraud users, to name but a few.
There are three main types of XSS attacks, reflected, stored and DOM based. Reflected are the most common, whilst stored are the most deadly.
These occur when the attack is reflected off a webserver, via a search result, error message or any response which echoes the user provided data back to the user. Reflected attacks are normally delivered via a link and therefore require some amount of coercion, such as tricking the victim into clicking a link sent to them in an email.
So say if a search function on a website was vulnerable to XSS, i.e.
Then we could enter as a search term:
Thus if we then send the entire link to someone else, i.e.:
They’ll see that the host is somewebsite.com, think it’s a legitimate site and click it, and then fall victim to the popup box of doom!
Ok maybe not of doom, but this is most common way of testing for XSS flaws, via these alert boxes. Once a flaw is confirmed, more malicious attacks can be demonstrated. You can see where the name ‘reflected’ comes from too, as you need a vulnerable site to ‘reflect’ the attack off.
Let’s work through an example using Damn Vulnerable Web Application (DVWA), which I will be using for all my demonstrating. I highly recommend it as a surface for practicing on; you can host it locally and it’s easy get up and running. Download it here and follow the install instructions here (or follow the install video here). Don’t forget to login with admin:password and then change the DVWA security level in the security settings tab to low (as the default high is invulnerable to all attacks).
Note, if you would rather practice these skills online, i.e. without installing DVWA, you can try reflected XSS attacks here and stored attacks here (be sure to reset the database for the stored example prior to use here). All my screenshots are of DVWA, but the same XSS strings and principles will work in the online practice environments too.
So head over to the Reflected XSS section and enter some text. The first thing we notice it that what we entered is being echoed exactly back to us on the page:
As you can see, <script> is not displayed, because it’s being read as part of the source of the webpage. If we check the source we can see that it’s there and that there’s no encoding taking place either. Cue rush of adrenaline because we’ve found an XSS flaw! So now all we have to do is pop an alert box to confirm…
That’s reflected covered, now onto its less common but far more deadly friend, stored XSS!
Stored XSS relies on exactly the same principle as reflected XSS; you’re trying to insert your own malicious code into the source, so when a victim visits that page, their browser will execute your code. The only difference, and the reason why they are so much more dangerous, is that your code will be permanently stored on the page. As a result, anyone who subsequently visits that page will trigger the attack; no coercion is required by you at all. They have traditionally often been found on message boards, public guestbooks etc.
There it is, being entered directly into the source, with no encoding or filtering. Thus from now on, whenever we revisit the page we will be XSSed, as the browser re-executes the code in the source every time you visit. (Note if you wish to stop this happening on DVWA, go to Setup > Create/Reset Database and it will revert the database back to its original state).
So last of all:
DOM Based XSS
This is getting into a relatively advanced area now, with regards to the concept of the Document Object Model. A detailed explanation is beyond the scope of this post, but just remember that it’s a platform and language independent interface that allows scripts to dynamically update a page’s content, structure and style. This updating can also be done real time, i.e. on the page being viewed currently, so requires no refreshing of the page. A good example of this is the Google auto search function, every time you type the page you are viewing gets updated with the new results, without requiring a refresh or being forwarded to a new page. This is where DOM based XSS differs from the above, the server is not required for the XSS payload to take effect; instead the attacker abuses the runtime embedding of user supplied data in the page.
To illustrate how the DOM works, we’ll have a quick look at WebGoat, which is another vulnerable application similar to DVWA. You can download it here and then follow the install instructions here. Once installed, fire it up and enter guest:guest if prompted. Then click on AJAX security (you don’t need to know what AJAX is in detail, just know that it’s one of the methods in which we can update the DOM on the fly) and select the first entry. Ignore the challenge there for now, just type in your name and immediately you see that as soon as you enter a letter, it gets displayed back to you, without the page being refreshed or a new page being opened. This is the DOM at work, and is similar to the Google auto search function described above.
Right now our hacker alarm bells should be ringing! What we’re entering is being echoed directly back to us! So let’s try our standard XSS string and then right click inspect the element using Firebug (a Firefox add-on for inspecting the DOM). Also, please note there’s no need to press submit solution, as that’s just to solve the challenge. The page is updated on the fly remember!