2 examples 0/3 challenges solved
Description
Ready for the full course?
Lifetime access of:
Next recipe
XSS Attacks Inside JavaScript
1 Example
0/4 challenges solved
All recipes
Hacking Websites With Cross-Site Scripting
1 Example
0/3 challenges solved
XSS Attacks From HTML Attributes
2 Examples
0/3 challenges solved
XSS Attacks From URLs
1 Example
0/2 challenges solved
XSS Filter Evasion
2 Examples
0/2 challenges solved
How To Use Event Handlers For XSS Exploits
2 Examples
0/3 challenges solved
XSS Attacks Inside JavaScript
1 Example
0/4 challenges solved
Polyglots: The Ultimate XSS Payloads
1 Example
0/1 challenges solved
How To Create Real XSS Exploits To Attack Websites
1 Example
0/3 challenges solved
How To Fix XSS Vulnerabilities In Code
0 Examples
0/3 challenges solved
How To Allow Safe HTML Injection
1 Example
0/2 challenges solved
How To Prevent XSS With Code Reviews
0 Examples
0/3 challenges solved
Automatic XSS Prevention
2 Examples
0/3 challenges solved
Exploiting Web Pages That Have A CSP
1 Example
0/2 challenges solved
Blind XSS
2 Examples
0/0 challenges solved
video transcript
It's time to be...
EVIL!
This next recipe is all about fine-tuning event handlers for exploits.
This course would not be complete unless you understood exploit techniques, because then you wouldn't truly understand XSS and how dangerous it can be.
As software professionals, you need to understand how cybercriminals can attack your applications, in order to protect your users and your company.
And there is no better way to learn than by doing. So this is where you get to jump into the mind of an attacker.
There are two key principles that make up a high-quality, XSS exploit.
First, your payload must execute as quickly as possible.
This means you need to eliminate or minimize user interaction.
Second, the attack needs to remain undetected.
If you make too much noise, someone will know something's wrong, and the vulnerability will be fixed before your exploit can do much damage. And using event handlers for exploits requires a bit more finesse.
Consider a tiny, little element at the very bottom of a webpage. It's naturally pretty safe from click events, because the user probably won't even scroll down far enough to even see it.
See this in the Exploit with Event Handlers example below.
I wanna give you some time to find the vulnerability. So take as long as you need.
As I hinted at earlier, there's something at the very bottom of the webpage where it says, "Share this page." So inspect the element. And you can see there's a data-url attribute that's being set to the current URL.
This is what's vulnerable.
What you need to do is add your payload to the URL. You can do this by
adding a hash followed by a double quote to break out of the attribute then
onclick="alert()
.
And any time you click the element the alert will pop up.
We already know that onclick probably isn't the best choice. So my favorite combination is to use onmouseover along with adding some style.
Now I know some of you are thinking:
If a teeny, tiny element at the bottom of the page won't get glicked, an onmouseover event won't work either.
But this is where the magic of CSS styling comes in.
You can use the style attribute to add CSS styles to an element to change its appearance on the webpage.
Quick rundown: create CSS style declarations using a property name, a colon then it's value, with each separated by a semicolon and optional whitespace.
<tag style="name: value; name: value;">
Craft the attack using an onmouseover event with an alert.
Add the onmouseover, equals, and I'm just gonna leave it unquoted, alert, then we're gonna need a space for our next attribute which is style, equals
onmouseover=alert() style=
The first thing we wanna do in CSS is move the element from the very bottom of the page to the very top.
By default, elements are positioned based on where they appear in the HTML. But if we change the CSS property "position" to "fixed", Then a semicolon we can fix the element to a certain spot in the browser window.
position:fixed;
We want that spot to be at the very top, so set the top property to zero. Then a semicolon.
top:0;
And we want it to start at the very beginning of the page, so set left to zero as well and hit enter.
left:0;
The positioning is perfect, but it's still to small to ensure a successful exploit, so let's just make it larger. First, we need to increase the width. So guess what CSS property does that.
WIDTH!
Y-yes. Width.
So we're gonna set width to and we want it to fill the entire page, so let's set it to 100 percent.
HOLD ON!
Certain characters in URLs have special meaning. The percent character and semicolon are just two of them.
This means that in order for your browser to send the URL properly, you need to URL encode these characters.
This is done by adding a percent symbol followed by the character's hex value.
So in your payload, % becomes %25, because 25 is the hex value of the percent character. So let's change the 100% to 100%25.
width:100%25;
And since our payload is in a URL hash, rather than a query parameter, we can leave semicolons alone for now.
Now that we have the width, next we want the h–
HEIGHT!
And so, we'll set the height to 100%25.
height:100%25;
The element now covers the entire page, and you can see it executes very easily.
Almost too easily.
So we've achieved our first goal of optimizing execution. Now we want to achieve our next goal of making it virtually undetectable.
The first step is very easy, we just need to hide the text by setting its color to transparent.
color:transparent;
Visually, everything looks normal as if we were just starting, but the HTML of the page still needs to be cleaned up because it contains our exploit code.
In other words, the onmouseover and style attributes need to be removed. And if you recall, JavaScript lets you control everything on the webpage, so just do it in your event handler code.
So right before you alert, you just need to add code that removes itself.
Now in JavaScript event handlers, you can use the word this to refer to the same element. So, since we just need to remove attributes, use:
this.removeAttribute('onmouseover')
Just like in CSS declarations, JavaScript expressions can be separated with semicolons. So after you remove the first attribute, add a semicolon, then remove the other. After that, we have a semicolon then our alert. and hit enter.
;this.removeAttribute('style');
We triggered the alert, and it only happens once. And if we scroll all the way to the bottom, the Share this page is back where it belongs.
Your attack is now self-deleting, and removes all traces of itself from the webpage. So the second goal of XSS is now achieved.
Here's a recap of what happened from start to finish. You broke out of the data-url attribute with a quote. You modified the element's style to secretly fill the entire webpage, listened for the mouseover event, to hide all traces of your attack, and finally launched an alert function in place of a malicious exploit.
Beautiful and evil.
Check out the next example, XSS with Progress Events, below.
This looks a lot like the example from the first recipe, so let's just try injecting a script element.
It stripped out our script tags, so we can't add a script element.
For this example, let's get perfect, immediate execution. So don't use onmouseover or onclick, because they require user interaction.
Since we can't inject script tags, javascript URLs and progress events can give us perfect, immediate execution. I'll show you how.
iframes with the src attribute set to a JavaScript URL will give you immediate execution.
<iframe src=javascript:alert()></iframe>
JavaScript URLs won't work with every element that uses src attributes, like images, but you can still use progress events to get your code to run.
One common payload is to use images with an invalid src, and then use the onerror event handler set to alert. and then anything that won't work. You could use, like, a number or just the letter x. And then update.
<img src=x onerror=alert()>
Now with these perfect, immediate execution payloads, there's still the problem of hiding the attack.
If you just add CSS to hide the element, that only solves 50% of the problem. You still have the code inside the HTML of the page.
So why not destroy the element entirely?
To do this: just get the element and then call remove.
So in our image example, before we call alert within our event handler, you can just add:
<img src=x onerror=this.remove();alert()>
You can see the alert executed, and the image is gone, leaving no traces behind on the webpage or in the HTML.
Automatic, self-destructing payloads make them much more difficult to find. And we're gonna go over how to create real, XSS exploits in a later recipe, but, right now, you have hands-on experience showing you how a tiny, little XSS security flaw can grow into a much bigger problem by an attacker who has enough skill, patience and...
EVIL.