XSS Without Slashes – A Little Bit Harder Now

Another day, another filter bypass. This time, it is XSS without slashes!

XSS Without Slashes – Introduction

Just like my Referer XSS post, I had someone come to me with an XSS issue they were having.

An application was vulnerable to reflected XSS, but it was via one part of the path. This meant that input couldn’t contain forward slashes, as that part of the path would have ended.

This might be a shorter post, so I’ll walk through my process and a few of my filed attempts.

Vulnerable Application

Like my XSS Without Spaces post, I’ll use a modified version of my XSS Phishing application.

In this case, I removed any forward slashes from the string in the value parameter, which is functionally the same vulnerability.

Here is my vulnerable form (value parameter):
    <input type="text" value="<?php echo preg_replace('/\//', '', ($_GET['value'])); ?>">

XSS Without Slashes - Vulnerable Application

Testing the Filter

As expected, when I pass input without any slashes, it ends up in the form.

XSS Without Slashes - Test Input

That said, when my input contains forward slashes, the filter properly removes them.

XSS Without Slashes - Slash Filtered

As you can see, the server is receiving the request as expected.

XSS Without Slashes - GET Request

Next, I verified that HTML injection was possible with a tag that I did not need to close.

XSS Without Slashes - HTML Injection

When I attempt a basic XSS payload, the filter breaks the trailing script tag, and the payload does not execute.

XSS Without Slashes - Failed Script

XSS Without Slashes – Failed Attempts

With basic understanding of the filter complete, it was time to bypass it.

First, I tried an opening script tag without a closing version. I was hoping that the closing tag on line 19 would be enough, but this wasn’t the case. I’m guessing some of the junk afterwards was breaking my JavaScript syntax.

XSS Without Slashes - No Closing Tag

Next, I tried the same idea, only setting everything after my payload to an arbitrary variable. I’m guessing that this broke once it reached the double-quote in console.log, but I’m not certain.

XSS Without Slashes - Alert Foo

Finally, I tried the form feed character as a separator, as suggested in this StackOverflow answer. Unfortunately, this did not work either. That said, this could have just been issue with being inside of a form tag for my demo.

XSS Without Slashes - Form Feed

I also thought about using JSFuck, but this was too long for a URL parameter in most cases.

Successful Exploitation

After a bit more searching and thinking, I realized that I did not need to close the img tag.

In this case, I used a standard ‘img src’ onerror XSS payload, and set everything afterwards to my arbitrary attribute. This worked, and I was able to pop an alert!

XSS Without Slashes - IMG Alert

That said, I wasn’t satisfied with this payload, as it was not fully weaponized. I realized that, while HTML encoding is usually the enemy, it is just fine when you are already inside of a tag.

In this case, I HTML encoded my XSS polyglot from ‘//r4y.pw’ to ‘&#x2f;&#x2f;r4y.pw’. I then URL encoded it to prevent any issues with the symbols, and ended up with ‘%26%23x2f%3B%26%23x2f%3Br4y.pw’.

When I set this as the script src, the payload fired, and the exploit was complete.

XSS Without Slashes - Full Exploit

Note that this needed a closing script tag somewhere, like my Short XSS payload.

XSS Without Slashes – Conclusion

This was still a simple filter to bypass, but another one that we found in the wild.

I may try to reproduce the actual version from the URL path, but I may not do another post for this.

I’ve still got plenty more post to catch up on, but let me know if there is anything specific that you would like to see!

Leave a Comment

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.