Building Your First Practical Lab (Part 2)
As part of Immersive One, you can build your labs through our powerful Lab Builder feature. In April, we released the ability to import your own virtual machines into your custom labs.
This is the second blog in a 2 part series that will walk you through the entire process of building your first custom practical lab. You’ll learn how to do everything from launching and configuring an EC2 instance in your AWS account to imaging it and seamlessly integrating it into our platform. In part 1 we showed you how to create and import your own machine. You can read part 1 here.
In this blog, we’ll walk through building a simple Linux privilege escalation scenario as a working example. Our goal is to give you the foundational steps so you can confidently design scenarios tailored to your own creativity, environment, and organizational needs.
The lab objective
Ensure you are connected to the machine via the Ubuntu user for the steps below and not our lab user (lab-user).
The objective of this lab is to read a token file. To do so, the user will need to escalate privileges via a misconfiguration. We will create a flag.txt file inside /root/ that contains a string that the user must read in the lab.
sudo nano /root/flag.txt
Add some content inside the file. This will act as a flag that can be used later to complete the lab.
w3ll_don3_h4ck3r
Save the file
The lab challenge
Now let’s set up the challenge! The goal is for lab-user to find a way to read the /root/flag.txt which is owned by root and not accessible to the lab-user by default. They will do this by exploiting a world-writable script that is executed as the root user in cron job.
Create a directory to hold the script that lab-user can exploit. For this example, it's going to be a simple script that outputs the current time to a file (not very creative).
sudo mkdir /opt/date_printer
This script will be executed by root, but lab-user will have write permissions to it. The initial content will be benign, but the purpose of this lab is for the lab-user to identify the misconfiguration that allows them to modify it to read the /root/flag.txt file to retrieve the flag.
Create a file for the script:
nano /opt/date_printer/printer.sh
Add the following content:
#!/bin/bash echo "Running date_printer: $(date '+%Y-%m-%d %H:%M:%S')" >> /var/log/date.log
Save the file.
Next, set the misconfigured permissions that allow lab-user to write to the script, enabling privilege escalation.
sudo chmod +x /opt/date_printer/printer.sh sudo chown root:root /opt/date_printer/printer.sh sudo chmod 666 /opt/date_printer/printer.sh
Additionally, we want to configure the folder to ensure root owns it, but other users on the machine have access to it.
sudo chown root:root /opt/date_printer sudo chmod 777 /opt/date_printer
Now, let’s add a cron job to run the script we just created. For this scenario, we are going to edit the /etc/crontab file. Cron jobs in this file are generally used for system-wide cron tasks and are readable by anyone. This is good as it adds some breadcrumbs to our lab! If the user reads this file (a common check when looking for privilege escalation on Linux), they will see a script gets run every minute, and it will point them to investigate that script file.
Edit the file
nano /etc/crontab
Add the following line at the end of the file. This line tells cron to execute /opt/date_printer/printer.sh every minute, as the root user
* * * * * root /opt/date_printer/printer.sh
Save the file.
At this point, we have a configured image with a low-privilege lab-user account, which we will use to connect to the lab machine. We also have a cronjob vulnerability that our users attempting the lab have to exploit as the lab-user! For this lab, all the user has to do is find the script that is run by the cronjob and edit it to print the token in the file we added at /root/flag.txt.
They could do this by easily updating the /opt/date_printer/printer.sh script to replace the contents with
#!/bin/bash cat /root/flag.txt >> /var/log/date.log
This one-liner will cat the contents of the /root/flag.txt file to the /var/log/date.log file, which the user can then read to get the token (there are other things we could do here as well, but for the purposes of this lab, let's keep it simple).
Imaging and sharing the lab AMI
Go back to the EC2 dashboard and find the running instance you just configured. Right-click on the EC2 machine, select Image and templates, and then Create image.
- Image name: Provide a descriptive name, e.g., “MyFirstCyberLab-AMI” or “Linux-PrivEsc-Lab-AMI”.
- Image description: Add a brief description, e.g., “Custom lab with lab-user password SSH and cron job privesc scenario.”
- Leave other settings at their default values.
- Click Create image.
This will now create an AMI from the configured EC2 lab machine.
Adding your custom AMI to your lab
Navigate to Lab Builder and go to your custom lab via Manage > Create Lab. If you haven’t created one yet, go ahead and do so by selecting Create a new custom lab.
On the Lab details page, we can give our lab a name and configure various other settings. For the purposes of this example, we’ll call it Linux CTF Challenge, and we’ll fill out the rest of the information to ensure our users know what the lab is all about.
- Lab description: This is a Linux CTF machine designed to test your ability in privilege escalation!
- Estimated Time Required: 30 Minutes
- Difficulty: 3
- Learning outcomes: Understand how to exploit a common Linux misconfiguration
- What’s involved: Investigate the machine and find the misconfiguration that allows for privilege escalation.
Next, we want to fill in the briefing panel. The briefing panel is the learning material that lets our lab users understand a bit about the topic and anything else they need to know to answer the questions. Since this is a CTF, we’ll give them limited information:
Linux CTF This is a CTF lab scenario designed to test your ability to exploit a common misconfiguration in Linux that could result in privilege escalation. Your task in this lab is to read a flag located at /root/flag.txt. Good luck! |
Next, we want to add a Task. Tasks are what the user has to solve to complete the lab. For this example lab, we want to add a question to verify that they’ve read the flag in the /root/flag.txt file.
Select Add task, which will bring up a library of task types. From the library, select Question. This will add a question to the lab task list, which we can then edit by selecting Edit.
Update the question settings to the following:
- Question text: What is the flag found in the /root/flag.txt file?
- Answer: w3ll_don3_h4ck3r
The next stage is to import our custom image. Select Systems and then click Add under the Virtual machine—EC2 type. This will add a new machine to your lab.
Once the machine has been added, we want to configure it. Selecting Edit at the top right will open the machine's configuration editor.
In the blue information box, we provide which region and, most importantly, which AWS account to share your image with so that our platform can use it in a lab.
Within your own AWS account where you created your AMI for the lab image, click on the AMI, and at the bottom of the screen, you will see Permissions.
Select Edit AMI permissions and Add account ID. This will open a box where you enter the Account ID that is displayed in Lab Builder.
Click Share AMI. Now, copy the AMI ID of the machine you just shared and add it to the Lab Builder machine AMI ID section:
Set the following configuration for the other sections in this editor:
- System Name: Your chosen name for the system you’re configuring. For this example, let's call it “Linux Machine”.
- Instance Type: t3.medium
- Connection Type: SSH
- Username: lab-user (or the username you set)
- Password: lab-user (or the password you set)
Once you’ve configured your system, you can easily use it in Lab Builder by selecting Preview System on the system view.
Assuming you’ve built everything correctly, you’ll get a shiny preview of your newly configured machine! This is a good time to run through your lab scenario to ensure it's working correctly.
And that’s it—congratulations on building your first practical lab! At this point, you can spruce up your lab by adding additional questions or details to the briefing panel and publish your lab to your organization for them to enjoy.
This powerful new feature puts the control directly in your hands, allowing you to create incredibly specific and challenging learning environments. These range from simple privilege escalation scenarios like this one to complex, multi-machine attack simulations.
We can’t wait to see the innovative labs you'll create. In the meantime, if you need more ideas or support, use our Help Centre docs for Lab Builder.