Pre-Auth RCE in Moodle Part II - Session Hijack in Moodle's Shibboleth
3.11 to 3.11.2, 3.10 to 3.10.6, 3.9 to 3.9.9
>= 3.11.3, 3.10.7, 3.9.10
In our previous blogpost we have introduced a pre-auth RCE in Moodles Shibboleth plugin.
This RCE could be triggered when Moodle was configured to store sessions in individual files which is the default configuration for new installations.
However, Moodle also supports storing sessions in the database. In this second part, we reveal a session hijack vulnerability exploiting the over-usage of PHP’s
session_decode function, when the database session handler is configured.
By exploiting this session hijack vulnerability, an unauthenticated attacker can take over the session of any user if shibboleth authentication is enabled. To leverage this vulnerability into a fully blown RCE an active admin session is required. With an admin session it is then trivial to gain RCE.
Log Out to Log In
For every logout request received via the SOAP endpoint
/auth/shibboleth/logout.php the function
logout_db_session() is invoked.
This function iterates over all available sessions in the database and throws every session into the
This will decode the serialized session data from the database, and populate the
$_SESSION superglobal with the decoded data.
As a result, the attacker is logged in as every user with an active session for a fraction of a second.
The problem here is, that the last session is never unloaded and the
$_SESSION variable remains populated with the session information of the very last user.
This session is now assigned to the attacker’s session cookie due to
This means that the attacker can refresh the page resulting in the hijack of a seemingly random user session.
In case the session is not a privileged admin session, the attackers can use the ordinary logout functionality of Moodle to remove this session from the database and repeat the attack. This way, attackers can iterate themselves through the list of all sessions and wait for an admin session to pop up in order to gain trivial Remote Command Execution e.g. via the plugin installer of Moodle.
It was recommended to mitigate this vulnerability by not relying on
session_decode in order to identify the session to be logged out.
Instead, the session could be identified directly by using the
session_id database field provided by Moodle.
By doing so, the session to be logged out can be identified and deleted directly with a single database query instead of
fetching and iterating all available sessions and relying on
In this series two vulnerabilities have been presented that reside in Moodle’s Shibboleth authentication plugin. Both of them stem from the attempts to re-implement or mess with PHP’s internal session mechanisms. This is generally not advisable, due to the complexity and pitfalls that are illustrated within this series. The commits show that these issues come from an almost ancient era. They could have eventually been noticed if source code audits would have been performed that include legay code in their analysis.
It is worth noting that the reporting process was extremely tedious due to problems when understanding and reproducing the issue on BugCrowd’s side 💩. It took 4 Months before the report was finally triaged and relayed to Moodle. For this reason, it is advisable to report security issues directly to Moodle in order to minimize the window of opporturnity for attackers.
|2021-02-21||Submitted Bug via Bugcrowd|
|2021-06-16||Bugcrowd triaged our report with P1|
|2021-09-12||Patch released on GitHub|