Webverselabs Challenge Rill Reflected XSS
Scenario :
Rill is a creek-conservation volunteer network. Their sign-up search has a 24-character cap because the dev heard “shorter queries are safer.” There’s no other filter.
Solution :
As usual, we navigate the app, check different endpoints , check Burp’s History to try and get a better understanding on how the app behaves.
/Watersheds :
Just a static page, nothing useful to us .
/Cleanups :
Same thing, nothing we can work with here.
/Reports :
This looks like a chat that we can use to talk to the team :
Looking at Burp , it’s just a simple GET request containing our input as parameter , maybe we can try to inject inside of it , specially that our input is rendered back to us.
I first started with a simple XSS payload :
1
<script>alert(window.origin)</script>
This returns an empty message, if we check the code :
We see that our payloads isn’t sent correctly . It looks like the field has a character limit : i tried entering 10 A and 10 B , 10 C and 10 D to verify :
Well , we see that our payload gets truncated after we surpass 24 characters : we can try to use a smaller payload then :
I found this Blog that talks about Bypassing lenght limits using Spanned payloads :
1
https://portswigger.net/support/xss-filters-beating-length-limits-using-spanned-payloads
But for this to work, we need to be able to input more than just 1 parameter ,since the idea is to spread our payload into smaller sections acress the submition form :
We also have /Signup endpoint :
We can try to split our payload and input it in differnt sections like they did :
This didn’t work since if we try to send a normal request we get this error which means we can’t really use this endpoint.
Now back to our Reports endpoint , let’s try to find a smaller payload or another way to bypass character restriction .
If we look at the code :
We find that 64 is the number of characters allowed, not 24 , maybe the payload didn’t work because it had filtered tags , so i decided to not use script tag completely and just use a payload that only has HTML event Handler :
1
<svg/onload='+/"`/+/onmouseover=1/+/[*/[]/+alert(42);//'>
Once we inject it, to test this we need to hover our mouse on that field to fire the XSS :
Although we don’t get the 42 alert, we are able to get the flag which means our code was executed . Maybe the app surpreses alerts but still our js code was executed .
We can also use different Obfuscation methods , i found these on a Blog by Invicti on Filter Bypasses for XSS .
1
<body onload="eval(atob('YWxlcnQoJ1N1Y2Nlc3NmdWwgWFNTJyk='))">
This triggers the XSS a well , if you want to try different paylaods, just reset the challenge and retry a different payload until you get your flag :)
For this one i think we should just avoid script tags , and use event handlers instead and all our payloads should work .
But based on the description i think the intended way was using a small XSS payload (les than 24) :
These two are less than 24 :
And it worked perfectly !
That was all for this challenge , see you in the next one :)