Few weeks ago, I decided to try to find a vulnerability on the platform that taught me a lot in cybersecurity: Root-Me. In that way, I started to search in the input box which is used for the following:
Moreover, this input box is also special, it allows you to use HTML and custom text descriptor to render your input.
After trying a lot of different HTML element, I learnt the following :
<code class="echappe-js"><script>alert()</script></code> <p> <code class="echappe-js"><img src=x onerror="alert()"></code> <br class="autobr"> <a>XSS</a> </p>
With both information, an idea came to my mind. What if it was possible to embed a js file that I can control? I would be able to bypass all the restriction!
Unfortunatly, the src attribute seems to be automatically removed. As a last try, I embed my own profile page.
This time, the result was different, I achieve embedding the www.root-me.org domain, but csp seems to block us from rendering the page.
However, it is important to notice that it is possible to render every site that we want. Then, finding a way to bypass filter on the back, will allow us to easily have an XSS.
frame-src http://* https://*
Having no possibility to embed the www.root-me.org domain due to the CSP, I started thinking that the filter was allowing me to embed only root-me.org origin. But after some tries, I figured out that I was wrong because it is not possible to iframe challenge01.root-me.org XSS challenges 👀
At this point, I had a lot of interesting things:
With that information, I understand something really important for the future tries : www.root-me.org domain must be used.
In order to verify my assumption, I embedded api.www.root-me.org:
Well, I've got my first iframe, it seems to be nothing because I can't get an XSS on the api domain and you're right, but what if I could do the opposite ?
Seeing that it worked, I immediately claimed www.root-me.org.mizu.re domain and start a flask server. (with https to avoid mixed content error)
from flask import Flask # Create the APP app = Flask(__name__) # Home page @app.route("/", methods=["GET"]) def index(): return "<script>alert(document.domain)</script>" if __name__ == "__main__": app.run("0.0.0.0", port=443, ssl_context=("cert/server.crt", 'cert/server.key'))
Et voila ! 🎉
Immediately after finding the XSS, I've contacted @podalirius who helped me to make some tests and report the vulnerability.
As you can see, the vulnerability was impacting the most pages of the website. For example, an attacker could have used it to rick roll each person going to the www.root-me.org domain using:
<script> window.top.location = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" </script>
After further researches from root-me team, the problem has been fixed by the following code patch:
Sometimes, critical vulnerabilities can arise for a simple slash!
Thanks to Root Me for patching quickly the vulnerability and authorizing me to post this article!
Thanks for reading! 👋