Building a Vulnerable VM for Students

I recently had the opportunity to collaborate with a local university professor to create an intentionally vulnerable virtual machine for his class to solve. I felt that it was a rewarding learning experience for everyone involved, so I decided to share the process that I used to create the VM. In this post, I will outline my process for creating the VM, and highlight some key considerations to help others that may be interesting in doing something similar in a classroom environment.

Initial Considerations

Before getting started, there are a few considerations that must be made to ensure that you reach your desired outcome. First, you must consider the target audience for the challenge. What is the skill level of the students? Are they just beginning to learn basic hacking concepts, graduate level cyber-security students, or seasoned penetration testers? Answering this question up front will guide the challenge creation process by ensuring that the challenge is difficult, but solvable, for their skill level. Next, you must consider how the students will access the challenge. My example uses a VMware virtual machine that is distributed to the students as an OVA. In this scenario, you must consider things like hardware requirements and DHCP when creating the vulnerable server. If the machine will be centrally hosted on instructor-managed infrastructure, then this is less of an issue. Finally, you may need to consider licensing costs depending on the Operating System and applications you choose for the VM. I have only used Linux and open-source software in my VMs, so specific guidance on licensing costs is beyond the scope of this document.

Finding Inspiration

As with many things in life, getting started can often be the most difficult part. While creating a vulnerable VM only requires two things, a VM and some vulnerabilities, you must have some idea of what type of scenario you want to create. For inspiration, you can check out some of the community made challenges at, read analyses of high-profile breaches from recent news, or reflect on interesting experiences from your personal or professional life.

Creating the VM

When creating the virtual machine, I like to work backwards from privilege escalation to initial exploitation. I prefer this methodology since privilege escalation vulnerabilities are more likely to be tied to specific OS versions, kernels, etc. The last thing I want is to lay all the groundwork only to find the my intended privilege escalation vulnerability has been patched in the OS version that I’ve selected.

Creating Privilege Escalation

I like to use as a reference for my privilege escalation vulnerabilities. Using a vulnerability with a public exploit on exploit-db ensures that all students should have equal access to the resources they need. Additionally, exploit-db will often have a copy of the vulnerable software related to the exploit, making configuration easier for you. If you choose a privilege escalation path that does not use a software vulnerability, ensure the students have similar access to information regarding the technique used for exploitation.

Once a privilege escalation exploit has been selected, build the virtual environment to match the vulnerable environment necessary for the exploit to be successful. This includes installing the OS, installing vulnerable packages, and making application configuration changes. Next, take a snapshot of the VM and test the exploit. If the exploit is successful and everything behaves as expected, move on to the low privilege exploit. If you encountered any issues related to the exploit, make the necessary corrections, snapshot, and test the exploit again until it works.

Creating the Low Privilege Vulnerability

The process for creating the low privilege vulnerability closely follows the process for creating the privilege escalation vulnerability. First, find a relevant vulnerability and exploit. Next, install and configure the application(s) as necessary. Snapshot and test until everything is behaving as expected. Additionally, you should test moving from the low privileged shell to a higher privileged shell using the privilege escalation vulnerability. Finally, if you plan to include intermediate steps between the low and high privilege exploits, test for proper access to any required resources or files using the low privilege shell.

Adding Complexity

If you plan on having intermediate steps between the low and high privilege exploits, now is the time to add them. Perhaps the student must escape a restricted shell. Perhaps the user must rewrite an exploit because the interpreter for the public exploit is not installed on the system. As with the actual exploits, there are many possibilities here. The only limitations are your imagination, the students’ skill level, and the amount of time the students have to complete the challenge. As with previous steps, it is recommended to make incremental changes and take regular snapshots. Once you have achieved the desired result with complexity, test the entire exploitation process to uncover any potential issues.

The is also a great time to add elements of realism or make the machine appear “lived-in”. For instance, you could create fake documents in users’ home directories, add content to a web application to support a narrative, etc. It is up to you how far you want to take it. Keep in mind that this will likely add a bit of time to the students’ process as they hunt for clues.

Cleaning Up the VM

Before moving on to the testing phase, you need to perform some clean up tasks to ensure that you don’t give away unintentional clues to the student. Hopefully you’ve been taking snapshots prior to exploiting your vulnerabilities, so there should not be any remnants of exploit code laying around on the system. If not, be sure to clean up any exploits, enumeration tools, etc. from the system. Additionally, you may consider clearing the .bash_history contents, as well as running ‘history -c’ to clear the history library.

Exporting the VM

I have found that exporting the VM as an OVA tends to work well. VMware Workstation and Virtualbox have this functionality built in. If you are using VMware Player to build the VM, you will need to download the free VMware ovftool from here.

Testing the VM

In addition to thoroughly testing your VM during creation, it is recommended that you distribute your VM to several trusted individuals for testing. Have you test team verify that the VM imports successfully and boots properly, the intended exploits work properly, the VM is close to the desired difficulty level, no unintentional vulnerabilities are present, etc. Once you have received feedback from your test team, make the necessary corrections and export a new version. Continue the testing process until you are satisfied with the final product.

Soliciting Writeups

Soliciting writeups from the students is a great way improve the learning experience for everyone. The students will learn more by documenting their process, and will be discouraged from cheating because they must show their own work. The instructor/creator can also benefit from the writeups by learning new techniques from the creative methods that the students develop to solve the challenge.

Final Thoughts

The method that I have laid out here is by no means the only process that you could follow when creating a custom vulnerable virtual machine. It is simply one that I developed that seems to work well for me. Please feel free to ask questions or make suggestions for improvements in the comments.

Leave a Reply