Introduction
Welcome to the world of TryHackMe, where cybersecurity education meets creativity! Building your own room on TryHackMe is a fantastic way to share your knowledge and engage with the community. In this guide, we'll walk you through the essential steps to plan, build, and submit your very own room.
Whether you're a seasoned professional or just starting, creating a TryHackMe room is a rewarding experience. Let's get started on this journey of knowledge-sharing and exploration.
Why Create a TryHackMe Room ?
If you’re looking to break into the industry, having a “portfolio” or list of personal projects is recommended by employers. It demonstrates your motivation, your interest, and your growing knowledge.
Building a room for TryHackMe users takes time and skill - it’s a perfect way to signal your mastery of foundational concepts.
You’ll also get great feedback from a supportive community who love challenge rooms.
Planning
In the planning phase, creators often draw inspiration from real-life incidents encountered during their cybersecurity journeys. Using my room, "Hijack", as an example, the initial spark came from intriguing scenarios and misconfigurations observed in the wild. These real-world incidents serve as the foundation for educating others and sharing valuable knowledge.
After formulating the core concept for our room, the next step involves outlining key components to shape the room's structure. For instance:
Foothold:
Identify potential entry points, such as exploiting an NFS share, compromising a web application, or abusing a service to gain a foothold on the target machine...etc
Pivoting:
Explore opportunities for pivoting, leveraging insecure credential storage to move laterally to another user and further exploring the system...etc
Privilege Escalation:
Investigate methods for privilege escalation, whether through recent kernel exploits or creative scenarios specific to the room's context.
Once the key components for the room structure are defined, we can expand on each of these elements. For instance:
Foothold (Example - Web Application):
Define the type of web application involved, detailing how users interact with it and providing a step-by-step process for exploiting vulnerabilities leading to a foothold.
Pivoting (Example - Insecure Credential Storage):
Specify where insecurely stored credentials can be found, creating a narrative that guides participants through discovering and leveraging these credentials for lateral movement.
Privilege Escalation (Example - Kernel Exploit):
Clearly outline the type of exploit, such as a recent kernel exploit, and explain how participants can use this exploit to escalate their privileges within the system.
With these key points and expanded details, the planning phase sets the structure for the room. Creators have a clear outline of the foothold, pivoting, and privilege escalation steps, making the subsequent building process more straightforward. The detailed planning ensures a comprehensive and well-thought-out learning experience for participants engaging with the room.
Building
With a well-defined structure established, we can start building. Staying consistent with our previous example, let's walk through the construction of the "Hijack" machine.
Before we start, we want to point out that you have the option to install VirtualBox
and a Linux ISO image instead of using Vagrant
. If you prefer this method, you can skip directly to Customizing Your Machine. However, we'll primarily focus on using Vagrant for building the room. Vagrant offers several advantages, including easy setup, reproducibility, and consistency across different environments. Additionally, Vagrant simplifies the process of sharing and distributing virtual machines, making it an ideal choice for creating rooms on TryHackMe.
To start, we'll install Vagrant and VirtualBox, the key software for building the virtual machine. The installation of these tools is straightforward. Simply execute the following command:
sudo apt update; sudo apt install vagrant virtualbox
After completing the installation, we proceed by creating a directory to store our machine's data:
mkdir hijack
Within this directory, we create two additional directories named box
and data
:
box
will store the configuration file for our virtual machine.data
will store the data related to the machine.
cd hijack; mkdir box data
Next, we navigate into the box
directory, where we will generate the configuration file.
Before creating the file, we must select the Vagrant box we want to use. You can choose from available boxes here. For this tutorial, we will use the ubuntu/xenial64
box:
Once the box is chosen, we go into the box
directory created earlier and run:
sudo vagrant init [BOX NAME]
With that, our configuration file is created:
Before starting the machine, we need to go into that configuration file and customize it a little bit. Scrolling down, we need to un-comment these highlighted lines:
The first line will assign an IP address
to our virtual machine, allowing us to access it in our local network. The second one will mount the previously created data
directory on the machine for ease of access.
After completing these steps, we are ready to start our machine. Simply run:
sudo vagrant up --provider virtualbox
Now, our virtual machine is up and running. To access it via SSH, execute:
sudo vagrant ssh
And there you have it, an interactive shell with our virtual machine!
Customizing Your Machine
Now comes the interesting part, the phase where we start customizing the virtual machine to align with the structure set during the planning phase. It's our responsibility to install all the tools and software needed to run various applications and services, marking the start of your trial and error journey.
Disclaimer: From this point onward, feel free to follow your own path. Each machine is unique and requires a distinct building approach. We'll continue with our example, the "Hijack" room, but you can extract concepts to start with your machine.
To initiate this process, we return to the data
directory created earlier on our local machine and create the bash setup script responsible for building and customizing our machine. Although manual installation is an option, using a script is more efficient.
cd ../data; touch setup.sh
If we navigate back to our virtual machine, we'll observe that the file is also created in /vagrant_data
, which is the mounted directory set up earlier in the Vagrant configuration:
The first command that we'll add to the setup script is sudo apt update
command to update the repositories.
Next, we need to change the password of the root user. This will ensure that we have complete control over our machine if needed, using this command:
echo -e "ROOT_PASSWORD\\nROOT_PASSWORD" | sudo passwd root
Now, we need to install the necessary packages to be able to run the services mentioned in the planning phase. After adding those, our setup.sh
file will look like this:
#!/bin/bash # update the repositories sudo apt-get update # change the root password echo -e "ROOT_PASSWORD\\nROOT_PASSWORD" | sudo passwd root # installing necessary packages sudo apt-get install -y vsftpd sudo apt-get install -y apache2 sudo debconf-set-selections /vagrant_data/mysql-server.seed sudo apt-get install -y mysql-server sudo apt-get install -y php libapache2-mod-php php-mysql sudo apt-get install -y zip sudo apt-get install -y unzip sudo apt-get install -y nfs-kernel-server sudo apt-get install -y gcc # enabling the services sudo systemctl enable apache2 sudo systemctl enable mysql sudo systemctl enable vsftpd sudo systemctl restart apache2 sudo systemctl restart mysql sudo systemctl restart vsftpd # disable firewall sudo ufw disable
After the installation, we need to configure some of the services, starting with the NFS share.
As planned, we aim to create a misconfigured NFS share vulnerable to user impersonation. After thorough research, we arrived at these commands:
# Configure NFS sudo mkdir /mnt/share sudo cp /vagrant_data/for_employees.txt /mnt/share/for_employees.txt sudo chown rick:rick /mnt/share/ sudo chown rick:rick /mnt/share/for_employees.txt sudo chmod 700 /mnt/share/ sudo chmod 700 /mnt/share/for_employees.txt sudo echo "/mnt/share *(rw,sync,root_squash)" > /etc/exports sudo exportfs -a sudo systemctl restart nfs-kernel-server
We append these to the setup.sh
file and add the for_employees.txt
file containing FTP credentials in the data
directory before moving on to configure FTP.
After further research and trial and error, we finalized these commands for FTP setup:
# Configure vsftpd sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak sudo sed -i 's/anonymous_enable=YES/anonymous_enable=NO/' /etc/vsftpd.conf sudo sed -i 's/#local_enable=YES/local_enable=YES/' /etc/vsftpd.conf sudo sed -i 's/#write_enable=YES/write_enable=YES/' /etc/vsftpd.conf sudo sed -i 's/#chroot_local_user=YES/chroot_local_user=YES/' /etc/vsftpd.conf echo "allow_writeable_chroot=YES" | sudo tee -a /etc/vsftpd.conf sudo service vsftpd restart ftp_user="ftpuser" ftp_password="FTP_PASSWORD" sudo adduser --disabled-password --gecos "" $ftp_user echo "$ftp_user:$ftp_password" | sudo chpasswd sudo chown -R $ftp_user:$ftp_user /home/$ftp_user sudo chmod -R 755 /home/$ftp_user sudo rm -rf /home/ftpuser/* sudo cp /vagrant_data/from_admin.txt /home/ftpuser/.from_admin.txt sudo chown ftpuser:ftpuser /home/ftpuser/.from_admin.txt sudo cp /vagrant_data/passwords_list.txt /home/ftpuser/.passwords_list.txt sudo chown ftpuser:ftpuser /home/ftpuser/.passwords_list.txt sudo systemctl restart vsftpd.service
These commands configure the FTP server, create the FTP user, and manage permissions for the root directory of the FTP server. Then adds the files relevant to the challenge to the server. We add these commands to the setup script and move on.
Now we need to set up the web application. After developing and testing the app, we place the source code in the data
directory and add these commands to our setup:
# add the web app to the web root and change it's ownership to www-data sudo unzip /vagrant_data/html.zip -d /var/www/html sudo rm /var/www/html/index.html sudo chown -R www-data:www-data /var/www/html # setup the database MYSQL_ROOT_PASSWORD="ROOT_PASSWORD" MYSQL_RICK_PASSWORD="RICK_PASSWORD" mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD';" mysql -u root -h localhost -p${MYSQL_ROOT_PASSWORD} -e "CREATE USER 'rick'@'localhost' IDENTIFIED BY '$MYSQL_RICK_PASSWORD';" mysql -u root -h localhost -p${MYSQL_ROOT_PASSWORD} -e "GRANT ALL PRIVILEGES ON *.* TO 'rick'@'localhost' WITH GRANT OPTION;" mysql -u rick -h localhost -p${MYSQL_RICK_PASSWORD} -e "CREATE DATABASE hijack;" mysql -u rick -h localhost -p${MYSQL_RICK_PASSWORD} -e "USE hijack; CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, failed_login_count INT DEFAULT 0, last_failed_login_time DATETIME, account_locked TINYINT(1) DEFAULT 0 );" mysql -u rick -h localhost -p${MYSQL_RICK_PASSWORD} -e "USE hijack; INSERT INTO users (id, username, password) VALUES (1, 'admin', 'MD5_HASH_PASSWORD');" sudo systemctl restart mysql sudo systemctl restart apache2
These commands copy the source code of our app and place it in the default root directory of the web, which is in /var/www/html/
, and then set up the database.
Now that we are done setting up the services and apps, it's time to create the user rick
using these commands:
# add user rick and limit his privileges sudo useradd rick sudo mkdir -p /home/rick sudo chown rick:rick /home/rick sudo bash -c "echo 'rick:RICK_PASSWORD' | chpasswd" sudo cp /vagrant_data/our_sudoers /etc/sudoers
Notice that we made a copy of the /etc/sudoers
file and placed it in the data
directory with slight modifications, allowing the user rick to run the /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2
command as root and adding the env_keep+=LD_LIBRARY_PATH
entry for the privilege escalation part.
We do the same for SSH
. We grab a copy of the /etc/ssh/sshd_config
file, make appropriate changes to it, save it in the data
file, and we add these lines to the setup script:
# configure ssh sudo cp /vagrant_data/our_sshd_config /etc/ssh/sshd_config sudo systemctl restart sshd
We are done with the base tasks; what's left now is cleaning the machine and adding the flags. First, we remove all the history files and redirect them to /dev/null
using symlinks:
# symlinks sudo rm /home/rick/.bash_history sudo rm /home/rick/.mysql_history sudo rm /root/.bash_history sudo rm /root/.mysql_history sudo ln -s /dev/null /home/rick/.bash_history sudo ln -s /dev/null /home/rick/.mysql_history sudo ln -s /dev/null /root/.bash_history sudo ln -s /dev/null /root/.mysql_history
Next, we add the flags:
# FLAGS sudo echo "THM{user_flag}" > /home/rick/user.txt sudo chown rick:rick /home/rick/user.txt sudo chmod 600 /home/rick/user.txt sudo echo "THM{root_flag}" > /root/root.txt sudo chmod 600 /root/root.txt
Now we need to patch the machine and secure it from any famous exploits. Looking at the version of this machine, we only need to remove SUID
from the psexec
binary and uninstall lxc
:
# removing lxc and lxd and patching sudo systemctl stop lxd sudo systemctl disable lxd sudo systemctl stop lxc sudo systemctl disable lxc sudo apt purge -y lxc sudo apt purge -y lxd sudo rm -rf /var/lib/lxd sudo rm -rf /var/lib/lxc sudo rm -rf /etc/lxd sudo rm -rf /etc/lxc sudo rm -rf /usr/bin/lxc sudo chmod 0755 /usr/bin/pkexec
Finally, we remove the users created by vagrant
:
# Cleaning sudo deluser ubuntu sudo delgroup ubuntu sudo rm -rf /home/ubuntu sudo deluser vagrant sudo delgroup vagrant sudo rm -rf /home/vagrant
With that, our setup script is complete.
Now, we move to our created virtual machine and run the setup script as the root
user:
/vagrant_data/setup.sh
Let the setup run. Once it finishes, we un-mount the /vagrant
and /vagrant_data
directories, then delete them:
sudo umount /vagrant sudo umount /vagrant_data sudo rm -rf /vagrant sudo rm -rf /vagrant_data
Now our machine is ready!
Before shutting it down, we want to ensure that the machine runs properly. First, we scan our machine with nmap
to check if all the intended ports are open:
Next, we quickly visit the web application to check if it's running properly:
Everything runs great. Now we are ready to shut down the machine.
We open a new terminal tab, then navigate to that box directory, and run:
sudo vagrant halt
The machine is now shutdown, and the building phase is complete.
Now, we need to export the virtual machine into an ova
format to be able to upload it to TryHackMe. To do that, we first open VirtualBox.
Note: Open VirtualBox as root
We can see our virtual machine. To export it, we go to the upper-left corner and click on File
, then Export Appliance
:
Then a new window pops up:
We select our virtual machine and click Next
:
Here, we specify the path where our exported machine will be saved, and leave all other settings on default, and click Next
:
Now, we just click Export
, and the operation starts.
After the export finishes, we get our ova
file that we will upload to TryHackMe:
Machine Upload and Submission
Please look at these articles on the room creation process.
With that, our submission is complete!
Now, the TryHackMe staff will carefully review our room and evaluate it. If the room meets their standards, they will proceed with testing. Otherwise, they will provide us with suggestions on how to improve the room. The TryHackMe Quality Assurance (QA) team is incredibly supportive during this process, offering helpful feedback and guidance to ensure that our room is both engaging and educational. Their expertise and assistance play a crucial role in refining and enhancing the quality of our room before it's released to the TryHackMe community.
The community's support during and after the room submission was invaluable. It was evident through the congratulatory messages, positive feedback, and expressed interest in room creation. Many community members showed enthusiasm and appreciation for the content created. Additionally, some individuals approached with collaboration proposals for room creation, showcasing a desire for collective contribution and knowledge sharing. Overall, the community's engagement and encouragement significantly contributed to the motivation to continue creating and enhancing rooms on TryHackMe.
In conclusion, creating and submitting a room on TryHackMe is a rewarding experience that offers numerous benefits. From honing technical skills to fostering collaboration within the cybersecurity community, the process of planning, building, and submitting a room provides valuable opportunities for growth and learning. The supportive environment provided by TryHackMe and its vibrant community ensures that creators receive constructive feedback and encouragement every step of the way. Whether you're a seasoned cybersecurity professional or a novice enthusiast, creating a room on TryHackMe is an excellent way to contribute to the community while expanding your knowledge and skill set. So why wait? Start planning your room today and dive into an exciting journey of exploration and education with TryHackMe.